xref: /openbmc/qemu/monitor/qmp-cmds.c (revision 68d00e429395a273cf25827f89f036548fb67bdd)
1f1b3ccfaSKevin Wolf /*
2f1b3ccfaSKevin Wolf  * QEMU Management Protocol commands
3f1b3ccfaSKevin Wolf  *
4f1b3ccfaSKevin Wolf  * Copyright IBM, Corp. 2011
5f1b3ccfaSKevin Wolf  *
6f1b3ccfaSKevin Wolf  * Authors:
7f1b3ccfaSKevin Wolf  *  Anthony Liguori   <aliguori@us.ibm.com>
8f1b3ccfaSKevin Wolf  *
9f1b3ccfaSKevin Wolf  * This work is licensed under the terms of the GNU GPL, version 2.  See
10f1b3ccfaSKevin Wolf  * the COPYING file in the top-level directory.
11f1b3ccfaSKevin Wolf  *
12f1b3ccfaSKevin Wolf  * Contributions after 2012-01-13 are licensed under the terms of the
13f1b3ccfaSKevin Wolf  * GNU GPL, version 2 or (at your option) any later version.
14f1b3ccfaSKevin Wolf  */
15f1b3ccfaSKevin Wolf 
16f1b3ccfaSKevin Wolf #include "qemu/osdep.h"
17f1b3ccfaSKevin Wolf #include "qemu-common.h"
18f1b3ccfaSKevin Wolf #include "qemu-version.h"
19f1b3ccfaSKevin Wolf #include "qemu/cutils.h"
20f1b3ccfaSKevin Wolf #include "qemu/option.h"
21f1b3ccfaSKevin Wolf #include "monitor/monitor.h"
22f1b3ccfaSKevin Wolf #include "sysemu/sysemu.h"
23f1b3ccfaSKevin Wolf #include "qemu/config-file.h"
24f1b3ccfaSKevin Wolf #include "qemu/uuid.h"
25f1b3ccfaSKevin Wolf #include "chardev/char.h"
26f1b3ccfaSKevin Wolf #include "ui/qemu-spice.h"
27f1b3ccfaSKevin Wolf #include "ui/vnc.h"
28f1b3ccfaSKevin Wolf #include "sysemu/kvm.h"
29f1b3ccfaSKevin Wolf #include "sysemu/arch_init.h"
30f1b3ccfaSKevin Wolf #include "hw/qdev.h"
31f1b3ccfaSKevin Wolf #include "sysemu/blockdev.h"
32f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h"
33f1b3ccfaSKevin Wolf #include "qom/qom-qobject.h"
34f1b3ccfaSKevin Wolf #include "qapi/error.h"
35f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-block-core.h"
36f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h"
37f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-ui.h"
38f1b3ccfaSKevin Wolf #include "qapi/qmp/qdict.h"
39f1b3ccfaSKevin Wolf #include "qapi/qmp/qerror.h"
40f1b3ccfaSKevin Wolf #include "qapi/qobject-input-visitor.h"
41f1b3ccfaSKevin Wolf #include "hw/boards.h"
42f1b3ccfaSKevin Wolf #include "qom/object_interfaces.h"
43f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h"
44f1b3ccfaSKevin Wolf #include "hw/acpi/acpi_dev_interface.h"
45f1b3ccfaSKevin Wolf 
46f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp)
47f1b3ccfaSKevin Wolf {
48f1b3ccfaSKevin Wolf     NameInfo *info = g_malloc0(sizeof(*info));
49f1b3ccfaSKevin Wolf 
50f1b3ccfaSKevin Wolf     if (qemu_name) {
51f1b3ccfaSKevin Wolf         info->has_name = true;
52f1b3ccfaSKevin Wolf         info->name = g_strdup(qemu_name);
53f1b3ccfaSKevin Wolf     }
54f1b3ccfaSKevin Wolf 
55f1b3ccfaSKevin Wolf     return info;
56f1b3ccfaSKevin Wolf }
57f1b3ccfaSKevin Wolf 
58f1b3ccfaSKevin Wolf VersionInfo *qmp_query_version(Error **errp)
59f1b3ccfaSKevin Wolf {
60f1b3ccfaSKevin Wolf     VersionInfo *info = g_new0(VersionInfo, 1);
61f1b3ccfaSKevin Wolf 
62f1b3ccfaSKevin Wolf     info->qemu = g_new0(VersionTriple, 1);
63f1b3ccfaSKevin Wolf     info->qemu->major = QEMU_VERSION_MAJOR;
64f1b3ccfaSKevin Wolf     info->qemu->minor = QEMU_VERSION_MINOR;
65f1b3ccfaSKevin Wolf     info->qemu->micro = QEMU_VERSION_MICRO;
66f1b3ccfaSKevin Wolf     info->package = g_strdup(QEMU_PKGVERSION);
67f1b3ccfaSKevin Wolf 
68f1b3ccfaSKevin Wolf     return info;
69f1b3ccfaSKevin Wolf }
70f1b3ccfaSKevin Wolf 
71f1b3ccfaSKevin Wolf KvmInfo *qmp_query_kvm(Error **errp)
72f1b3ccfaSKevin Wolf {
73f1b3ccfaSKevin Wolf     KvmInfo *info = g_malloc0(sizeof(*info));
74f1b3ccfaSKevin Wolf 
75f1b3ccfaSKevin Wolf     info->enabled = kvm_enabled();
76f1b3ccfaSKevin Wolf     info->present = kvm_available();
77f1b3ccfaSKevin Wolf 
78f1b3ccfaSKevin Wolf     return info;
79f1b3ccfaSKevin Wolf }
80f1b3ccfaSKevin Wolf 
81f1b3ccfaSKevin Wolf UuidInfo *qmp_query_uuid(Error **errp)
82f1b3ccfaSKevin Wolf {
83f1b3ccfaSKevin Wolf     UuidInfo *info = g_malloc0(sizeof(*info));
84f1b3ccfaSKevin Wolf 
85f1b3ccfaSKevin Wolf     info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
86f1b3ccfaSKevin Wolf     return info;
87f1b3ccfaSKevin Wolf }
88f1b3ccfaSKevin Wolf 
89f1b3ccfaSKevin Wolf void qmp_quit(Error **errp)
90f1b3ccfaSKevin Wolf {
91f1b3ccfaSKevin Wolf     no_shutdown = 0;
92f1b3ccfaSKevin Wolf     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
93f1b3ccfaSKevin Wolf }
94f1b3ccfaSKevin Wolf 
95f1b3ccfaSKevin Wolf void qmp_stop(Error **errp)
96f1b3ccfaSKevin Wolf {
97f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
98f1b3ccfaSKevin Wolf      * finished */
99f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
100f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
101f1b3ccfaSKevin Wolf         return;
102f1b3ccfaSKevin Wolf     }
103f1b3ccfaSKevin Wolf 
104f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
105f1b3ccfaSKevin Wolf         autostart = 0;
106f1b3ccfaSKevin Wolf     } else {
107f1b3ccfaSKevin Wolf         vm_stop(RUN_STATE_PAUSED);
108f1b3ccfaSKevin Wolf     }
109f1b3ccfaSKevin Wolf }
110f1b3ccfaSKevin Wolf 
111f1b3ccfaSKevin Wolf void qmp_system_reset(Error **errp)
112f1b3ccfaSKevin Wolf {
113f1b3ccfaSKevin Wolf     qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
114f1b3ccfaSKevin Wolf }
115f1b3ccfaSKevin Wolf 
116f1b3ccfaSKevin Wolf void qmp_system_powerdown(Error **erp)
117f1b3ccfaSKevin Wolf {
118f1b3ccfaSKevin Wolf     qemu_system_powerdown_request();
119f1b3ccfaSKevin Wolf }
120f1b3ccfaSKevin Wolf 
121f1b3ccfaSKevin Wolf void qmp_cpu_add(int64_t id, Error **errp)
122f1b3ccfaSKevin Wolf {
123f1b3ccfaSKevin Wolf     MachineClass *mc;
124f1b3ccfaSKevin Wolf 
125f1b3ccfaSKevin Wolf     mc = MACHINE_GET_CLASS(current_machine);
126f1b3ccfaSKevin Wolf     if (mc->hot_add_cpu) {
127f1b3ccfaSKevin Wolf         mc->hot_add_cpu(id, errp);
128f1b3ccfaSKevin Wolf     } else {
129f1b3ccfaSKevin Wolf         error_setg(errp, "Not supported");
130f1b3ccfaSKevin Wolf     }
131f1b3ccfaSKevin Wolf }
132f1b3ccfaSKevin Wolf 
133f1b3ccfaSKevin Wolf void qmp_x_exit_preconfig(Error **errp)
134f1b3ccfaSKevin Wolf {
135f1b3ccfaSKevin Wolf     if (!runstate_check(RUN_STATE_PRECONFIG)) {
136f1b3ccfaSKevin Wolf         error_setg(errp, "The command is permitted only in '%s' state",
137f1b3ccfaSKevin Wolf                    RunState_str(RUN_STATE_PRECONFIG));
138f1b3ccfaSKevin Wolf         return;
139f1b3ccfaSKevin Wolf     }
140f1b3ccfaSKevin Wolf     qemu_exit_preconfig_request();
141f1b3ccfaSKevin Wolf }
142f1b3ccfaSKevin Wolf 
143f1b3ccfaSKevin Wolf void qmp_cont(Error **errp)
144f1b3ccfaSKevin Wolf {
145f1b3ccfaSKevin Wolf     BlockBackend *blk;
146*68d00e42SVladimir Sementsov-Ogievskiy     BlockJob *job;
147f1b3ccfaSKevin Wolf     Error *local_err = NULL;
148f1b3ccfaSKevin Wolf 
149f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
150f1b3ccfaSKevin Wolf      * finished */
151f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
152f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
153f1b3ccfaSKevin Wolf         return;
154f1b3ccfaSKevin Wolf     }
155f1b3ccfaSKevin Wolf 
156f1b3ccfaSKevin Wolf     if (runstate_needs_reset()) {
157f1b3ccfaSKevin Wolf         error_setg(errp, "Resetting the Virtual Machine is required");
158f1b3ccfaSKevin Wolf         return;
159f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_SUSPENDED)) {
160f1b3ccfaSKevin Wolf         return;
161f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
162f1b3ccfaSKevin Wolf         error_setg(errp, "Migration is not finalized yet");
163f1b3ccfaSKevin Wolf         return;
164f1b3ccfaSKevin Wolf     }
165f1b3ccfaSKevin Wolf 
166f1b3ccfaSKevin Wolf     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
167f1b3ccfaSKevin Wolf         blk_iostatus_reset(blk);
168f1b3ccfaSKevin Wolf     }
169f1b3ccfaSKevin Wolf 
170*68d00e42SVladimir Sementsov-Ogievskiy     for (job = block_job_next(NULL); job; job = block_job_next(job)) {
171*68d00e42SVladimir Sementsov-Ogievskiy         block_job_iostatus_reset(job);
172*68d00e42SVladimir Sementsov-Ogievskiy     }
173*68d00e42SVladimir Sementsov-Ogievskiy 
174f1b3ccfaSKevin Wolf     /* Continuing after completed migration. Images have been inactivated to
175f1b3ccfaSKevin Wolf      * allow the destination to take control. Need to get control back now.
176f1b3ccfaSKevin Wolf      *
177f1b3ccfaSKevin Wolf      * If there are no inactive block nodes (e.g. because the VM was just
178f1b3ccfaSKevin Wolf      * paused rather than completing a migration), bdrv_inactivate_all() simply
179f1b3ccfaSKevin Wolf      * doesn't do anything. */
180f1b3ccfaSKevin Wolf     bdrv_invalidate_cache_all(&local_err);
181f1b3ccfaSKevin Wolf     if (local_err) {
182f1b3ccfaSKevin Wolf         error_propagate(errp, local_err);
183f1b3ccfaSKevin Wolf         return;
184f1b3ccfaSKevin Wolf     }
185f1b3ccfaSKevin Wolf 
186f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
187f1b3ccfaSKevin Wolf         autostart = 1;
188f1b3ccfaSKevin Wolf     } else {
189f1b3ccfaSKevin Wolf         vm_start();
190f1b3ccfaSKevin Wolf     }
191f1b3ccfaSKevin Wolf }
192f1b3ccfaSKevin Wolf 
193f1b3ccfaSKevin Wolf void qmp_system_wakeup(Error **errp)
194f1b3ccfaSKevin Wolf {
195f1b3ccfaSKevin Wolf     if (!qemu_wakeup_suspend_enabled()) {
196f1b3ccfaSKevin Wolf         error_setg(errp,
197f1b3ccfaSKevin Wolf                    "wake-up from suspend is not supported by this guest");
198f1b3ccfaSKevin Wolf         return;
199f1b3ccfaSKevin Wolf     }
200f1b3ccfaSKevin Wolf 
201f1b3ccfaSKevin Wolf     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
202f1b3ccfaSKevin Wolf }
203f1b3ccfaSKevin Wolf 
204f1b3ccfaSKevin Wolf ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
205f1b3ccfaSKevin Wolf {
206f1b3ccfaSKevin Wolf     Object *obj;
207f1b3ccfaSKevin Wolf     bool ambiguous = false;
208f1b3ccfaSKevin Wolf     ObjectPropertyInfoList *props = NULL;
209f1b3ccfaSKevin Wolf     ObjectProperty *prop;
210f1b3ccfaSKevin Wolf     ObjectPropertyIterator iter;
211f1b3ccfaSKevin Wolf 
212f1b3ccfaSKevin Wolf     obj = object_resolve_path(path, &ambiguous);
213f1b3ccfaSKevin Wolf     if (obj == NULL) {
214f1b3ccfaSKevin Wolf         if (ambiguous) {
215f1b3ccfaSKevin Wolf             error_setg(errp, "Path '%s' is ambiguous", path);
216f1b3ccfaSKevin Wolf         } else {
217f1b3ccfaSKevin Wolf             error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
218f1b3ccfaSKevin Wolf                       "Device '%s' not found", path);
219f1b3ccfaSKevin Wolf         }
220f1b3ccfaSKevin Wolf         return NULL;
221f1b3ccfaSKevin Wolf     }
222f1b3ccfaSKevin Wolf 
223f1b3ccfaSKevin Wolf     object_property_iter_init(&iter, obj);
224f1b3ccfaSKevin Wolf     while ((prop = object_property_iter_next(&iter))) {
225f1b3ccfaSKevin Wolf         ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
226f1b3ccfaSKevin Wolf 
227f1b3ccfaSKevin Wolf         entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
228f1b3ccfaSKevin Wolf         entry->next = props;
229f1b3ccfaSKevin Wolf         props = entry;
230f1b3ccfaSKevin Wolf 
231f1b3ccfaSKevin Wolf         entry->value->name = g_strdup(prop->name);
232f1b3ccfaSKevin Wolf         entry->value->type = g_strdup(prop->type);
233f1b3ccfaSKevin Wolf     }
234f1b3ccfaSKevin Wolf 
235f1b3ccfaSKevin Wolf     return props;
236f1b3ccfaSKevin Wolf }
237f1b3ccfaSKevin Wolf 
238f1b3ccfaSKevin Wolf void qmp_qom_set(const char *path, const char *property, QObject *value,
239f1b3ccfaSKevin Wolf                  Error **errp)
240f1b3ccfaSKevin Wolf {
241f1b3ccfaSKevin Wolf     Object *obj;
242f1b3ccfaSKevin Wolf 
243f1b3ccfaSKevin Wolf     obj = object_resolve_path(path, NULL);
244f1b3ccfaSKevin Wolf     if (!obj) {
245f1b3ccfaSKevin Wolf         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
246f1b3ccfaSKevin Wolf                   "Device '%s' not found", path);
247f1b3ccfaSKevin Wolf         return;
248f1b3ccfaSKevin Wolf     }
249f1b3ccfaSKevin Wolf 
250f1b3ccfaSKevin Wolf     object_property_set_qobject(obj, value, property, errp);
251f1b3ccfaSKevin Wolf }
252f1b3ccfaSKevin Wolf 
253f1b3ccfaSKevin Wolf QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
254f1b3ccfaSKevin Wolf {
255f1b3ccfaSKevin Wolf     Object *obj;
256f1b3ccfaSKevin Wolf 
257f1b3ccfaSKevin Wolf     obj = object_resolve_path(path, NULL);
258f1b3ccfaSKevin Wolf     if (!obj) {
259f1b3ccfaSKevin Wolf         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
260f1b3ccfaSKevin Wolf                   "Device '%s' not found", path);
261f1b3ccfaSKevin Wolf         return NULL;
262f1b3ccfaSKevin Wolf     }
263f1b3ccfaSKevin Wolf 
264f1b3ccfaSKevin Wolf     return object_property_get_qobject(obj, property, errp);
265f1b3ccfaSKevin Wolf }
266f1b3ccfaSKevin Wolf 
267f1b3ccfaSKevin Wolf void qmp_set_password(const char *protocol, const char *password,
268f1b3ccfaSKevin Wolf                       bool has_connected, const char *connected, Error **errp)
269f1b3ccfaSKevin Wolf {
270f1b3ccfaSKevin Wolf     int disconnect_if_connected = 0;
271f1b3ccfaSKevin Wolf     int fail_if_connected = 0;
272f1b3ccfaSKevin Wolf     int rc;
273f1b3ccfaSKevin Wolf 
274f1b3ccfaSKevin Wolf     if (has_connected) {
275f1b3ccfaSKevin Wolf         if (strcmp(connected, "fail") == 0) {
276f1b3ccfaSKevin Wolf             fail_if_connected = 1;
277f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "disconnect") == 0) {
278f1b3ccfaSKevin Wolf             disconnect_if_connected = 1;
279f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "keep") == 0) {
280f1b3ccfaSKevin Wolf             /* nothing */
281f1b3ccfaSKevin Wolf         } else {
282f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
283f1b3ccfaSKevin Wolf             return;
284f1b3ccfaSKevin Wolf         }
285f1b3ccfaSKevin Wolf     }
286f1b3ccfaSKevin Wolf 
287f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
288f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
289f1b3ccfaSKevin Wolf             return;
290f1b3ccfaSKevin Wolf         }
291f1b3ccfaSKevin Wolf         rc = qemu_spice_set_passwd(password, fail_if_connected,
292f1b3ccfaSKevin Wolf                                    disconnect_if_connected);
293f1b3ccfaSKevin Wolf         if (rc != 0) {
294f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
295f1b3ccfaSKevin Wolf         }
296f1b3ccfaSKevin Wolf         return;
297f1b3ccfaSKevin Wolf     }
298f1b3ccfaSKevin Wolf 
299f1b3ccfaSKevin Wolf     if (strcmp(protocol, "vnc") == 0) {
300f1b3ccfaSKevin Wolf         if (fail_if_connected || disconnect_if_connected) {
301f1b3ccfaSKevin Wolf             /* vnc supports "connected=keep" only */
302f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
303f1b3ccfaSKevin Wolf             return;
304f1b3ccfaSKevin Wolf         }
305f1b3ccfaSKevin Wolf         /* Note that setting an empty password will not disable login through
306f1b3ccfaSKevin Wolf          * this interface. */
307f1b3ccfaSKevin Wolf         rc = vnc_display_password(NULL, password);
308f1b3ccfaSKevin Wolf         if (rc < 0) {
309f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
310f1b3ccfaSKevin Wolf         }
311f1b3ccfaSKevin Wolf         return;
312f1b3ccfaSKevin Wolf     }
313f1b3ccfaSKevin Wolf 
314f1b3ccfaSKevin Wolf     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
315f1b3ccfaSKevin Wolf }
316f1b3ccfaSKevin Wolf 
317f1b3ccfaSKevin Wolf void qmp_expire_password(const char *protocol, const char *whenstr,
318f1b3ccfaSKevin Wolf                          Error **errp)
319f1b3ccfaSKevin Wolf {
320f1b3ccfaSKevin Wolf     time_t when;
321f1b3ccfaSKevin Wolf     int rc;
322f1b3ccfaSKevin Wolf 
323f1b3ccfaSKevin Wolf     if (strcmp(whenstr, "now") == 0) {
324f1b3ccfaSKevin Wolf         when = 0;
325f1b3ccfaSKevin Wolf     } else if (strcmp(whenstr, "never") == 0) {
326f1b3ccfaSKevin Wolf         when = TIME_MAX;
327f1b3ccfaSKevin Wolf     } else if (whenstr[0] == '+') {
328f1b3ccfaSKevin Wolf         when = time(NULL) + strtoull(whenstr+1, NULL, 10);
329f1b3ccfaSKevin Wolf     } else {
330f1b3ccfaSKevin Wolf         when = strtoull(whenstr, NULL, 10);
331f1b3ccfaSKevin Wolf     }
332f1b3ccfaSKevin Wolf 
333f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
334f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
335f1b3ccfaSKevin Wolf             return;
336f1b3ccfaSKevin Wolf         }
337f1b3ccfaSKevin Wolf         rc = qemu_spice_set_pw_expire(when);
338f1b3ccfaSKevin Wolf         if (rc != 0) {
339f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
340f1b3ccfaSKevin Wolf         }
341f1b3ccfaSKevin Wolf         return;
342f1b3ccfaSKevin Wolf     }
343f1b3ccfaSKevin Wolf 
344f1b3ccfaSKevin Wolf     if (strcmp(protocol, "vnc") == 0) {
345f1b3ccfaSKevin Wolf         rc = vnc_display_pw_expire(NULL, when);
346f1b3ccfaSKevin Wolf         if (rc != 0) {
347f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
348f1b3ccfaSKevin Wolf         }
349f1b3ccfaSKevin Wolf         return;
350f1b3ccfaSKevin Wolf     }
351f1b3ccfaSKevin Wolf 
352f1b3ccfaSKevin Wolf     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
353f1b3ccfaSKevin Wolf }
354f1b3ccfaSKevin Wolf 
355f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
356f1b3ccfaSKevin Wolf void qmp_change_vnc_password(const char *password, Error **errp)
357f1b3ccfaSKevin Wolf {
358f1b3ccfaSKevin Wolf     if (vnc_display_password(NULL, password) < 0) {
359f1b3ccfaSKevin Wolf         error_setg(errp, QERR_SET_PASSWD_FAILED);
360f1b3ccfaSKevin Wolf     }
361f1b3ccfaSKevin Wolf }
362f1b3ccfaSKevin Wolf 
363f1b3ccfaSKevin Wolf static void qmp_change_vnc_listen(const char *target, Error **errp)
364f1b3ccfaSKevin Wolf {
365f1b3ccfaSKevin Wolf     QemuOptsList *olist = qemu_find_opts("vnc");
366f1b3ccfaSKevin Wolf     QemuOpts *opts;
367f1b3ccfaSKevin Wolf 
368f1b3ccfaSKevin Wolf     if (strstr(target, "id=")) {
369f1b3ccfaSKevin Wolf         error_setg(errp, "id not supported");
370f1b3ccfaSKevin Wolf         return;
371f1b3ccfaSKevin Wolf     }
372f1b3ccfaSKevin Wolf 
373f1b3ccfaSKevin Wolf     opts = qemu_opts_find(olist, "default");
374f1b3ccfaSKevin Wolf     if (opts) {
375f1b3ccfaSKevin Wolf         qemu_opts_del(opts);
376f1b3ccfaSKevin Wolf     }
377f1b3ccfaSKevin Wolf     opts = vnc_parse(target, errp);
378f1b3ccfaSKevin Wolf     if (!opts) {
379f1b3ccfaSKevin Wolf         return;
380f1b3ccfaSKevin Wolf     }
381f1b3ccfaSKevin Wolf 
382f1b3ccfaSKevin Wolf     vnc_display_open("default", errp);
383f1b3ccfaSKevin Wolf }
384f1b3ccfaSKevin Wolf 
385f1b3ccfaSKevin Wolf static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
386f1b3ccfaSKevin Wolf                            Error **errp)
387f1b3ccfaSKevin Wolf {
388f1b3ccfaSKevin Wolf     if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) {
389f1b3ccfaSKevin Wolf         if (!has_arg) {
390f1b3ccfaSKevin Wolf             error_setg(errp, QERR_MISSING_PARAMETER, "password");
391f1b3ccfaSKevin Wolf         } else {
392f1b3ccfaSKevin Wolf             qmp_change_vnc_password(arg, errp);
393f1b3ccfaSKevin Wolf         }
394f1b3ccfaSKevin Wolf     } else {
395f1b3ccfaSKevin Wolf         qmp_change_vnc_listen(target, errp);
396f1b3ccfaSKevin Wolf     }
397f1b3ccfaSKevin Wolf }
398f1b3ccfaSKevin Wolf #endif /* !CONFIG_VNC */
399f1b3ccfaSKevin Wolf 
400f1b3ccfaSKevin Wolf void qmp_change(const char *device, const char *target,
401f1b3ccfaSKevin Wolf                 bool has_arg, const char *arg, Error **errp)
402f1b3ccfaSKevin Wolf {
403f1b3ccfaSKevin Wolf     if (strcmp(device, "vnc") == 0) {
404f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
405f1b3ccfaSKevin Wolf         qmp_change_vnc(target, has_arg, arg, errp);
406f1b3ccfaSKevin Wolf #else
407f1b3ccfaSKevin Wolf         error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
408f1b3ccfaSKevin Wolf #endif
409f1b3ccfaSKevin Wolf     } else {
410f1b3ccfaSKevin Wolf         qmp_blockdev_change_medium(true, device, false, NULL, target,
411f1b3ccfaSKevin Wolf                                    has_arg, arg, false, 0, errp);
412f1b3ccfaSKevin Wolf     }
413f1b3ccfaSKevin Wolf }
414f1b3ccfaSKevin Wolf 
415f1b3ccfaSKevin Wolf static void qom_list_types_tramp(ObjectClass *klass, void *data)
416f1b3ccfaSKevin Wolf {
417f1b3ccfaSKevin Wolf     ObjectTypeInfoList *e, **pret = data;
418f1b3ccfaSKevin Wolf     ObjectTypeInfo *info;
419f1b3ccfaSKevin Wolf     ObjectClass *parent = object_class_get_parent(klass);
420f1b3ccfaSKevin Wolf 
421f1b3ccfaSKevin Wolf     info = g_malloc0(sizeof(*info));
422f1b3ccfaSKevin Wolf     info->name = g_strdup(object_class_get_name(klass));
423f1b3ccfaSKevin Wolf     info->has_abstract = info->abstract = object_class_is_abstract(klass);
424f1b3ccfaSKevin Wolf     if (parent) {
425f1b3ccfaSKevin Wolf         info->has_parent = true;
426f1b3ccfaSKevin Wolf         info->parent = g_strdup(object_class_get_name(parent));
427f1b3ccfaSKevin Wolf     }
428f1b3ccfaSKevin Wolf 
429f1b3ccfaSKevin Wolf     e = g_malloc0(sizeof(*e));
430f1b3ccfaSKevin Wolf     e->value = info;
431f1b3ccfaSKevin Wolf     e->next = *pret;
432f1b3ccfaSKevin Wolf     *pret = e;
433f1b3ccfaSKevin Wolf }
434f1b3ccfaSKevin Wolf 
435f1b3ccfaSKevin Wolf ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
436f1b3ccfaSKevin Wolf                                        const char *implements,
437f1b3ccfaSKevin Wolf                                        bool has_abstract,
438f1b3ccfaSKevin Wolf                                        bool abstract,
439f1b3ccfaSKevin Wolf                                        Error **errp)
440f1b3ccfaSKevin Wolf {
441f1b3ccfaSKevin Wolf     ObjectTypeInfoList *ret = NULL;
442f1b3ccfaSKevin Wolf 
443f1b3ccfaSKevin Wolf     object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
444f1b3ccfaSKevin Wolf 
445f1b3ccfaSKevin Wolf     return ret;
446f1b3ccfaSKevin Wolf }
447f1b3ccfaSKevin Wolf 
448f1b3ccfaSKevin Wolf /* Return a DevicePropertyInfo for a qdev property.
449f1b3ccfaSKevin Wolf  *
450f1b3ccfaSKevin Wolf  * If a qdev property with the given name does not exist, use the given default
451f1b3ccfaSKevin Wolf  * type.  If the qdev property info should not be shown, return NULL.
452f1b3ccfaSKevin Wolf  *
453f1b3ccfaSKevin Wolf  * The caller must free the return value.
454f1b3ccfaSKevin Wolf  */
455f1b3ccfaSKevin Wolf static ObjectPropertyInfo *make_device_property_info(ObjectClass *klass,
456f1b3ccfaSKevin Wolf                                                   const char *name,
457f1b3ccfaSKevin Wolf                                                   const char *default_type,
458f1b3ccfaSKevin Wolf                                                   const char *description)
459f1b3ccfaSKevin Wolf {
460f1b3ccfaSKevin Wolf     ObjectPropertyInfo *info;
461f1b3ccfaSKevin Wolf     Property *prop;
462f1b3ccfaSKevin Wolf 
463f1b3ccfaSKevin Wolf     do {
464f1b3ccfaSKevin Wolf         for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
465f1b3ccfaSKevin Wolf             if (strcmp(name, prop->name) != 0) {
466f1b3ccfaSKevin Wolf                 continue;
467f1b3ccfaSKevin Wolf             }
468f1b3ccfaSKevin Wolf 
469f1b3ccfaSKevin Wolf             /*
470f1b3ccfaSKevin Wolf              * TODO Properties without a parser are just for dirty hacks.
471f1b3ccfaSKevin Wolf              * qdev_prop_ptr is the only such PropertyInfo.  It's marked
472f1b3ccfaSKevin Wolf              * for removal.  This conditional should be removed along with
473f1b3ccfaSKevin Wolf              * it.
474f1b3ccfaSKevin Wolf              */
475f1b3ccfaSKevin Wolf             if (!prop->info->set && !prop->info->create) {
476f1b3ccfaSKevin Wolf                 return NULL;           /* no way to set it, don't show */
477f1b3ccfaSKevin Wolf             }
478f1b3ccfaSKevin Wolf 
479f1b3ccfaSKevin Wolf             info = g_malloc0(sizeof(*info));
480f1b3ccfaSKevin Wolf             info->name = g_strdup(prop->name);
481f1b3ccfaSKevin Wolf             info->type = default_type ? g_strdup(default_type)
482f1b3ccfaSKevin Wolf                                       : g_strdup(prop->info->name);
483f1b3ccfaSKevin Wolf             info->has_description = !!prop->info->description;
484f1b3ccfaSKevin Wolf             info->description = g_strdup(prop->info->description);
485f1b3ccfaSKevin Wolf             return info;
486f1b3ccfaSKevin Wolf         }
487f1b3ccfaSKevin Wolf         klass = object_class_get_parent(klass);
488f1b3ccfaSKevin Wolf     } while (klass != object_class_by_name(TYPE_DEVICE));
489f1b3ccfaSKevin Wolf 
490f1b3ccfaSKevin Wolf     /* Not a qdev property, use the default type */
491f1b3ccfaSKevin Wolf     info = g_malloc0(sizeof(*info));
492f1b3ccfaSKevin Wolf     info->name = g_strdup(name);
493f1b3ccfaSKevin Wolf     info->type = g_strdup(default_type);
494f1b3ccfaSKevin Wolf     info->has_description = !!description;
495f1b3ccfaSKevin Wolf     info->description = g_strdup(description);
496f1b3ccfaSKevin Wolf 
497f1b3ccfaSKevin Wolf     return info;
498f1b3ccfaSKevin Wolf }
499f1b3ccfaSKevin Wolf 
500f1b3ccfaSKevin Wolf ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
501f1b3ccfaSKevin Wolf                                                 Error **errp)
502f1b3ccfaSKevin Wolf {
503f1b3ccfaSKevin Wolf     ObjectClass *klass;
504f1b3ccfaSKevin Wolf     Object *obj;
505f1b3ccfaSKevin Wolf     ObjectProperty *prop;
506f1b3ccfaSKevin Wolf     ObjectPropertyIterator iter;
507f1b3ccfaSKevin Wolf     ObjectPropertyInfoList *prop_list = NULL;
508f1b3ccfaSKevin Wolf 
509f1b3ccfaSKevin Wolf     klass = object_class_by_name(typename);
510f1b3ccfaSKevin Wolf     if (klass == NULL) {
511f1b3ccfaSKevin Wolf         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
512f1b3ccfaSKevin Wolf                   "Device '%s' not found", typename);
513f1b3ccfaSKevin Wolf         return NULL;
514f1b3ccfaSKevin Wolf     }
515f1b3ccfaSKevin Wolf 
516f1b3ccfaSKevin Wolf     klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
517f1b3ccfaSKevin Wolf     if (klass == NULL) {
518f1b3ccfaSKevin Wolf         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_DEVICE);
519f1b3ccfaSKevin Wolf         return NULL;
520f1b3ccfaSKevin Wolf     }
521f1b3ccfaSKevin Wolf 
522f1b3ccfaSKevin Wolf     if (object_class_is_abstract(klass)) {
523f1b3ccfaSKevin Wolf         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
524f1b3ccfaSKevin Wolf                    "non-abstract device type");
525f1b3ccfaSKevin Wolf         return NULL;
526f1b3ccfaSKevin Wolf     }
527f1b3ccfaSKevin Wolf 
528f1b3ccfaSKevin Wolf     obj = object_new(typename);
529f1b3ccfaSKevin Wolf 
530f1b3ccfaSKevin Wolf     object_property_iter_init(&iter, obj);
531f1b3ccfaSKevin Wolf     while ((prop = object_property_iter_next(&iter))) {
532f1b3ccfaSKevin Wolf         ObjectPropertyInfo *info;
533f1b3ccfaSKevin Wolf         ObjectPropertyInfoList *entry;
534f1b3ccfaSKevin Wolf 
535f1b3ccfaSKevin Wolf         /* Skip Object and DeviceState properties */
536f1b3ccfaSKevin Wolf         if (strcmp(prop->name, "type") == 0 ||
537f1b3ccfaSKevin Wolf             strcmp(prop->name, "realized") == 0 ||
538f1b3ccfaSKevin Wolf             strcmp(prop->name, "hotpluggable") == 0 ||
539f1b3ccfaSKevin Wolf             strcmp(prop->name, "hotplugged") == 0 ||
540f1b3ccfaSKevin Wolf             strcmp(prop->name, "parent_bus") == 0) {
541f1b3ccfaSKevin Wolf             continue;
542f1b3ccfaSKevin Wolf         }
543f1b3ccfaSKevin Wolf 
544f1b3ccfaSKevin Wolf         /* Skip legacy properties since they are just string versions of
545f1b3ccfaSKevin Wolf          * properties that we already list.
546f1b3ccfaSKevin Wolf          */
547f1b3ccfaSKevin Wolf         if (strstart(prop->name, "legacy-", NULL)) {
548f1b3ccfaSKevin Wolf             continue;
549f1b3ccfaSKevin Wolf         }
550f1b3ccfaSKevin Wolf 
551f1b3ccfaSKevin Wolf         info = make_device_property_info(klass, prop->name, prop->type,
552f1b3ccfaSKevin Wolf                                          prop->description);
553f1b3ccfaSKevin Wolf         if (!info) {
554f1b3ccfaSKevin Wolf             continue;
555f1b3ccfaSKevin Wolf         }
556f1b3ccfaSKevin Wolf 
557f1b3ccfaSKevin Wolf         entry = g_malloc0(sizeof(*entry));
558f1b3ccfaSKevin Wolf         entry->value = info;
559f1b3ccfaSKevin Wolf         entry->next = prop_list;
560f1b3ccfaSKevin Wolf         prop_list = entry;
561f1b3ccfaSKevin Wolf     }
562f1b3ccfaSKevin Wolf 
563f1b3ccfaSKevin Wolf     object_unref(obj);
564f1b3ccfaSKevin Wolf 
565f1b3ccfaSKevin Wolf     return prop_list;
566f1b3ccfaSKevin Wolf }
567f1b3ccfaSKevin Wolf 
568f1b3ccfaSKevin Wolf ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
569f1b3ccfaSKevin Wolf                                              Error **errp)
570f1b3ccfaSKevin Wolf {
571f1b3ccfaSKevin Wolf     ObjectClass *klass;
572f1b3ccfaSKevin Wolf     Object *obj = NULL;
573f1b3ccfaSKevin Wolf     ObjectProperty *prop;
574f1b3ccfaSKevin Wolf     ObjectPropertyIterator iter;
575f1b3ccfaSKevin Wolf     ObjectPropertyInfoList *prop_list = NULL;
576f1b3ccfaSKevin Wolf 
577f1b3ccfaSKevin Wolf     klass = object_class_by_name(typename);
578f1b3ccfaSKevin Wolf     if (klass == NULL) {
579f1b3ccfaSKevin Wolf         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
580f1b3ccfaSKevin Wolf                   "Class '%s' not found", typename);
581f1b3ccfaSKevin Wolf         return NULL;
582f1b3ccfaSKevin Wolf     }
583f1b3ccfaSKevin Wolf 
584f1b3ccfaSKevin Wolf     klass = object_class_dynamic_cast(klass, TYPE_OBJECT);
585f1b3ccfaSKevin Wolf     if (klass == NULL) {
586f1b3ccfaSKevin Wolf         error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_OBJECT);
587f1b3ccfaSKevin Wolf         return NULL;
588f1b3ccfaSKevin Wolf     }
589f1b3ccfaSKevin Wolf 
590f1b3ccfaSKevin Wolf     if (object_class_is_abstract(klass)) {
591f1b3ccfaSKevin Wolf         object_class_property_iter_init(&iter, klass);
592f1b3ccfaSKevin Wolf     } else {
593f1b3ccfaSKevin Wolf         obj = object_new(typename);
594f1b3ccfaSKevin Wolf         object_property_iter_init(&iter, obj);
595f1b3ccfaSKevin Wolf     }
596f1b3ccfaSKevin Wolf     while ((prop = object_property_iter_next(&iter))) {
597f1b3ccfaSKevin Wolf         ObjectPropertyInfo *info;
598f1b3ccfaSKevin Wolf         ObjectPropertyInfoList *entry;
599f1b3ccfaSKevin Wolf 
600f1b3ccfaSKevin Wolf         info = g_malloc0(sizeof(*info));
601f1b3ccfaSKevin Wolf         info->name = g_strdup(prop->name);
602f1b3ccfaSKevin Wolf         info->type = g_strdup(prop->type);
603f1b3ccfaSKevin Wolf         info->has_description = !!prop->description;
604f1b3ccfaSKevin Wolf         info->description = g_strdup(prop->description);
605f1b3ccfaSKevin Wolf 
606f1b3ccfaSKevin Wolf         entry = g_malloc0(sizeof(*entry));
607f1b3ccfaSKevin Wolf         entry->value = info;
608f1b3ccfaSKevin Wolf         entry->next = prop_list;
609f1b3ccfaSKevin Wolf         prop_list = entry;
610f1b3ccfaSKevin Wolf     }
611f1b3ccfaSKevin Wolf 
612f1b3ccfaSKevin Wolf     object_unref(obj);
613f1b3ccfaSKevin Wolf 
614f1b3ccfaSKevin Wolf     return prop_list;
615f1b3ccfaSKevin Wolf }
616f1b3ccfaSKevin Wolf 
617f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname,
618f1b3ccfaSKevin Wolf                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
619f1b3ccfaSKevin Wolf                     Error **errp)
620f1b3ccfaSKevin Wolf {
621f1b3ccfaSKevin Wolf     Chardev *s;
622f1b3ccfaSKevin Wolf     int fd;
623f1b3ccfaSKevin Wolf 
624f1b3ccfaSKevin Wolf     fd = monitor_get_fd(cur_mon, fdname, errp);
625f1b3ccfaSKevin Wolf     if (fd < 0) {
626f1b3ccfaSKevin Wolf         return;
627f1b3ccfaSKevin Wolf     }
628f1b3ccfaSKevin Wolf 
629f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
630f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
631f1b3ccfaSKevin Wolf             close(fd);
632f1b3ccfaSKevin Wolf             return;
633f1b3ccfaSKevin Wolf         }
634f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
635f1b3ccfaSKevin Wolf         tls = has_tls ? tls : false;
636f1b3ccfaSKevin Wolf         if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
637f1b3ccfaSKevin Wolf             error_setg(errp, "spice failed to add client");
638f1b3ccfaSKevin Wolf             close(fd);
639f1b3ccfaSKevin Wolf         }
640f1b3ccfaSKevin Wolf         return;
641f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
642f1b3ccfaSKevin Wolf     } else if (strcmp(protocol, "vnc") == 0) {
643f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
644f1b3ccfaSKevin Wolf         vnc_display_add_client(NULL, fd, skipauth);
645f1b3ccfaSKevin Wolf         return;
646f1b3ccfaSKevin Wolf #endif
647f1b3ccfaSKevin Wolf     } else if ((s = qemu_chr_find(protocol)) != NULL) {
648f1b3ccfaSKevin Wolf         if (qemu_chr_add_client(s, fd) < 0) {
649f1b3ccfaSKevin Wolf             error_setg(errp, "failed to add client");
650f1b3ccfaSKevin Wolf             close(fd);
651f1b3ccfaSKevin Wolf             return;
652f1b3ccfaSKevin Wolf         }
653f1b3ccfaSKevin Wolf         return;
654f1b3ccfaSKevin Wolf     }
655f1b3ccfaSKevin Wolf 
656f1b3ccfaSKevin Wolf     error_setg(errp, "protocol '%s' is invalid", protocol);
657f1b3ccfaSKevin Wolf     close(fd);
658f1b3ccfaSKevin Wolf }
659f1b3ccfaSKevin Wolf 
660f1b3ccfaSKevin Wolf 
661f1b3ccfaSKevin Wolf void qmp_object_add(const char *type, const char *id,
662f1b3ccfaSKevin Wolf                     bool has_props, QObject *props, Error **errp)
663f1b3ccfaSKevin Wolf {
664f1b3ccfaSKevin Wolf     QDict *pdict;
665f1b3ccfaSKevin Wolf     Visitor *v;
666f1b3ccfaSKevin Wolf     Object *obj;
667f1b3ccfaSKevin Wolf 
668f1b3ccfaSKevin Wolf     if (props) {
669f1b3ccfaSKevin Wolf         pdict = qobject_to(QDict, props);
670f1b3ccfaSKevin Wolf         if (!pdict) {
671f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
672f1b3ccfaSKevin Wolf             return;
673f1b3ccfaSKevin Wolf         }
674f1b3ccfaSKevin Wolf         qobject_ref(pdict);
675f1b3ccfaSKevin Wolf     } else {
676f1b3ccfaSKevin Wolf         pdict = qdict_new();
677f1b3ccfaSKevin Wolf     }
678f1b3ccfaSKevin Wolf 
679f1b3ccfaSKevin Wolf     v = qobject_input_visitor_new(QOBJECT(pdict));
680f1b3ccfaSKevin Wolf     obj = user_creatable_add_type(type, id, pdict, v, errp);
681f1b3ccfaSKevin Wolf     visit_free(v);
682f1b3ccfaSKevin Wolf     if (obj) {
683f1b3ccfaSKevin Wolf         object_unref(obj);
684f1b3ccfaSKevin Wolf     }
685f1b3ccfaSKevin Wolf     qobject_unref(pdict);
686f1b3ccfaSKevin Wolf }
687f1b3ccfaSKevin Wolf 
688f1b3ccfaSKevin Wolf void qmp_object_del(const char *id, Error **errp)
689f1b3ccfaSKevin Wolf {
690f1b3ccfaSKevin Wolf     user_creatable_del(id, errp);
691f1b3ccfaSKevin Wolf }
692f1b3ccfaSKevin Wolf 
693f1b3ccfaSKevin Wolf MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
694f1b3ccfaSKevin Wolf {
695f1b3ccfaSKevin Wolf     return qmp_memory_device_list();
696f1b3ccfaSKevin Wolf }
697f1b3ccfaSKevin Wolf 
698f1b3ccfaSKevin Wolf ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
699f1b3ccfaSKevin Wolf {
700f1b3ccfaSKevin Wolf     bool ambig;
701f1b3ccfaSKevin Wolf     ACPIOSTInfoList *head = NULL;
702f1b3ccfaSKevin Wolf     ACPIOSTInfoList **prev = &head;
703f1b3ccfaSKevin Wolf     Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
704f1b3ccfaSKevin Wolf 
705f1b3ccfaSKevin Wolf     if (obj) {
706f1b3ccfaSKevin Wolf         AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
707f1b3ccfaSKevin Wolf         AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
708f1b3ccfaSKevin Wolf 
709f1b3ccfaSKevin Wolf         adevc->ospm_status(adev, &prev);
710f1b3ccfaSKevin Wolf     } else {
711f1b3ccfaSKevin Wolf         error_setg(errp, "command is not supported, missing ACPI device");
712f1b3ccfaSKevin Wolf     }
713f1b3ccfaSKevin Wolf 
714f1b3ccfaSKevin Wolf     return head;
715f1b3ccfaSKevin Wolf }
716f1b3ccfaSKevin Wolf 
717f1b3ccfaSKevin Wolf MemoryInfo *qmp_query_memory_size_summary(Error **errp)
718f1b3ccfaSKevin Wolf {
719f1b3ccfaSKevin Wolf     MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
720f1b3ccfaSKevin Wolf 
721f1b3ccfaSKevin Wolf     mem_info->base_memory = ram_size;
722f1b3ccfaSKevin Wolf 
723f1b3ccfaSKevin Wolf     mem_info->plugged_memory = get_plugged_memory_size();
724f1b3ccfaSKevin Wolf     mem_info->has_plugged_memory =
725f1b3ccfaSKevin Wolf         mem_info->plugged_memory != (uint64_t)-1;
726f1b3ccfaSKevin Wolf 
727f1b3ccfaSKevin Wolf     return mem_info;
728f1b3ccfaSKevin Wolf }
729