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 "qapi/qmp/qdict.h"
32#include "qapi/qmp/qjson.h"
33#include "qapi/qmp/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
326
327
328
329 aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co);
330 qemu_coroutine_yield();
331
332
333 if (req_obj->req) {
334 if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {
335 QDict *qdict = qobject_to(QDict, req_obj->req);
336 QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
337 GString *id_json;
338
339 id_json = id ? qobject_to_json(id) : g_string_new(NULL);
340 trace_monitor_qmp_cmd_in_band(id_json->str);
341 g_string_free(id_json, true);
342 }
343 monitor_qmp_dispatch(mon, req_obj->req);
344 } else {
345 assert(req_obj->err);
346 trace_monitor_qmp_err_in_band(error_get_pretty(req_obj->err));
347 rsp = qmp_error_response(req_obj->err);
348 req_obj->err = NULL;
349 monitor_qmp_respond(mon, rsp);
350 qobject_unref(rsp);
351 }
352
353 if (!oob_enabled) {
354 monitor_resume(&mon->common);
355 }
356
357 qmp_request_free(req_obj);
358
359
360
361
362
363
364
365 aio_co_schedule(iohandler_get_aio_context(), qmp_dispatcher_co);
366 qemu_coroutine_yield();
367 }
368 qatomic_set(&qmp_dispatcher_co, NULL);
369}
370
371void qmp_dispatcher_co_wake(void)
372{
373
374 smp_mb__before_rmw();
375
376 if (!qatomic_xchg(&qmp_dispatcher_co_busy, true)) {
377 aio_co_wake(qmp_dispatcher_co);
378 }
379}
380
381static void handle_qmp_command(void *opaque, QObject *req, Error *err)
382{
383 MonitorQMP *mon = opaque;
384 QDict *qdict = qobject_to(QDict, req);
385 QMPRequest *req_obj;
386
387 assert(!req != !err);
388
389 if (req && trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
390 GString *req_json = qobject_to_json(req);
391 trace_handle_qmp_command(mon, req_json->str);
392 g_string_free(req_json, true);
393 }
394
395 if (qdict && qmp_is_oob(qdict)) {
396
397 if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_OUT_OF_BAND)) {
398 QObject *id = qdict_get(qdict, "id");
399 GString *id_json;
400
401 id_json = id ? qobject_to_json(id) : g_string_new(NULL);
402 trace_monitor_qmp_cmd_out_of_band(id_json->str);
403 g_string_free(id_json, true);
404 }
405 monitor_qmp_dispatch(mon, req);
406 qobject_unref(req);
407 return;
408 }
409
410 req_obj = g_new0(QMPRequest, 1);
411 req_obj->mon = mon;
412 req_obj->req = req;
413 req_obj->err = err;
414
415
416 WITH_QEMU_LOCK_GUARD(&mon->qmp_queue_lock) {
417
418
419
420
421
422
423
424
425 if (!qmp_oob_enabled(mon) ||
426 mon->qmp_requests->length == QMP_REQ_QUEUE_LEN_MAX - 1) {
427 monitor_suspend(&mon->common);
428 }
429
430
431
432
433
434
435 trace_monitor_qmp_in_band_enqueue(req_obj, mon,
436 mon->qmp_requests->length);
437 assert(mon->qmp_requests->length < QMP_REQ_QUEUE_LEN_MAX);
438 g_queue_push_tail(mon->qmp_requests, req_obj);
439 }
440
441
442 qmp_dispatcher_co_wake();
443}
444
445static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
446{
447 MonitorQMP *mon = opaque;
448
449 json_message_parser_feed(&mon->parser, (const char *) buf, size);
450}
451
452static QDict *qmp_greeting(MonitorQMP *mon)
453{
454 QList *cap_list = qlist_new();
455 QObject *ver = NULL;
456 QDict *args;
457 QMPCapability cap;
458
459 args = qdict_new();
460 qmp_marshal_query_version(args, &ver, NULL);
461 qobject_unref(args);
462
463 for (cap = 0; cap < QMP_CAPABILITY__MAX; cap++) {
464 if (mon->capab_offered[cap]) {
465 qlist_append_str(cap_list, QMPCapability_str(cap));
466 }
467 }
468
469 return qdict_from_jsonf_nofail(
470 "{'QMP': {'version': %p, 'capabilities': %p}}",
471 ver, cap_list);
472}
473
474static void monitor_qmp_event(void *opaque, QEMUChrEvent event)
475{
476 QDict *data;
477 MonitorQMP *mon = opaque;
478
479 switch (event) {
480 case CHR_EVENT_OPENED:
481 mon->commands = &qmp_cap_negotiation_commands;
482 monitor_qmp_caps_reset(mon);
483 data = qmp_greeting(mon);
484 qmp_send_response(mon, data);
485 qobject_unref(data);
486 mon_refcount++;
487 break;
488 case CHR_EVENT_CLOSED:
489
490
491
492
493
494
495 monitor_qmp_cleanup_queue_and_resume(mon);
496 json_message_parser_destroy(&mon->parser);
497 json_message_parser_init(&mon->parser, handle_qmp_command,
498 mon, NULL);
499 mon_refcount--;
500 monitor_fdsets_cleanup();
501 break;
502 case CHR_EVENT_BREAK:
503 case CHR_EVENT_MUX_IN:
504 case CHR_EVENT_MUX_OUT:
505
506 break;
507 }
508}
509
510void monitor_data_destroy_qmp(MonitorQMP *mon)
511{
512 json_message_parser_destroy(&mon->parser);
513 qemu_mutex_destroy(&mon->qmp_queue_lock);
514 monitor_qmp_cleanup_req_queue_locked(mon);
515 g_queue_free(mon->qmp_requests);
516}
517
518static void monitor_qmp_setup_handlers_bh(void *opaque)
519{
520 MonitorQMP *mon = opaque;
521 GMainContext *context;
522
523 assert(mon->common.use_io_thread);
524 context = iothread_get_g_main_context(mon_iothread);
525 assert(context);
526 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
527 monitor_qmp_read, monitor_qmp_event,
528 NULL, &mon->common, context, true);
529 monitor_list_append(&mon->common);
530}
531
532void monitor_init_qmp(Chardev *chr, bool pretty, Error **errp)
533{
534 MonitorQMP *mon = g_new0(MonitorQMP, 1);
535
536 if (!qemu_chr_fe_init(&mon->common.chr, chr, errp)) {
537 g_free(mon);
538 return;
539 }
540 qemu_chr_fe_set_echo(&mon->common.chr, true);
541
542
543 monitor_data_init(&mon->common, true, false,
544 qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
545
546 mon->pretty = pretty;
547
548 qemu_mutex_init(&mon->qmp_queue_lock);
549 mon->qmp_requests = g_queue_new();
550
551 json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
552 if (mon->common.use_io_thread) {
553
554
555
556
557 remove_fd_in_watch(chr);
558
559
560
561
562
563 aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
564 monitor_qmp_setup_handlers_bh, mon);
565
566 } else {
567 qemu_chr_fe_set_handlers(&mon->common.chr, monitor_can_read,
568 monitor_qmp_read, monitor_qmp_event,
569 NULL, &mon->common, NULL, true);
570 monitor_list_append(&mon->common);
571 }
572}
573