]>
Commit | Line | Data |
---|---|---|
48a32bed | 1 | /* |
f1b3ccfa | 2 | * QEMU Management Protocol commands |
48a32bed AL |
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 | * | |
6b620ca3 PB |
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. | |
48a32bed AL |
14 | */ |
15 | ||
d38ea87a | 16 | #include "qemu/osdep.h" |
bf5de8c5 | 17 | #include "qemu/sockets.h" |
e6e108d1 MA |
18 | #include "monitor-internal.h" |
19 | #include "monitor/qdev.h" | |
3125af29 | 20 | #include "monitor/qmp-helpers.h" |
9c17d615 | 21 | #include "sysemu/sysemu.h" |
9c17d615 | 22 | #include "sysemu/kvm.h" |
54d31236 | 23 | #include "sysemu/runstate.h" |
e6dba048 | 24 | #include "sysemu/runstate-action.h" |
373340b2 | 25 | #include "sysemu/block-backend.h" |
e688df6b | 26 | #include "qapi/error.h" |
e6e108d1 | 27 | #include "qapi/qapi-init-commands.h" |
fa4dcf57 | 28 | #include "qapi/qapi-commands-control.h" |
112ed241 | 29 | #include "qapi/qapi-commands-misc.h" |
e6e108d1 | 30 | #include "qapi/qmp/qerror.h" |
37087fde | 31 | #include "qapi/type-helpers.h" |
2cc0e2e8 | 32 | #include "hw/mem/memory-device.h" |
91f2fa70 | 33 | #include "hw/intc/intc.h" |
8dbbca5c | 34 | #include "hw/rdma/rdma.h" |
48a32bed AL |
35 | |
36 | NameInfo *qmp_query_name(Error **errp) | |
37 | { | |
38 | NameInfo *info = g_malloc0(sizeof(*info)); | |
39 | ||
9492718b | 40 | info->name = g_strdup(qemu_name); |
48a32bed AL |
41 | return info; |
42 | } | |
b9c15f16 | 43 | |
7daecb30 | 44 | void qmp_quit(Error **errp) |
7a7f325e | 45 | { |
e6dba048 | 46 | shutdown_action = SHUTDOWN_ACTION_POWEROFF; |
92548938 | 47 | qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT); |
7a7f325e LC |
48 | } |
49 | ||
5f158f21 LC |
50 | void qmp_stop(Error **errp) |
51 | { | |
65d64f36 PX |
52 | /* if there is a dump in background, we should wait until the dump |
53 | * finished */ | |
544803c7 | 54 | if (qemu_system_dump_in_progress()) { |
65d64f36 PX |
55 | error_setg(errp, "There is a dump in process, please wait."); |
56 | return; | |
57 | } | |
58 | ||
1e998146 PB |
59 | if (runstate_check(RUN_STATE_INMIGRATE)) { |
60 | autostart = 0; | |
61 | } else { | |
62 | vm_stop(RUN_STATE_PAUSED); | |
63 | } | |
5f158f21 LC |
64 | } |
65 | ||
e42e818b LC |
66 | void qmp_cont(Error **errp) |
67 | { | |
373340b2 | 68 | BlockBackend *blk; |
68d00e42 | 69 | BlockJob *job; |
788cf9f8 | 70 | Error *local_err = NULL; |
e42e818b | 71 | |
65d64f36 PX |
72 | /* if there is a dump in background, we should wait until the dump |
73 | * finished */ | |
544803c7 | 74 | if (qemu_system_dump_in_progress()) { |
65d64f36 PX |
75 | error_setg(errp, "There is a dump in process, please wait."); |
76 | return; | |
77 | } | |
78 | ||
ede085b3 | 79 | if (runstate_needs_reset()) { |
f231b88d | 80 | error_setg(errp, "Resetting the Virtual Machine is required"); |
e42e818b | 81 | return; |
ad02b96a LC |
82 | } else if (runstate_check(RUN_STATE_SUSPENDED)) { |
83 | return; | |
9183dd15 VSO |
84 | } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { |
85 | error_setg(errp, "Migration is not finalized yet"); | |
86 | return; | |
e42e818b LC |
87 | } |
88 | ||
373340b2 HR |
89 | for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { |
90 | blk_iostatus_reset(blk); | |
ab31979a | 91 | } |
7c8eece4 | 92 | |
880eeec6 EGE |
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 | } | |
68d00e42 VSO |
98 | } |
99 | ||
76b1c7fe | 100 | /* Continuing after completed migration. Images have been inactivated to |
ace21a58 KW |
101 | * allow the destination to take control. Need to get control back now. |
102 | * | |
103 | * If there are no inactive block nodes (e.g. because the VM was just | |
104 | * paused rather than completing a migration), bdrv_inactivate_all() simply | |
105 | * doesn't do anything. */ | |
3b717194 | 106 | bdrv_activate_all(&local_err); |
ace21a58 KW |
107 | if (local_err) { |
108 | error_propagate(errp, local_err); | |
109 | return; | |
76b1c7fe KW |
110 | } |
111 | ||
1e998146 PB |
112 | if (runstate_check(RUN_STATE_INMIGRATE)) { |
113 | autostart = 1; | |
114 | } else { | |
115 | vm_start(); | |
116 | } | |
e42e818b | 117 | } |
b4b12c62 | 118 | |
b224e5e2 LC |
119 | void qmp_add_client(const char *protocol, const char *fdname, |
120 | bool has_skipauth, bool skipauth, bool has_tls, bool tls, | |
121 | Error **errp) | |
122 | { | |
f916a175 | 123 | static const struct { |
3125af29 MA |
124 | const char *name; |
125 | bool (*add_client)(int fd, bool has_skipauth, bool skipauth, | |
126 | bool has_tls, bool tls, Error **errp); | |
127 | } protocol_table[] = { | |
128 | { "spice", qmp_add_client_spice }, | |
129 | #ifdef CONFIG_VNC | |
130 | { "vnc", qmp_add_client_vnc }, | |
131 | #endif | |
132 | #ifdef CONFIG_DBUS_DISPLAY | |
133 | { "@dbus-display", qmp_add_client_dbus_display }, | |
134 | #endif | |
135 | }; | |
3125af29 | 136 | int fd, i; |
b224e5e2 | 137 | |
947e4744 | 138 | fd = monitor_get_fd(monitor_cur(), fdname, errp); |
b224e5e2 LC |
139 | if (fd < 0) { |
140 | return; | |
141 | } | |
142 | ||
bf5de8c5 MAL |
143 | if (!fd_is_socket(fd)) { |
144 | error_setg(errp, "parameter @fdname must name a socket"); | |
145 | close(fd); | |
146 | return; | |
147 | } | |
148 | ||
3125af29 MA |
149 | for (i = 0; i < ARRAY_SIZE(protocol_table); i++) { |
150 | if (!strcmp(protocol, protocol_table[i].name)) { | |
151 | if (!protocol_table[i].add_client(fd, has_skipauth, skipauth, | |
152 | has_tls, tls, errp)) { | |
153 | close(fd); | |
154 | } | |
b224e5e2 LC |
155 | return; |
156 | } | |
b224e5e2 | 157 | } |
3125af29 | 158 | |
c3054a6e MA |
159 | if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls, |
160 | protocol, errp)) { | |
3125af29 | 161 | close(fd); |
3125af29 | 162 | } |
b224e5e2 | 163 | } |
e6e108d1 MA |
164 | |
165 | char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index, | |
166 | int64_t cpu_index, Error **errp) | |
167 | { | |
168 | char *output = NULL; | |
169 | MonitorHMP hmp = {}; | |
170 | ||
171 | monitor_data_init(&hmp.common, false, true, false); | |
172 | ||
173 | if (has_cpu_index) { | |
174 | int ret = monitor_set_cpu(&hmp.common, cpu_index); | |
175 | if (ret < 0) { | |
176 | error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index", | |
177 | "a CPU number"); | |
178 | goto out; | |
179 | } | |
180 | } | |
181 | ||
182 | handle_hmp_command(&hmp, command_line); | |
183 | ||
184 | WITH_QEMU_LOCK_GUARD(&hmp.common.mon_lock) { | |
185 | output = g_strdup(hmp.common.outbuf->str); | |
186 | } | |
187 | ||
188 | out: | |
189 | monitor_data_destroy(&hmp.common); | |
190 | return output; | |
191 | } | |
192 | ||
193 | static void __attribute__((__constructor__)) monitor_init_qmp_commands(void) | |
194 | { | |
195 | /* | |
196 | * Two command lists: | |
197 | * - qmp_commands contains all QMP commands | |
198 | * - qmp_cap_negotiation_commands contains just | |
199 | * "qmp_capabilities", to enforce capability negotiation | |
200 | */ | |
201 | ||
202 | qmp_init_marshal(&qmp_commands); | |
203 | ||
204 | qmp_register_command(&qmp_commands, "device_add", | |
205 | qmp_device_add, 0, 0); | |
206 | ||
207 | QTAILQ_INIT(&qmp_cap_negotiation_commands); | |
208 | qmp_register_command(&qmp_cap_negotiation_commands, "qmp_capabilities", | |
209 | qmp_marshal_qmp_capabilities, | |
210 | QCO_ALLOW_PRECONFIG, 0); | |
211 | } |