1
2
3
4
5
6
7
8
9
10
11
12
13
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 "sysemu/sysemu.h"
22#include "sysemu/kvm.h"
23#include "sysemu/runstate.h"
24#include "sysemu/runstate-action.h"
25#include "sysemu/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 "hw/rdma/rdma.h"
35
36NameInfo *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
44void qmp_quit(Error **errp)
45{
46 shutdown_action = SHUTDOWN_ACTION_POWEROFF;
47 qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
48}
49
50void qmp_stop(Error **errp)
51{
52
53
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
66void qmp_cont(Error **errp)
67{
68 BlockBackend *blk;
69 BlockJob *job;
70 Error *local_err = NULL;
71
72
73
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
101
102
103
104
105
106 bdrv_activate_all(&local_err);
107 if (local_err) {
108 error_propagate(errp, local_err);
109 return;
110 }
111
112 if (runstate_check(RUN_STATE_INMIGRATE)) {
113 autostart = 1;
114 } else {
115 vm_start();
116 }
117}
118
119void qmp_add_client(const char *protocol, const char *fdname,
120 bool has_skipauth, bool skipauth, bool has_tls, bool tls,
121 Error **errp)
122{
123 static const struct {
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 };
136 int fd, i;
137
138 fd = monitor_get_fd(monitor_cur(), fdname, errp);
139 if (fd < 0) {
140 return;
141 }
142
143 if (!fd_is_socket(fd)) {
144 error_setg(errp, "parameter @fdname must name a socket");
145 close(fd);
146 return;
147 }
148
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 }
155 return;
156 }
157 }
158
159 if (!qmp_add_client_char(fd, has_skipauth, skipauth, has_tls, tls,
160 protocol, errp)) {
161 close(fd);
162 }
163}
164
165char *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
188out:
189 monitor_data_destroy(&hmp.common);
190 return output;
191}
192
193static void __attribute__((__constructor__)) monitor_init_qmp_commands(void)
194{
195
196
197
198
199
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}
212