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"
17*bf5de8c5SMarc-André Lureau #include "qemu/sockets.h"
18e6e108d1SMarkus Armbruster #include "monitor-internal.h"
19e6e108d1SMarkus Armbruster #include "monitor/qdev.h"
203125af29SMarkus Armbruster #include "monitor/qmp-helpers.h"
21f1b3ccfaSKevin Wolf #include "sysemu/sysemu.h"
22f1b3ccfaSKevin Wolf #include "sysemu/kvm.h"
2354d31236SMarkus Armbruster #include "sysemu/runstate.h"
24e6dba048SAlejandro Jimenez #include "sysemu/runstate-action.h"
25f1b3ccfaSKevin Wolf #include "sysemu/block-backend.h"
26f1b3ccfaSKevin Wolf #include "qapi/error.h"
27e6e108d1SMarkus Armbruster #include "qapi/qapi-init-commands.h"
28fa4dcf57SKevin Wolf #include "qapi/qapi-commands-control.h"
29f1b3ccfaSKevin Wolf #include "qapi/qapi-commands-misc.h"
30e6e108d1SMarkus Armbruster #include "qapi/qmp/qerror.h"
3137087fdeSDaniel P. Berrangé #include "qapi/type-helpers.h"
32f1b3ccfaSKevin Wolf #include "hw/mem/memory-device.h"
3391f2fa70SDaniel P. Berrangé #include "hw/intc/intc.h"
34f1b3ccfaSKevin Wolf
qmp_query_name(Error ** errp)35f1b3ccfaSKevin Wolf NameInfo *qmp_query_name(Error **errp)
36f1b3ccfaSKevin Wolf {
37f1b3ccfaSKevin Wolf NameInfo *info = g_malloc0(sizeof(*info));
38f1b3ccfaSKevin Wolf
39f1b3ccfaSKevin Wolf info->name = g_strdup(qemu_name);
40f1b3ccfaSKevin Wolf return info;
41f1b3ccfaSKevin Wolf }
42f1b3ccfaSKevin Wolf
qmp_quit(Error ** errp)43f1b3ccfaSKevin Wolf void qmp_quit(Error **errp)
44f1b3ccfaSKevin Wolf {
45e6dba048SAlejandro Jimenez shutdown_action = SHUTDOWN_ACTION_POWEROFF;
46f1b3ccfaSKevin Wolf qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
47f1b3ccfaSKevin Wolf }
48f1b3ccfaSKevin Wolf
qmp_stop(Error ** errp)49f1b3ccfaSKevin Wolf void qmp_stop(Error **errp)
50f1b3ccfaSKevin Wolf {
51f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump
52f1b3ccfaSKevin Wolf * finished */
53544803c7SMarc-André Lureau if (qemu_system_dump_in_progress()) {
54f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait.");
55f1b3ccfaSKevin Wolf return;
56f1b3ccfaSKevin Wolf }
57f1b3ccfaSKevin Wolf
58f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) {
59f1b3ccfaSKevin Wolf autostart = 0;
60f1b3ccfaSKevin Wolf } else {
61f1b3ccfaSKevin Wolf vm_stop(RUN_STATE_PAUSED);
62f1b3ccfaSKevin Wolf }
63f1b3ccfaSKevin Wolf }
64f1b3ccfaSKevin Wolf
qmp_cont(Error ** errp)65f1b3ccfaSKevin Wolf void qmp_cont(Error **errp)
66f1b3ccfaSKevin Wolf {
67f1b3ccfaSKevin Wolf BlockBackend *blk;
6868d00e42SVladimir Sementsov-Ogievskiy BlockJob *job;
69f1b3ccfaSKevin Wolf Error *local_err = NULL;
70f1b3ccfaSKevin Wolf
71f1b3ccfaSKevin Wolf /* if there is a dump in background, we should wait until the dump
72f1b3ccfaSKevin Wolf * finished */
73544803c7SMarc-André Lureau if (qemu_system_dump_in_progress()) {
74f1b3ccfaSKevin Wolf error_setg(errp, "There is a dump in process, please wait.");
75f1b3ccfaSKevin Wolf return;
76f1b3ccfaSKevin Wolf }
77f1b3ccfaSKevin Wolf
78f1b3ccfaSKevin Wolf if (runstate_needs_reset()) {
79f1b3ccfaSKevin Wolf error_setg(errp, "Resetting the Virtual Machine is required");
80f1b3ccfaSKevin Wolf return;
81f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_SUSPENDED)) {
82f1b3ccfaSKevin Wolf return;
83f1b3ccfaSKevin Wolf } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
84f1b3ccfaSKevin Wolf error_setg(errp, "Migration is not finalized yet");
85f1b3ccfaSKevin Wolf return;
86f1b3ccfaSKevin Wolf }
87f1b3ccfaSKevin Wolf
88f1b3ccfaSKevin Wolf for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
89f1b3ccfaSKevin Wolf blk_iostatus_reset(blk);
90f1b3ccfaSKevin Wolf }
91f1b3ccfaSKevin Wolf
92880eeec6SEmanuele Giuseppe Esposito WITH_JOB_LOCK_GUARD() {
93880eeec6SEmanuele Giuseppe Esposito for (job = block_job_next_locked(NULL); job;
94880eeec6SEmanuele Giuseppe Esposito job = block_job_next_locked(job)) {
95880eeec6SEmanuele Giuseppe Esposito block_job_iostatus_reset_locked(job);
96880eeec6SEmanuele Giuseppe Esposito }
9768d00e42SVladimir Sementsov-Ogievskiy }
9868d00e42SVladimir Sementsov-Ogievskiy
99f1b3ccfaSKevin Wolf /* Continuing after completed migration. Images have been inactivated to
100f1b3ccfaSKevin Wolf * allow the destination to take control. Need to get control back now.
101f1b3ccfaSKevin Wolf *
102f1b3ccfaSKevin Wolf * If there are no inactive block nodes (e.g. because the VM was just
103f1b3ccfaSKevin Wolf * paused rather than completing a migration), bdrv_inactivate_all() simply
104f1b3ccfaSKevin Wolf * doesn't do anything. */
1053b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err);
106f1b3ccfaSKevin Wolf if (local_err) {
107f1b3ccfaSKevin Wolf error_propagate(errp, local_err);
108f1b3ccfaSKevin Wolf return;
109f1b3ccfaSKevin Wolf }
110f1b3ccfaSKevin Wolf
111f1b3ccfaSKevin Wolf if (runstate_check(RUN_STATE_INMIGRATE)) {
112f1b3ccfaSKevin Wolf autostart = 1;
113f1b3ccfaSKevin Wolf } else {
114f1b3ccfaSKevin Wolf vm_start();
115f1b3ccfaSKevin Wolf }
116f1b3ccfaSKevin Wolf }
117f1b3ccfaSKevin Wolf
qmp_add_client(const char * protocol,const char * fdname,bool has_skipauth,bool skipauth,bool has_tls,bool tls,Error ** errp)118f1b3ccfaSKevin Wolf void qmp_add_client(const char *protocol, const char *fdname,
119f1b3ccfaSKevin Wolf bool has_skipauth, bool skipauth, bool has_tls, bool tls,
120f1b3ccfaSKevin Wolf Error **errp)
121f1b3ccfaSKevin Wolf {
122f916a175SMarkus Armbruster static const struct {
1233125af29SMarkus Armbruster const char *name;
1243125af29SMarkus Armbruster bool (*add_client)(int fd, bool has_skipauth, bool skipauth,
1253125af29SMarkus Armbruster bool has_tls, bool tls, Error **errp);
1263125af29SMarkus Armbruster } protocol_table[] = {
1273125af29SMarkus Armbruster { "spice", qmp_add_client_spice },
1283125af29SMarkus Armbruster #ifdef CONFIG_VNC
1293125af29SMarkus Armbruster { "vnc", qmp_add_client_vnc },
1303125af29SMarkus Armbruster #endif
1313125af29SMarkus Armbruster #ifdef CONFIG_DBUS_DISPLAY
1323125af29SMarkus Armbruster { "@dbus-display", qmp_add_client_dbus_display },
1333125af29SMarkus Armbruster #endif
1343125af29SMarkus Armbruster };
1353125af29SMarkus Armbruster int fd, i;
136f1b3ccfaSKevin Wolf
137947e4744SKevin Wolf fd = monitor_get_fd(monitor_cur(), fdname, errp);
138f1b3ccfaSKevin Wolf if (fd < 0) {
139f1b3ccfaSKevin Wolf return;
140f1b3ccfaSKevin Wolf }
141f1b3ccfaSKevin Wolf
142*bf5de8c5SMarc-André Lureau if (!fd_is_socket(fd)) {
143*bf5de8c5SMarc-André Lureau error_setg(errp, "parameter @fdname must name a socket");
144*bf5de8c5SMarc-André Lureau close(fd);
145*bf5de8c5SMarc-André Lureau return;
146*bf5de8c5SMarc-André Lureau }
147*bf5de8c5SMarc-André Lureau
1483125af29SMarkus Armbruster for (i = 0; i < ARRAY_SIZE(protocol_table); i++) {
1493125af29SMarkus Armbruster if (!strcmp(protocol, protocol_table[i].name)) {
1503125af29SMarkus Armbruster if (!protocol_table[i].add_client(fd, has_skipauth, skipauth,
1513125af29SMarkus Armbruster has_tls, tls, errp)) {
152f1b3ccfaSKevin Wolf close(fd);
1533125af29SMarkus Armbruster }
154f1b3ccfaSKevin Wolf return;
155f1b3ccfaSKevin Wolf }
156f1b3ccfaSKevin Wolf }
1573125af29SMarkus Armbruster
158c3054a6eSMarkus Armbruster if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls,
159c3054a6eSMarkus Armbruster protocol, errp)) {
16061d7f2a9SMarkus Armbruster close(fd);
161f1b3ccfaSKevin Wolf }
162f1b3ccfaSKevin Wolf }
163e6e108d1SMarkus Armbruster
qmp_human_monitor_command(const char * command_line,bool has_cpu_index,int64_t cpu_index,Error ** errp)164e6e108d1SMarkus Armbruster char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
165e6e108d1SMarkus Armbruster int64_t cpu_index, Error **errp)
166e6e108d1SMarkus Armbruster {
167e6e108d1SMarkus Armbruster char *output = NULL;
168e6e108d1SMarkus Armbruster MonitorHMP hmp = {};
169e6e108d1SMarkus Armbruster
170e6e108d1SMarkus Armbruster monitor_data_init(&hmp.common, false, true, false);
171e6e108d1SMarkus Armbruster
172e6e108d1SMarkus Armbruster if (has_cpu_index) {
173e6e108d1SMarkus Armbruster int ret = monitor_set_cpu(&hmp.common, cpu_index);
174e6e108d1SMarkus Armbruster if (ret < 0) {
175e6e108d1SMarkus Armbruster error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
176e6e108d1SMarkus Armbruster "a CPU number");
177e6e108d1SMarkus Armbruster goto out;
178e6e108d1SMarkus Armbruster }
179e6e108d1SMarkus Armbruster }
180e6e108d1SMarkus Armbruster
181e6e108d1SMarkus Armbruster handle_hmp_command(&hmp, command_line);
182e6e108d1SMarkus Armbruster
183e6e108d1SMarkus Armbruster WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) {
184e6e108d1SMarkus Armbruster output = g_strdup(hmp.common.outbuf->str);
185e6e108d1SMarkus Armbruster }
186e6e108d1SMarkus Armbruster
187e6e108d1SMarkus Armbruster out:
188e6e108d1SMarkus Armbruster monitor_data_destroy(&hmp.common);
189e6e108d1SMarkus Armbruster return output;
190e6e108d1SMarkus Armbruster }
191e6e108d1SMarkus Armbruster
monitor_init_qmp_commands(void)192e6e108d1SMarkus Armbruster static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
193e6e108d1SMarkus Armbruster {
194e6e108d1SMarkus Armbruster /*
195e6e108d1SMarkus Armbruster * Two command lists:
196e6e108d1SMarkus Armbruster * - qmp_commands contains all QMP commands
197e6e108d1SMarkus Armbruster * - qmp_cap_negotiation_commands contains just
198e6e108d1SMarkus Armbruster * "qmp_capabilities", to enforce capability negotiation
199e6e108d1SMarkus Armbruster */
200e6e108d1SMarkus Armbruster
201e6e108d1SMarkus Armbruster qmp_init_marshal(&qmp_commands);
202e6e108d1SMarkus Armbruster
203e6e108d1SMarkus Armbruster qmp_register_command(&qmp_commands, "device_add",
204e6e108d1SMarkus Armbruster qmp_device_add, 0, 0);
205e6e108d1SMarkus Armbruster
206e6e108d1SMarkus Armbruster QTAILQ_INIT(&qmp_cap_negotiation_commands);
207e6e108d1SMarkus Armbruster qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
208e6e108d1SMarkus Armbruster qmp_marshal_qmp_capabilities,
209e6e108d1SMarkus Armbruster QCO_ALLOW_PRECONFIG, 0);
210e6e108d1SMarkus Armbruster }
211