+
+void object_add(const char *type, const char *id, const QDict *qdict,
+ Visitor *v, Error **errp)
+{
+ Object *obj;
+ ObjectClass *klass;
+ const QDictEntry *e;
+ Error *local_err = NULL;
+
+ klass = object_class_by_name(type);
+ if (!klass) {
+ error_setg(errp, "invalid object type: %s", type);
+ return;
+ }
+
+ if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) {
+ error_setg(errp, "object type '%s' isn't supported by object-add",
+ type);
+ return;
+ }
+
+ if (object_class_is_abstract(klass)) {
+ error_setg(errp, "object type '%s' is abstract", type);
+ return;
+ }
+
+ obj = object_new(type);
+ if (qdict) {
+ for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+ object_property_set(obj, v, e->key, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ }
+ }
+
+ object_property_add_child(container_get(object_get_root(), "/objects"),
+ id, obj, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ user_creatable_complete(obj, &local_err);
+ if (local_err) {
+ object_property_del(container_get(object_get_root(), "/objects"),
+ id, &error_abort);
+ goto out;
+ }
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+ object_unref(obj);
+}
+
+int qmp_object_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+ const char *type = qdict_get_str(qdict, "qom-type");
+ const char *id = qdict_get_str(qdict, "id");
+ QObject *props = qdict_get(qdict, "props");
+ const QDict *pdict = NULL;
+ Error *local_err = NULL;
+ QmpInputVisitor *qiv;
+
+ if (props) {
+ pdict = qobject_to_qdict(props);
+ if (!pdict) {
+ error_set(&local_err, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
+ goto out;
+ }
+ }
+
+ qiv = qmp_input_visitor_new(props);
+ object_add(type, id, pdict, qmp_input_get_visitor(qiv), &local_err);
+ qmp_input_visitor_cleanup(qiv);
+
+out:
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return -1;
+ }
+
+ return 0;
+}
+
+void qmp_object_del(const char *id, Error **errp)
+{
+ Object *container;
+ Object *obj;
+
+ container = container_get(object_get_root(), "/objects");
+ obj = object_resolve_path_component(container, id);
+ if (!obj) {
+ error_setg(errp, "object id not found");
+ return;
+ }
+ object_unparent(obj);
+}
+
+MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
+{
+ MemoryDeviceInfoList *head = NULL;
+ MemoryDeviceInfoList **prev = &head;
+
+ qmp_pc_dimm_device_list(qdev_get_machine(), &prev);
+
+ return head;
+}
+
+ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
+{
+ bool ambig;
+ ACPIOSTInfoList *head = NULL;
+ ACPIOSTInfoList **prev = &head;
+ Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
+
+ if (obj) {
+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
+ AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
+
+ adevc->ospm_status(adev, &prev);
+ } else {
+ error_setg(errp, "command is not supported, missing ACPI device");
+ }
+
+ return head;
+}