xref: /qemu/monitor/qmp-cmds.c (revision 8597af76153a87068b675d8099063c3ad8695773)
1 /*
2  * QEMU Management Protocol commands
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  *
12  * Contributions after 2012-01-13 are licensed under the terms of the
13  * GNU GPL, version 2 or (at your option) any later version.
14  */
15 
16 #include "qemu/osdep.h"
17 #include "qemu/sockets.h"
18 #include "monitor-internal.h"
19 #include "monitor/qdev.h"
20 #include "monitor/qmp-helpers.h"
21 #include "system/system.h"
22 #include "system/kvm.h"
23 #include "system/runstate.h"
24 #include "system/runstate-action.h"
25 #include "system/block-backend.h"
26 #include "qapi/error.h"
27 #include "qapi/qapi-init-commands.h"
28 #include "qapi/qapi-commands-control.h"
29 #include "qapi/qapi-commands-misc.h"
30 #include "qapi/qmp/qerror.h"
31 #include "qapi/type-helpers.h"
32 #include "hw/mem/memory-device.h"
33 #include "hw/intc/intc.h"
34 #include "migration/misc.h"
35 
qmp_query_name(Error ** errp)36 NameInfo *qmp_query_name(Error **errp)
37 {
38     NameInfo *info = g_malloc0(sizeof(*info));
39 
40     info->name = g_strdup(qemu_name);
41     return info;
42 }
43 
qmp_quit(Error ** errp)44 void qmp_quit(Error **errp)
45 {
46     shutdown_action = SHUTDOWN_ACTION_POWEROFF;
47     qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
48 }
49 
qmp_stop(Error ** errp)50 void qmp_stop(Error **errp)
51 {
52     /* if there is a dump in background, we should wait until the dump
53      * finished */
54     if (qemu_system_dump_in_progress()) {
55         error_setg(errp, "There is a dump in process, please wait.");
56         return;
57     }
58 
59     if (runstate_check(RUN_STATE_INMIGRATE)) {
60         autostart = 0;
61     } else {
62         vm_stop(RUN_STATE_PAUSED);
63     }
64 }
65 
qmp_cont(Error ** errp)66 void qmp_cont(Error **errp)
67 {
68     BlockBackend *blk;
69     BlockJob *job;
70     Error *local_err = NULL;
71 
72     /* if there is a dump in background, we should wait until the dump
73      * finished */
74     if (qemu_system_dump_in_progress()) {
75         error_setg(errp, "There is a dump in process, please wait.");
76         return;
77     }
78 
79     if (runstate_needs_reset()) {
80         error_setg(errp, "Resetting the Virtual Machine is required");
81         return;
82     } else if (runstate_check(RUN_STATE_SUSPENDED)) {
83         return;
84     } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
85         error_setg(errp, "Migration is not finalized yet");
86         return;
87     }
88 
89     for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
90         blk_iostatus_reset(blk);
91     }
92 
93     WITH_JOB_LOCK_GUARD() {
94         for (job = block_job_next_locked(NULL); job;
95              job = block_job_next_locked(job)) {
96             block_job_iostatus_reset_locked(job);
97         }
98     }
99 
100     if (runstate_check(RUN_STATE_INMIGRATE)) {
101         autostart = 1;
102     } else {
103         /*
104          * Continuing after completed migration. Images have been
105          * inactivated to allow the destination to take control. Need to
106          * get control back now.
107          */
108         if (!migration_block_activate(&local_err)) {
109             error_propagate(errp, local_err);
110             return;
111         }
112         vm_start();
113     }
114 }
115 
qmp_add_client(const char * protocol,const char * fdname,bool has_skipauth,bool skipauth,bool has_tls,bool tls,Error ** errp)116 void qmp_add_client(const char *protocol, const char *fdname,
117                     bool has_skipauth, bool skipauth, bool has_tls, bool tls,
118                     Error **errp)
119 {
120     static const struct {
121         const char *name;
122         bool (*add_client)(int fd, bool has_skipauth, bool skipauth,
123                            bool has_tls, bool tls, Error **errp);
124     } protocol_table[] = {
125         { "spice", qmp_add_client_spice },
126 #ifdef CONFIG_VNC
127         { "vnc", qmp_add_client_vnc },
128 #endif
129 #ifdef CONFIG_DBUS_DISPLAY
130         { "@dbus-display", qmp_add_client_dbus_display },
131 #endif
132     };
133     int fd, i;
134 
135     fd = monitor_get_fd(monitor_cur(), fdname, errp);
136     if (fd < 0) {
137         return;
138     }
139 
140     if (!fd_is_socket(fd)) {
141         error_setg(errp, "parameter @fdname must name a socket");
142         close(fd);
143         return;
144     }
145 
146     for (i = 0; i < ARRAY_SIZE(protocol_table); i++) {
147         if (!strcmp(protocol, protocol_table[i].name)) {
148             if (!protocol_table[i].add_client(fd, has_skipauth, skipauth,
149                                               has_tls, tls, errp)) {
150                 close(fd);
151             }
152             return;
153         }
154     }
155 
156     if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls,
157                              protocol, errp)) {
158         close(fd);
159     }
160 }
161 
qmp_human_monitor_command(const char * command_line,bool has_cpu_index,int64_t cpu_index,Error ** errp)162 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
163                                 int64_t cpu_index, Error **errp)
164 {
165     char *output = NULL;
166     MonitorHMP hmp = {};
167 
168     monitor_data_init(&hmp.common, false, true, false);
169 
170     if (has_cpu_index) {
171         int ret = monitor_set_cpu(&hmp.common, cpu_index);
172         if (ret < 0) {
173             error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
174                        "a CPU number");
175             goto out;
176         }
177     }
178 
179     handle_hmp_command(&hmp, command_line);
180 
181     WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) {
182         output = g_strdup(hmp.common.outbuf->str);
183     }
184 
185 out:
186     monitor_data_destroy(&hmp.common);
187     return output;
188 }
189 
monitor_init_qmp_commands(void)190 static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
191 {
192     /*
193      * Two command lists:
194      * - qmp_commands contains all QMP commands
195      * - qmp_cap_negotiation_commands contains just
196      *   "qmp_capabilities", to enforce capability negotiation
197      */
198 
199     qmp_init_marshal(&qmp_commands);
200 
201     qmp_register_command(&qmp_commands, "device_add",
202                          qmp_device_add, 0, 0);
203 
204     QTAILQ_INIT(&qmp_cap_negotiation_commands);
205     qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities",
206                          qmp_marshal_qmp_capabilities,
207                          QCO_ALLOW_PRECONFIG, 0);
208 }
209