1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26
27#include "chardev/char-io.h"
28#include "monitor-internal.h"
29#include "qapi/error.h"
30#include "qapi/qapi-commands-control.h"
31#include "qobject/qdict.h"
32#include "qobject/qjson.h"
33#include "qobject/qlist.h"
34#include "trace.h"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58static bool qmp_dispatcher_co_busy = true;
59
60struct QMPRequest {
61
62 MonitorQMP *mon;
63
64
65
66
67 QObject *req;
68 Error *err;
69};
70typedef struct QMPRequest QMPRequest;
71
72QmpCommandList qmp_commands, qmp_cap_negotiation_commands;
73
74static bool qmp_oob_enabled(MonitorQMP *mon)
75{
76 return mon->capab[QMP_CAPABILITY_OOB];
77}
78
79static void monitor_qmp_caps_reset(MonitorQMP *mon)
80{
81 memset(mon->capab_offered, 0, sizeof(mon->capab_offered));
82 memset(mon->capab, 0, sizeof(mon->capab));
83 mon->capab_offered[QMP_CAPABILITY_OOB] = mon->common.use_io_thread;
84}
85
86static void qmp_request_free(QMPRequest *req)
87{
88 qobject_unref(req->req);
89 error_free(req->err);
90 g_free(req);
91}
92
93
94static void monitor_qmp_cleanup_req_queue_locked(MonitorQMP *mon)
95{
96 while (!g_queue_is_empty(mon->qmp_requests)) {
97 qmp_request_free(g_queue_pop_head(mon->qmp_requests));
98 }
99}
100
101static void monitor_qmp_cleanup_queue_and_resume(MonitorQMP *mon)
102{
103 QEMU_LOCK_GUARD(&mon->qmp_queue_lock);
104
105
106
107
108
109
110
111 bool need_resume = (!qmp_oob_enabled(mon) ||
112 mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX)
113 && !g_queue_is_empty(mon->qmp_requests);
114
115 monitor_qmp_cleanup_req_queue_locked(mon);
116
117 if (need_resume) {
118
119
120
121
122
123
124
125
126
127 monitor_resume(&mon->common);
128 }
129
130}
131
132void qmp_send_response(MonitorQMP *mon, const QDict *rsp)
133{
134 const QObject *data = QOBJECT(rsp);
135 GString *json;
136
137 json = qobject_to_json_pretty(data, mon->pretty);
138 assert(json != NULL);
139 trace_monitor_qmp_respond(mon, json->str);
140
141 g_string_append_c(json, '\n');
142 monitor_puts(&mon->common, json->str);
143
144 g_string_free(json, true);
145}
146
147
148
149
150
151
152static void monitor_qmp_respond(MonitorQMP *mon, QDict *rsp)
153{
154 if (rsp) {
155 qmp_send_response(mon, rsp);
156 }
157}
158
159
160
161
162
163static void monitor_qmp_dispatch(MonitorQMP *mon, QObject *req)
164{
165 QDict *rsp;
166 QDict *error;
167
168 rsp = qmp_dispatch(mon->commands, req, qmp_oob_enabled(mon),
169 &mon->common);
170
171 if (mon->commands == &qmp_cap_negotiation_commands) {
172 error = qdict_get_qdict(rsp, "error");
173 if (error
174 && !g_strcmp0(qdict_get_try_str(error, "class"),
175 QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND))) {
176
177 qdict_del(error, "desc");
178 qdict_put_str(error, "desc", "Expecting capabilities negotiation"
179 " with 'qmp_capabilities'");
180 }
181 }
182
183 monitor_qmp_respond(mon, rsp);
184 qobject_unref(rsp);
185}
186
187
188
189
190
191
192
193
194
195
196
197
198
199static QMPRequest *monitor_qmp_requests_pop_any_with_lock(void)
200{
201 QMPRequest *req_obj = NULL;
202 Monitor *mon;
203 MonitorQMP *qmp_mon;
204
205 QTAILQ_FOREACH(mon, &mon_list, entry) {
206 if (!monitor_is_qmp(mon)) {
207 continue;
208 }
209
210 qmp_mon = container_of(mon, MonitorQMP, common);
211 qemu_mutex_lock(&qmp_mon->qmp_queue_lock);
212 req_obj = g_queue_pop_head(qmp_mon->qmp_requests);
213 if (req_obj) {
214
215 break;
216 }
217 qemu_mutex_unlock(&qmp_mon->qmp_queue_lock);
218 }
219
220 if (req_obj) {
221
222
223
224
225 QTAILQ_REMOVE(&mon_list, mon, entry);
226 QTAILQ_INSERT_TAIL(&mon_list, mon, entry);
227 }
228
229 return req_obj;
230}
231
232static QMPRequest *monitor_qmp_dispatcher_pop_any(void)
233{
234 while (true) {
235
236
237
238
239
240 assert(qatomic_read(&qmp_dispatcher_co_busy) == true);
241
242
243
244
245
246
247
248
249 qatomic_set_mb(&qmp_dispatcher_co_busy, false);
250
251 WITH_QEMU_LOCK_GUARD(&monitor_lock) {
252 QMPRequest *req_obj;
253
254
255 if (qmp_dispatcher_co_shutdown) {
256 return NULL;
257 }
258
259 req_obj = monitor_qmp_requests_pop_any_with_lock();
260 if (req_obj) {
261 return req_obj;
262 }
263 }
264
265
266
267
268
269
270 qemu_coroutine_yield();
271 }
272}
273
274void coroutine_fn monitor_qmp_dispatcher_co(void *data)
275{
276 QMPRequest *req_obj;
277 QDict *rsp;
278 bool oob_enabled;
279 MonitorQMP *mon;
280
281 while ((req_obj = monitor_qmp_dispatcher_pop_any()) != NULL) {
282 trace_monitor_qmp_in_band_dequeue(req_obj,
283 req_obj->mon->qmp_requests->length);
284
285
286
287
288
289 mon = req_obj->mon;
290
291
292
293
294
295
296
297
298
299
300
301
302 oob_enabled = qmp_oob_enabled(mon);
303 if (oob_enabled
304 && mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
305 monitor_resume(&mon->common);
306 }
307
308
309
310
311
312 qemu_mutex_unlock(&mon->qmp_queue_lock);
313
314 if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
315
316
317
318
319
320
321 qemu_coroutine_yield();
322 }
323
324
325 if (req_obj->req) {
326 if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {
327 QDict *qdict = qobject_to(QDict, req_obj->req);
328 QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
329 GString *id_json;
330
331 id_json = id ? qobject_to_json(id) : g_string_new(NULL);
332 trace_monitor_qmp_cmd_in_band(id_json->str);
333 g_string_free(id_json, true);
334 }
335 monitor_qmp_dispatch(mon, req_obj->req);
336 } else {
337 assert(req_obj->err);
338 trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err));
339 rsp = qmp_error_response(req_obj->err);
340 req_obj->err = NULL;
341 monitor_qmp_respond(mon, rsp);
342 qobject_unref(rsp);
343 }
344
345 if (!oob_enabled) {
346 monitor_resume(&mon->common);
347 }
348
349 qmp_request_free(req_obj);
350 }
351 qatomic_set(&qmp_dispatcher_co, NULL);
352}
353
354void qmp_dispatcher_co_wake(void)
355{
356
357 smp_mb__before_rmw();
358
359 if (!qatomic_xchg(&qmp_dispatcher_co_busy, true) &&
360 qatomic_read(&qmp_dispatcher_co)) {
361 aio_co_wake(qmp_dispatcher_co);
362 }
363}
364
365static void handle_qmp_command(void *opaque, QObject *req, Error *err)
366{
367 MonitorQMP *mon = opaque;
368 QDict *qdict = qobject_to(QDict, req);
369 QMPRequest *req_obj;
370
371 assert(!req != !err);
372
373 if (req && trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
374 GString *req_json = qobject_to_json(req);
375 trace_handle_qmp_command(mon, req_json->str);
376 g_string_free(req_json, true);
377 }
378
379 if (qdict && qmp_is_oob(qdict)) {
380
381 if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_OUT_OF_BAND)) {
382 QObject *id = qdict_get(qdict, "id");
383 GString *id_json;
384
385 id_json = id ? qobject_to_json(id) : g_string_new(NULL);
386 trace_monitor_qmp_cmd_out_of_band(id_json->str);
387 g_string_free(id_json, true);
388 }
389 monitor_qmp_dispatch(mon, req);
390 qobject_unref(req);
391 return;
392 }
393
394 req_obj = g_new0(QMPRequest, 1);
395 req_obj->mon = mon;
396 req_obj->req = req;
397 req_obj->err = err;
398
399
400 WITH_QEMU_LOCK_GUARD(&mon->qmp_queue_lock) {
401
402
403
404
405
406
407
408
409 if (!qmp_oob_enabled(mon) ||
410 mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
411 monitor_suspend(&mon->common);
412 }
413
414
415
416
417
418
419 trace_monitor_qmp_in_band_enqueue(req_obj, mon,
420 mon->qmp_requests->length);
421 assert(mon->qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX);
422 g_queue_push_tail(mon->qmp_requests, req_obj);
423 }
424
425
426 qmp_dispatcher_co_wake();
427}
428
429static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
430{
431 MonitorQMP *mon = opaque;
432
433 json_message_parser_feed(&mon->parser, (const char *) buf, size);
434}
435
436static QDict *qmp_greeting(MonitorQMP *mon)
437{
438 QList *cap_list = qlist_new();
439 QObject *ver = NULL;
440 QDict *args;
441 QMPCapability cap;
442
443 args = qdict_new();
444 qmp_marshal_query_version(args, &ver, NULL);
445 qobject_unref(args);
446
447 for (cap = 0; cap < QMP_CAPABILITY__MAX; cap++) {
448 if (mon->capab_offered[cap]) {
449 qlist_append_str(cap_list, QMPCapability_str(cap));
450 }
451 }
452
453 return qdict_from_jsonf_nofail(
454 "{'QMP': {'version': %p, 'capabilities': %p}}",
455 ver, cap_list);
456}
457
458static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
459{
460 QDict *data;
461 MonitorQMP *mon = opaque;
462
463 switch (event) {
464 case CHR_EVENT_OPENED:
465 mon->commands = &qmp_cap_negotiation_commands;
466 monitor_qmp_caps_reset(mon);
467 data = qmp_greeting(mon);
468 qmp_send_response(mon, data);
469 qobject_unref(data);
470 break;
471 case CHR_EVENT_CLOSED:
472
473
474
475
476
477
478 monitor_qmp_cleanup_queue_and_resume(mon);
479 json_message_parser_destroy(&mon->parser);
480 json_message_parser_init(&mon->parser, handle_qmp_command,
481 mon, NULL);
482 monitor_fdsets_cleanup();
483 break;
484 case CHR_EVENT_BREAK:
485 case CHR_EVENT_MUX_IN:
486 case CHR_EVENT_MUX_OUT:
487
488 break;
489 }
490}
491
492void monitor_data_destroy_qmp(MonitorQMP *mon)
493{
494 json_message_parser_destroy(&mon->parser);
495 qemu_mutex_destroy(&mon->qmp_queue_lock);
496 monitor_qmp_cleanup_req_queue_locked(mon);
497 g_queue_free(mon->qmp_requests);
498}
499
500static void monitor_qmp_setup_handlers_bh(void *opaque)
501{
502 MonitorQMP *mon = opaque;
503 GMainContext *context;
504
505 assert(mon->common.use_io_thread);
506 context = iothread_get_g_main_context(mon_iothread);
507 assert(context);
508 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
509 monitor_qmp_read, monitor_qmp_event,
510 NULL, &mon->common, context, true);
511 monitor_list_append(&mon->common);
512}
513
514void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
515{
516 MonitorQMP *mon = g_new0(MonitorQMP, 1);
517
518 if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
519 g_free(mon);
520 return;
521 }
522 qemu_chr_fe_set_echo(&mon->common.chr, true);
523
524
525 monitor_data_init(&mon->common, true, false,
526 qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
527
528 mon->pretty = pretty;
529
530 qemu_mutex_init(&mon->qmp_queue_lock);
531 mon->qmp_requests = g_queue_new();
532
533 json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
534 if (mon->common.use_io_thread) {
535
536
537
538
539 remove_fd_in_watch(chr);
540
541
542
543
544
545 aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
546 monitor_qmp_setup_handlers_bh, mon);
547
548 } else {
549 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
550 monitor_qmp_read, monitor_qmp_event,
551 NULL, &mon->common, NULL, true);
552 monitor_list_append(&mon->common);
553 }
554}
555