xref: /openbmc/qemu/monitor/qmp-cmds.c (revision 54d31236b906c8f03eb011717de7bc47000720c3)
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"
29*54d31236SMarkus Armbruster #include "sysemu/runstate.h"
30f1b3ccfaSKevin Wolf #include "sysemu/arch_init.h"
31f1b3ccfaSKevin Wolf #include "sysemu/blockdev.h"
32f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h"
33f1b3ccfaSKevin Wolf #include "qapi/error.h"
34f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-block-core.h"
358ac25c84SMarkus Armbruster #include "qapi/qapi-commands-machine.h"
36f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h"
37f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-ui.h"
38f1b3ccfaSKevin Wolf #include "qapi/qmp/qerror.h"
39f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h"
40f1b3ccfaSKevin Wolf #include "hw/acpi/acpi_dev_interface.h"
41f1b3ccfaSKevin Wolf 
42f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp)
43f1b3ccfaSKevin Wolf {
44f1b3ccfaSKevin Wolf     NameInfo *info = g_malloc0(sizeof(*info));
45f1b3ccfaSKevin Wolf 
46f1b3ccfaSKevin Wolf     if (qemu_name) {
47f1b3ccfaSKevin Wolf         info->has_name = true;
48f1b3ccfaSKevin Wolf         info->name = g_strdup(qemu_name);
49f1b3ccfaSKevin Wolf     }
50f1b3ccfaSKevin Wolf 
51f1b3ccfaSKevin Wolf     return info;
52f1b3ccfaSKevin Wolf }
53f1b3ccfaSKevin Wolf 
54f1b3ccfaSKevin Wolf VersionInfo *qmp_query_version(Error **errp)
55f1b3ccfaSKevin Wolf {
56f1b3ccfaSKevin Wolf     VersionInfo *info = g_new0(VersionInfo, 1);
57f1b3ccfaSKevin Wolf 
58f1b3ccfaSKevin Wolf     info->qemu = g_new0(VersionTriple, 1);
59f1b3ccfaSKevin Wolf     info->qemu->major = QEMU_VERSION_MAJOR;
60f1b3ccfaSKevin Wolf     info->qemu->minor = QEMU_VERSION_MINOR;
61f1b3ccfaSKevin Wolf     info->qemu->micro = QEMU_VERSION_MICRO;
62f1b3ccfaSKevin Wolf     info->package = g_strdup(QEMU_PKGVERSION);
63f1b3ccfaSKevin Wolf 
64f1b3ccfaSKevin Wolf     return info;
65f1b3ccfaSKevin Wolf }
66f1b3ccfaSKevin Wolf 
67f1b3ccfaSKevin Wolf KvmInfo *qmp_query_kvm(Error **errp)
68f1b3ccfaSKevin Wolf {
69f1b3ccfaSKevin Wolf     KvmInfo *info = g_malloc0(sizeof(*info));
70f1b3ccfaSKevin Wolf 
71f1b3ccfaSKevin Wolf     info->enabled = kvm_enabled();
72f1b3ccfaSKevin Wolf     info->present = kvm_available();
73f1b3ccfaSKevin Wolf 
74f1b3ccfaSKevin Wolf     return info;
75f1b3ccfaSKevin Wolf }
76f1b3ccfaSKevin Wolf 
77f1b3ccfaSKevin Wolf UuidInfo *qmp_query_uuid(Error **errp)
78f1b3ccfaSKevin Wolf {
79f1b3ccfaSKevin Wolf     UuidInfo *info = g_malloc0(sizeof(*info));
80f1b3ccfaSKevin Wolf 
81f1b3ccfaSKevin Wolf     info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
82f1b3ccfaSKevin Wolf     return info;
83f1b3ccfaSKevin Wolf }
84f1b3ccfaSKevin Wolf 
85f1b3ccfaSKevin Wolf void qmp_quit(Error **errp)
86f1b3ccfaSKevin Wolf {
87f1b3ccfaSKevin Wolf     no_shutdown = 0;
88f1b3ccfaSKevin Wolf     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
89f1b3ccfaSKevin Wolf }
90f1b3ccfaSKevin Wolf 
91f1b3ccfaSKevin Wolf void qmp_stop(Error **errp)
92f1b3ccfaSKevin Wolf {
93f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
94f1b3ccfaSKevin Wolf      * finished */
95f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
96f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
97f1b3ccfaSKevin Wolf         return;
98f1b3ccfaSKevin Wolf     }
99f1b3ccfaSKevin Wolf 
100f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
101f1b3ccfaSKevin Wolf         autostart = 0;
102f1b3ccfaSKevin Wolf     } else {
103f1b3ccfaSKevin Wolf         vm_stop(RUN_STATE_PAUSED);
104f1b3ccfaSKevin Wolf     }
105f1b3ccfaSKevin Wolf }
106f1b3ccfaSKevin Wolf 
107f1b3ccfaSKevin Wolf void qmp_system_reset(Error **errp)
108f1b3ccfaSKevin Wolf {
109f1b3ccfaSKevin Wolf     qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
110f1b3ccfaSKevin Wolf }
111f1b3ccfaSKevin Wolf 
112f1b3ccfaSKevin Wolf void qmp_system_powerdown(Error **erp)
113f1b3ccfaSKevin Wolf {
114f1b3ccfaSKevin Wolf     qemu_system_powerdown_request();
115f1b3ccfaSKevin Wolf }
116f1b3ccfaSKevin Wolf 
117f1b3ccfaSKevin Wolf void qmp_x_exit_preconfig(Error **errp)
118f1b3ccfaSKevin Wolf {
119f1b3ccfaSKevin Wolf     if (!runstate_check(RUN_STATE_PRECONFIG)) {
120f1b3ccfaSKevin Wolf         error_setg(errp, "The command is permitted only in '%s' state",
121f1b3ccfaSKevin Wolf                    RunState_str(RUN_STATE_PRECONFIG));
122f1b3ccfaSKevin Wolf         return;
123f1b3ccfaSKevin Wolf     }
124f1b3ccfaSKevin Wolf     qemu_exit_preconfig_request();
125f1b3ccfaSKevin Wolf }
126f1b3ccfaSKevin Wolf 
127f1b3ccfaSKevin Wolf void qmp_cont(Error **errp)
128f1b3ccfaSKevin Wolf {
129f1b3ccfaSKevin Wolf     BlockBackend *blk;
13068d00e42SVladimir Sementsov-Ogievskiy     BlockJob *job;
131f1b3ccfaSKevin Wolf     Error *local_err = NULL;
132f1b3ccfaSKevin Wolf 
133f1b3ccfaSKevin Wolf     /* if there is a dump in background, we should wait until the dump
134f1b3ccfaSKevin Wolf      * finished */
135f1b3ccfaSKevin Wolf     if (dump_in_progress()) {
136f1b3ccfaSKevin Wolf         error_setg(errp, "There is a dump in process, please wait.");
137f1b3ccfaSKevin Wolf         return;
138f1b3ccfaSKevin Wolf     }
139f1b3ccfaSKevin Wolf 
140f1b3ccfaSKevin Wolf     if (runstate_needs_reset()) {
141f1b3ccfaSKevin Wolf         error_setg(errp, "Resetting the Virtual Machine is required");
142f1b3ccfaSKevin Wolf         return;
143f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_SUSPENDED)) {
144f1b3ccfaSKevin Wolf         return;
145f1b3ccfaSKevin Wolf     } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
146f1b3ccfaSKevin Wolf         error_setg(errp, "Migration is not finalized yet");
147f1b3ccfaSKevin Wolf         return;
148f1b3ccfaSKevin Wolf     }
149f1b3ccfaSKevin Wolf 
150f1b3ccfaSKevin Wolf     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
151f1b3ccfaSKevin Wolf         blk_iostatus_reset(blk);
152f1b3ccfaSKevin Wolf     }
153f1b3ccfaSKevin Wolf 
15468d00e42SVladimir Sementsov-Ogievskiy     for (job = block_job_next(NULL); job; job = block_job_next(job)) {
15568d00e42SVladimir Sementsov-Ogievskiy         block_job_iostatus_reset(job);
15668d00e42SVladimir Sementsov-Ogievskiy     }
15768d00e42SVladimir Sementsov-Ogievskiy 
158f1b3ccfaSKevin Wolf     /* Continuing after completed migration. Images have been inactivated to
159f1b3ccfaSKevin Wolf      * allow the destination to take control. Need to get control back now.
160f1b3ccfaSKevin Wolf      *
161f1b3ccfaSKevin Wolf      * If there are no inactive block nodes (e.g. because the VM was just
162f1b3ccfaSKevin Wolf      * paused rather than completing a migration), bdrv_inactivate_all() simply
163f1b3ccfaSKevin Wolf      * doesn't do anything. */
164f1b3ccfaSKevin Wolf     bdrv_invalidate_cache_all(&local_err);
165f1b3ccfaSKevin Wolf     if (local_err) {
166f1b3ccfaSKevin Wolf         error_propagate(errp, local_err);
167f1b3ccfaSKevin Wolf         return;
168f1b3ccfaSKevin Wolf     }
169f1b3ccfaSKevin Wolf 
170f1b3ccfaSKevin Wolf     if (runstate_check(RUN_STATE_INMIGRATE)) {
171f1b3ccfaSKevin Wolf         autostart = 1;
172f1b3ccfaSKevin Wolf     } else {
173f1b3ccfaSKevin Wolf         vm_start();
174f1b3ccfaSKevin Wolf     }
175f1b3ccfaSKevin Wolf }
176f1b3ccfaSKevin Wolf 
177f1b3ccfaSKevin Wolf void qmp_system_wakeup(Error **errp)
178f1b3ccfaSKevin Wolf {
179f1b3ccfaSKevin Wolf     if (!qemu_wakeup_suspend_enabled()) {
180f1b3ccfaSKevin Wolf         error_setg(errp,
181f1b3ccfaSKevin Wolf                    "wake-up from suspend is not supported by this guest");
182f1b3ccfaSKevin Wolf         return;
183f1b3ccfaSKevin Wolf     }
184f1b3ccfaSKevin Wolf 
185f1b3ccfaSKevin Wolf     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
186f1b3ccfaSKevin Wolf }
187f1b3ccfaSKevin Wolf 
188f1b3ccfaSKevin Wolf void qmp_set_password(const char *protocol, const char *password,
189f1b3ccfaSKevin Wolf                       bool has_connected, const char *connected, Error **errp)
190f1b3ccfaSKevin Wolf {
191f1b3ccfaSKevin Wolf     int disconnect_if_connected = 0;
192f1b3ccfaSKevin Wolf     int fail_if_connected = 0;
193f1b3ccfaSKevin Wolf     int rc;
194f1b3ccfaSKevin Wolf 
195f1b3ccfaSKevin Wolf     if (has_connected) {
196f1b3ccfaSKevin Wolf         if (strcmp(connected, "fail") == 0) {
197f1b3ccfaSKevin Wolf             fail_if_connected = 1;
198f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "disconnect") == 0) {
199f1b3ccfaSKevin Wolf             disconnect_if_connected = 1;
200f1b3ccfaSKevin Wolf         } else if (strcmp(connected, "keep") == 0) {
201f1b3ccfaSKevin Wolf             /* nothing */
202f1b3ccfaSKevin Wolf         } else {
203f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
204f1b3ccfaSKevin Wolf             return;
205f1b3ccfaSKevin Wolf         }
206f1b3ccfaSKevin Wolf     }
207f1b3ccfaSKevin Wolf 
208f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
209f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
210f1b3ccfaSKevin Wolf             return;
211f1b3ccfaSKevin Wolf         }
212f1b3ccfaSKevin Wolf         rc = qemu_spice_set_passwd(password, fail_if_connected,
213f1b3ccfaSKevin Wolf                                    disconnect_if_connected);
214f1b3ccfaSKevin Wolf         if (rc != 0) {
215f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
216f1b3ccfaSKevin Wolf         }
217f1b3ccfaSKevin Wolf         return;
218f1b3ccfaSKevin Wolf     }
219f1b3ccfaSKevin Wolf 
220f1b3ccfaSKevin Wolf     if (strcmp(protocol, "vnc") == 0) {
221f1b3ccfaSKevin Wolf         if (fail_if_connected || disconnect_if_connected) {
222f1b3ccfaSKevin Wolf             /* vnc supports "connected=keep" only */
223f1b3ccfaSKevin Wolf             error_setg(errp, QERR_INVALID_PARAMETER, "connected");
224f1b3ccfaSKevin Wolf             return;
225f1b3ccfaSKevin Wolf         }
226f1b3ccfaSKevin Wolf         /* Note that setting an empty password will not disable login through
227f1b3ccfaSKevin Wolf          * this interface. */
228f1b3ccfaSKevin Wolf         rc = vnc_display_password(NULL, password);
229f1b3ccfaSKevin Wolf         if (rc < 0) {
230f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
231f1b3ccfaSKevin Wolf         }
232f1b3ccfaSKevin Wolf         return;
233f1b3ccfaSKevin Wolf     }
234f1b3ccfaSKevin Wolf 
235f1b3ccfaSKevin Wolf     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
236f1b3ccfaSKevin Wolf }
237f1b3ccfaSKevin Wolf 
238f1b3ccfaSKevin Wolf void qmp_expire_password(const char *protocol, const char *whenstr,
239f1b3ccfaSKevin Wolf                          Error **errp)
240f1b3ccfaSKevin Wolf {
241f1b3ccfaSKevin Wolf     time_t when;
242f1b3ccfaSKevin Wolf     int rc;
243f1b3ccfaSKevin Wolf 
244f1b3ccfaSKevin Wolf     if (strcmp(whenstr, "now") == 0) {
245f1b3ccfaSKevin Wolf         when = 0;
246f1b3ccfaSKevin Wolf     } else if (strcmp(whenstr, "never") == 0) {
247f1b3ccfaSKevin Wolf         when = TIME_MAX;
248f1b3ccfaSKevin Wolf     } else if (whenstr[0] == '+') {
249f1b3ccfaSKevin Wolf         when = time(NULL) + strtoull(whenstr+1, NULL, 10);
250f1b3ccfaSKevin Wolf     } else {
251f1b3ccfaSKevin Wolf         when = strtoull(whenstr, NULL, 10);
252f1b3ccfaSKevin Wolf     }
253f1b3ccfaSKevin Wolf 
254f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
255f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
256f1b3ccfaSKevin Wolf             return;
257f1b3ccfaSKevin Wolf         }
258f1b3ccfaSKevin Wolf         rc = qemu_spice_set_pw_expire(when);
259f1b3ccfaSKevin Wolf         if (rc != 0) {
260f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
261f1b3ccfaSKevin Wolf         }
262f1b3ccfaSKevin Wolf         return;
263f1b3ccfaSKevin Wolf     }
264f1b3ccfaSKevin Wolf 
265f1b3ccfaSKevin Wolf     if (strcmp(protocol, "vnc") == 0) {
266f1b3ccfaSKevin Wolf         rc = vnc_display_pw_expire(NULL, when);
267f1b3ccfaSKevin Wolf         if (rc != 0) {
268f1b3ccfaSKevin Wolf             error_setg(errp, QERR_SET_PASSWD_FAILED);
269f1b3ccfaSKevin Wolf         }
270f1b3ccfaSKevin Wolf         return;
271f1b3ccfaSKevin Wolf     }
272f1b3ccfaSKevin Wolf 
273f1b3ccfaSKevin Wolf     error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
274f1b3ccfaSKevin Wolf }
275f1b3ccfaSKevin Wolf 
276f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
277f1b3ccfaSKevin Wolf void qmp_change_vnc_password(const char *password, Error **errp)
278f1b3ccfaSKevin Wolf {
279f1b3ccfaSKevin Wolf     if (vnc_display_password(NULL, password) < 0) {
280f1b3ccfaSKevin Wolf         error_setg(errp, QERR_SET_PASSWD_FAILED);
281f1b3ccfaSKevin Wolf     }
282f1b3ccfaSKevin Wolf }
283f1b3ccfaSKevin Wolf 
284f1b3ccfaSKevin Wolf static void qmp_change_vnc_listen(const char *target, Error **errp)
285f1b3ccfaSKevin Wolf {
286f1b3ccfaSKevin Wolf     QemuOptsList *olist = qemu_find_opts("vnc");
287f1b3ccfaSKevin Wolf     QemuOpts *opts;
288f1b3ccfaSKevin Wolf 
289f1b3ccfaSKevin Wolf     if (strstr(target, "id=")) {
290f1b3ccfaSKevin Wolf         error_setg(errp, "id not supported");
291f1b3ccfaSKevin Wolf         return;
292f1b3ccfaSKevin Wolf     }
293f1b3ccfaSKevin Wolf 
294f1b3ccfaSKevin Wolf     opts = qemu_opts_find(olist, "default");
295f1b3ccfaSKevin Wolf     if (opts) {
296f1b3ccfaSKevin Wolf         qemu_opts_del(opts);
297f1b3ccfaSKevin Wolf     }
298f1b3ccfaSKevin Wolf     opts = vnc_parse(target, errp);
299f1b3ccfaSKevin Wolf     if (!opts) {
300f1b3ccfaSKevin Wolf         return;
301f1b3ccfaSKevin Wolf     }
302f1b3ccfaSKevin Wolf 
303f1b3ccfaSKevin Wolf     vnc_display_open("default", errp);
304f1b3ccfaSKevin Wolf }
305f1b3ccfaSKevin Wolf 
306f1b3ccfaSKevin Wolf static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
307f1b3ccfaSKevin Wolf                            Error **errp)
308f1b3ccfaSKevin Wolf {
309f1b3ccfaSKevin Wolf     if (strcmp(target, "passwd") == 0 || strcmp(target, "password") == 0) {
310f1b3ccfaSKevin Wolf         if (!has_arg) {
311f1b3ccfaSKevin Wolf             error_setg(errp, QERR_MISSING_PARAMETER, "password");
312f1b3ccfaSKevin Wolf         } else {
313f1b3ccfaSKevin Wolf             qmp_change_vnc_password(arg, errp);
314f1b3ccfaSKevin Wolf         }
315f1b3ccfaSKevin Wolf     } else {
316f1b3ccfaSKevin Wolf         qmp_change_vnc_listen(target, errp);
317f1b3ccfaSKevin Wolf     }
318f1b3ccfaSKevin Wolf }
319f1b3ccfaSKevin Wolf #endif /* !CONFIG_VNC */
320f1b3ccfaSKevin Wolf 
321f1b3ccfaSKevin Wolf void qmp_change(const char *device, const char *target,
322f1b3ccfaSKevin Wolf                 bool has_arg, const char *arg, Error **errp)
323f1b3ccfaSKevin Wolf {
324f1b3ccfaSKevin Wolf     if (strcmp(device, "vnc") == 0) {
325f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
326f1b3ccfaSKevin Wolf         qmp_change_vnc(target, has_arg, arg, errp);
327f1b3ccfaSKevin Wolf #else
328f1b3ccfaSKevin Wolf         error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
329f1b3ccfaSKevin Wolf #endif
330f1b3ccfaSKevin Wolf     } else {
331f1b3ccfaSKevin Wolf         qmp_blockdev_change_medium(true, device, false, NULL, target,
332f1b3ccfaSKevin Wolf                                    has_arg, arg, false, 0, errp);
333f1b3ccfaSKevin Wolf     }
334f1b3ccfaSKevin Wolf }
335f1b3ccfaSKevin Wolf 
336f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname,
337f1b3ccfaSKevin Wolf                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
338f1b3ccfaSKevin Wolf                     Error **errp)
339f1b3ccfaSKevin Wolf {
340f1b3ccfaSKevin Wolf     Chardev *s;
341f1b3ccfaSKevin Wolf     int fd;
342f1b3ccfaSKevin Wolf 
343f1b3ccfaSKevin Wolf     fd = monitor_get_fd(cur_mon, fdname, errp);
344f1b3ccfaSKevin Wolf     if (fd < 0) {
345f1b3ccfaSKevin Wolf         return;
346f1b3ccfaSKevin Wolf     }
347f1b3ccfaSKevin Wolf 
348f1b3ccfaSKevin Wolf     if (strcmp(protocol, "spice") == 0) {
349f1b3ccfaSKevin Wolf         if (!qemu_using_spice(errp)) {
350f1b3ccfaSKevin Wolf             close(fd);
351f1b3ccfaSKevin Wolf             return;
352f1b3ccfaSKevin Wolf         }
353f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
354f1b3ccfaSKevin Wolf         tls = has_tls ? tls : false;
355f1b3ccfaSKevin Wolf         if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
356f1b3ccfaSKevin Wolf             error_setg(errp, "spice failed to add client");
357f1b3ccfaSKevin Wolf             close(fd);
358f1b3ccfaSKevin Wolf         }
359f1b3ccfaSKevin Wolf         return;
360f1b3ccfaSKevin Wolf #ifdef CONFIG_VNC
361f1b3ccfaSKevin Wolf     } else if (strcmp(protocol, "vnc") == 0) {
362f1b3ccfaSKevin Wolf         skipauth = has_skipauth ? skipauth : false;
363f1b3ccfaSKevin Wolf         vnc_display_add_client(NULL, fd, skipauth);
364f1b3ccfaSKevin Wolf         return;
365f1b3ccfaSKevin Wolf #endif
366f1b3ccfaSKevin Wolf     } else if ((s = qemu_chr_find(protocol)) != NULL) {
367f1b3ccfaSKevin Wolf         if (qemu_chr_add_client(s, fd) < 0) {
368f1b3ccfaSKevin Wolf             error_setg(errp, "failed to add client");
369f1b3ccfaSKevin Wolf             close(fd);
370f1b3ccfaSKevin Wolf             return;
371f1b3ccfaSKevin Wolf         }
372f1b3ccfaSKevin Wolf         return;
373f1b3ccfaSKevin Wolf     }
374f1b3ccfaSKevin Wolf 
375f1b3ccfaSKevin Wolf     error_setg(errp, "protocol '%s' is invalid", protocol);
376f1b3ccfaSKevin Wolf     close(fd);
377f1b3ccfaSKevin Wolf }
378f1b3ccfaSKevin Wolf 
379f1b3ccfaSKevin Wolf 
380f1b3ccfaSKevin Wolf MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
381f1b3ccfaSKevin Wolf {
382f1b3ccfaSKevin Wolf     return qmp_memory_device_list();
383f1b3ccfaSKevin Wolf }
384f1b3ccfaSKevin Wolf 
385f1b3ccfaSKevin Wolf ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
386f1b3ccfaSKevin Wolf {
387f1b3ccfaSKevin Wolf     bool ambig;
388f1b3ccfaSKevin Wolf     ACPIOSTInfoList *head = NULL;
389f1b3ccfaSKevin Wolf     ACPIOSTInfoList **prev = &head;
390f1b3ccfaSKevin Wolf     Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
391f1b3ccfaSKevin Wolf 
392f1b3ccfaSKevin Wolf     if (obj) {
393f1b3ccfaSKevin Wolf         AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
394f1b3ccfaSKevin Wolf         AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
395f1b3ccfaSKevin Wolf 
396f1b3ccfaSKevin Wolf         adevc->ospm_status(adev, &prev);
397f1b3ccfaSKevin Wolf     } else {
398f1b3ccfaSKevin Wolf         error_setg(errp, "command is not supported, missing ACPI device");
399f1b3ccfaSKevin Wolf     }
400f1b3ccfaSKevin Wolf 
401f1b3ccfaSKevin Wolf     return head;
402f1b3ccfaSKevin Wolf }
403f1b3ccfaSKevin Wolf 
404f1b3ccfaSKevin Wolf MemoryInfo *qmp_query_memory_size_summary(Error **errp)
405f1b3ccfaSKevin Wolf {
406f1b3ccfaSKevin Wolf     MemoryInfo *mem_info = g_malloc0(sizeof(MemoryInfo));
407f1b3ccfaSKevin Wolf 
408f1b3ccfaSKevin Wolf     mem_info->base_memory = ram_size;
409f1b3ccfaSKevin Wolf 
410f1b3ccfaSKevin Wolf     mem_info->plugged_memory = get_plugged_memory_size();
411f1b3ccfaSKevin Wolf     mem_info->has_plugged_memory =
412f1b3ccfaSKevin Wolf         mem_info->plugged_memory != (uint64_t)-1;
413f1b3ccfaSKevin Wolf 
414f1b3ccfaSKevin Wolf     return mem_info;
415f1b3ccfaSKevin Wolf }
416