master
c 308 lines 8.73 KB
Raw
1 /*
2 * Core Definitions for QAPI/QMP Dispatch
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 LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
11 *
12 */
13
14 #include "qemu/osdep.h"
15
16 #include "qemu/aio.h"
17 #include "qemu/aio-wait.h"
18 #include "qapi/compat-policy.h"
19 #include "qapi/error.h"
20 #include "qapi/qmp-registry.h"
21 #include "qobject/qdict.h"
22 #include "qobject/qjson.h"
23 #include "qapi/qobject-input-visitor.h"
24 #include "qapi/qobject-output-visitor.h"
25 #include "qobject/qbool.h"
26 #include "qemu/coroutine.h"
27 #include "qemu/main-loop.h"
28 #include "monitor/monitor.h"
29
30 Visitor *qobject_input_visitor_new_qmp(QObject *obj)
31 {
32 Visitor *v = qobject_input_visitor_new(obj);
33
34 visit_set_policy(v, &compat_policy);
35 return v;
36 }
37
38 Visitor *qobject_output_visitor_new_qmp(QObject **result)
39 {
40 Visitor *v = qobject_output_visitor_new(result);
41
42 visit_set_policy(v, &compat_policy);
43 return v;
44 }
45
46 static QDict *qmp_dispatch_check_obj(QDict *dict, bool allow_oob,
47 Error **errp)
48 {
49 const char *exec_key = NULL;
50 const QDictEntry *ent;
51 const char *arg_name;
52 const QObject *arg_obj;
53
54 for (ent = qdict_first(dict); ent;
55 ent = qdict_next(dict, ent)) {
56 arg_name = qdict_entry_key(ent);
57 arg_obj = qdict_entry_value(ent);
58
59 if (!strcmp(arg_name, "execute")
60 || (!strcmp(arg_name, "exec-oob") && allow_oob)) {
61 if (qobject_type(arg_obj) != QTYPE_QSTRING) {
62 error_setg(errp, "QMP input member '%s' must be a string",
63 arg_name);
64 return NULL;
65 }
66 if (exec_key) {
67 error_setg(errp, "QMP input member '%s' clashes with '%s'",
68 arg_name, exec_key);
69 return NULL;
70 }
71 exec_key = arg_name;
72 } else if (!strcmp(arg_name, "arguments")) {
73 if (qobject_type(arg_obj) != QTYPE_QDICT) {
74 error_setg(errp,
75 "QMP input member 'arguments' must be an object");
76 return NULL;
77 }
78 } else if (!strcmp(arg_name, "id")) {
79 continue;
80 } else {
81 error_setg(errp, "QMP input member '%s' is unexpected",
82 arg_name);
83 return NULL;
84 }
85 }
86
87 if (!exec_key) {
88 error_setg(errp, "QMP input lacks member 'execute'");
89 return NULL;
90 }
91
92 return dict;
93 }
94
95 QDict *qmp_error_response(Error *err)
96 {
97 QDict *rsp;
98
99 rsp = qdict_from_jsonf_nofail("{ 'error': { 'class': %s, 'desc': %s } }",
100 QapiErrorClass_str(error_get_class(err)),
101 error_get_pretty(err));
102 error_free(err);
103 return rsp;
104 }
105
106 /*
107 * Does @qdict look like a command to be run out-of-band?
108 */
109 bool qmp_is_oob(const QDict *dict)
110 {
111 return qdict_haskey(dict, "exec-oob")
112 && !qdict_haskey(dict, "execute");
113 }
114
115 typedef struct QmpDispatchBH {
116 const QmpCommand *cmd;
117 Monitor *cur_mon;
118 QDict *args;
119 QObject **ret;
120 Error **errp;
121 Coroutine *co;
122 } QmpDispatchBH;
123
124 static void do_qmp_dispatch_bh(void *opaque)
125 {
126 QmpDispatchBH *data = opaque;
127
128 assert(monitor_cur() == NULL);
129 monitor_set_cur(qemu_coroutine_self(), data->cur_mon);
130 data->cmd->fn(data->args, data->ret, data->errp);
131 monitor_set_cur(qemu_coroutine_self(), NULL);
132 aio_co_wake(data->co);
133
134 /*
135 * If the QMP dispatcher coroutine is waiting to be scheduled
136 * in iohandler_ctx, we must kick the main loop. This ensures
137 * that AIO_WAIT_WHILE_UNLOCKED() in monitor_cleanup() doesn't
138 * block indefinitely waiting for an event in qemu_aio_context,
139 * but actually gets the chance to poll iohandler_ctx and resume
140 * the coroutine.
141 */
142 aio_wait_kick();
143 }
144
145 /*
146 * Runs outside of coroutine context for OOB commands, but in coroutine
147 * context for everything else.
148 */
149 QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *request,
150 bool allow_oob, Monitor *cur_mon)
151 {
152 Error *err = NULL;
153 bool oob;
154 const char *command;
155 QDict *args;
156 const QmpCommand *cmd;
157 QDict *dict;
158 QObject *id;
159 QObject *ret = NULL;
160 QDict *rsp = NULL;
161
162 dict = qobject_to(QDict, request);
163 if (!dict) {
164 id = NULL;
165 error_setg(&err, "QMP input must be a JSON object");
166 goto out;
167 }
168
169 id = qdict_get(dict, "id");
170
171 if (!qmp_dispatch_check_obj(dict, allow_oob, &err)) {
172 goto out;
173 }
174
175 command = qdict_get_try_str(dict, "execute");
176 oob = false;
177 if (!command) {
178 assert(allow_oob);
179 command = qdict_get_str(dict, "exec-oob");
180 oob = true;
181 }
182 cmd = qmp_find_command(cmds, command);
183 if (cmd == NULL) {
184 error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
185 "The command %s has not been found", command);
186 goto out;
187 }
188 if (!compat_policy_input_ok(cmd->features, &compat_policy,
189 ERROR_CLASS_COMMAND_NOT_FOUND,
190 "command", command, &err)) {
191 goto out;
192 }
193 if (!cmd->enabled) {
194 error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
195 "Command %s has been disabled%s%s",
196 command,
197 cmd->disable_reason ? ": " : "",
198 cmd->disable_reason ?: "");
199 goto out;
200 }
201 if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
202 error_setg(&err, "The command %s does not support OOB",
203 command);
204 goto out;
205 }
206
207 if (!qmp_command_available(cmd, &err)) {
208 goto out;
209 }
210
211 if (!qdict_haskey(dict, "arguments")) {
212 args = qdict_new();
213 } else {
214 args = qdict_get_qdict(dict, "arguments");
215 qobject_ref(args);
216 }
217
218 assert(!(oob && qemu_in_coroutine()));
219 assert(monitor_cur() == NULL);
220 if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) {
221 if (qemu_in_coroutine()) {
222 /*
223 * Move the coroutine from iohandler_ctx to qemu_aio_context for
224 * executing the command handler so that it can make progress if it
225 * involves an AIO_WAIT_WHILE().
226 */
227 aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self());
228 qemu_coroutine_yield();
229 }
230
231 monitor_set_cur(qemu_coroutine_self(), cur_mon);
232 cmd->fn(args, &ret, &err);
233 monitor_set_cur(qemu_coroutine_self(), NULL);
234
235 if (qemu_in_coroutine()) {
236 /*
237 * Yield and reschedule so the main loop stays responsive.
238 *
239 * Move back to iohandler_ctx so that nested event loops for
240 * qemu_aio_context don't start new monitor commands.
241 */
242 aio_co_schedule(iohandler_get_aio_context(),
243 qemu_coroutine_self());
244 qemu_coroutine_yield();
245 }
246 } else {
247 /*
248 * Actual context doesn't match the one the command needs.
249 *
250 * Case 1: we are in coroutine context, but command does not
251 * have QCO_COROUTINE. We need to drop out of coroutine
252 * context for executing it.
253 *
254 * Case 2: we are outside coroutine context, but command has
255 * QCO_COROUTINE. Can't actually happen, because we get here
256 * outside coroutine context only when executing a command
257 * out of band, and OOB commands never have QCO_COROUTINE.
258 */
259 assert(!oob && qemu_in_coroutine() && !(cmd->options & QCO_COROUTINE));
260
261 QmpDispatchBH data = {
262 .cur_mon = cur_mon,
263 .cmd = cmd,
264 .args = args,
265 .ret = &ret,
266 .errp = &err,
267 .co = qemu_coroutine_self(),
268 };
269 aio_bh_schedule_oneshot(iohandler_get_aio_context(), do_qmp_dispatch_bh,
270 &data);
271 qemu_coroutine_yield();
272 }
273 qobject_unref(args);
274 if (err) {
275 /* or assert(!ret) after reviewing all handlers: */
276 qobject_unref(ret);
277 goto out;
278 }
279
280 if (cmd->options & QCO_NO_SUCCESS_RESP) {
281 g_assert(!ret);
282 return NULL;
283 } else if (!ret) {
284 /*
285 * When the command's schema has no 'returns', cmd->fn()
286 * leaves @ret null. The QMP spec calls for an empty object
287 * then; supply it.
288 */
289 ret = QOBJECT(qdict_new());
290 }
291
292 rsp = qdict_new();
293 qdict_put_obj(rsp, "return", ret);
294
295 out:
296 if (err) {
297 assert(!rsp);
298 rsp = qmp_error_response(err);
299 }
300
301 assert(rsp);
302
303 if (id) {
304 qdict_put_obj(rsp, "id", qobject_ref(id));
305 }
306
307 return rsp;
308 }