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