[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v2 18/22] qmp: support out-of-band (oob) execution
From: |
Peter Xu |
Subject: |
[Qemu-devel] [RFC v2 18/22] qmp: support out-of-band (oob) execution |
Date: |
Fri, 29 Sep 2017 11:38:40 +0800 |
Having "allow-oob" to true for a command does not mean that this command
will always be run in out-of-band mode. The out-of-band quick path will
only be executed if we specify the extra "run-oob" flag when sending the
QMP request:
{ "execute": "command-that-allows-oob",
"arguments": { ... },
"control": { "run-oob": true } }
The "control" key is introduced to store this extra flag. "control"
field is used to store arguments that are shared by all the commands,
rather than command specific arguments. Let "run-oob" be the first.
Signed-off-by: Peter Xu <address@hidden>
---
include/qapi/qmp/dispatch.h | 1 +
monitor.c | 8 ++++++++
qapi/qmp-dispatch.c | 34 ++++++++++++++++++++++++++++++++++
trace-events | 2 ++
4 files changed, 45 insertions(+)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index b76798800c..ee2b8ce576 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -49,6 +49,7 @@ bool qmp_command_is_enabled(const QmpCommand *cmd);
const char *qmp_command_name(const QmpCommand *cmd);
bool qmp_has_success_response(const QmpCommand *cmd);
QObject *qmp_build_error_object(Error *err);
+bool qmp_is_oob(const QObject *request);
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
diff --git a/monitor.c b/monitor.c
index 847468ecb0..2be79eadcc 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3968,6 +3968,7 @@ static void monitor_qmp_bh_dispatcher(void *data)
if (!req_obj) {
break;
}
+ trace_monitor_qmp_cmd_in_band(qobject_get_try_str(req_obj->id));
monitor_qmp_dispatch_one(req_obj);
}
}
@@ -4005,6 +4006,13 @@ static void handle_qmp_command(JSONMessageParser
*parser, GQueue *tokens,
req_obj->id = id;
req_obj->req = req;
+ if (qmp_is_oob(req)) {
+ /* Out-Of-Band (OOB) requests are executed directly in parser. */
+ trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(req_obj->id));
+ monitor_qmp_dispatch_one(req_obj);
+ return;
+ }
+
/* Drop the request if queue is full. */
if (mon->qmp_requests->length >= QMP_ASYNC_QUEUE_LEN_MAX) {
const char *id_str = qobject_get_try_str(id);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index b41fa174fe..3c7c67acc1 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -52,6 +52,12 @@ static QDict *qmp_dispatch_check_obj(const QObject *request,
Error **errp)
"QMP input member 'arguments' must be an object");
return NULL;
}
+ } else if (!strcmp(arg_name, "control")) {
+ if (qobject_type(arg_obj) != QTYPE_QDICT) {
+ error_setg(errp,
+ "QMP input member 'control' must be a dict");
+ return NULL;
+ }
} else {
error_setg(errp, "QMP input member '%s' is unexpected",
arg_name);
@@ -122,6 +128,34 @@ QObject *qmp_build_error_object(Error *err)
error_get_pretty(err));
}
+/*
+ * Detect whether a request should be run out-of-band, by quickly
+ * peeking at whether we have: { "control": { "run-oob": True } }. By
+ * default commands are run in-band.
+ */
+bool qmp_is_oob(const QObject *request)
+{
+ QDict *dict;
+ QBool *bool_obj;
+
+ dict = qobject_to_qdict(request);
+ if (!dict) {
+ return false;
+ }
+
+ dict = qdict_get_qdict(dict, "control");
+ if (!dict) {
+ return false;
+ }
+
+ bool_obj = qobject_to_qbool(qdict_get(dict, "run-oob"));
+ if (!bool_obj) {
+ return false;
+ }
+
+ return qbool_get_bool(bool_obj);
+}
+
QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request)
{
Error *err = NULL;
diff --git a/trace-events b/trace-events
index 1d2eb5d3e4..3148e590c9 100644
--- a/trace-events
+++ b/trace-events
@@ -47,6 +47,8 @@ monitor_protocol_event_emit(uint32_t event, void *data)
"event=%d data=%p"
monitor_protocol_event_queue(uint32_t event, void *qdict, uint64_t rate)
"event=%d data=%p rate=%" PRId64
handle_hmp_command(void *mon, const char *cmdline) "mon %p cmdline: %s"
handle_qmp_command(void *mon, const char *req) "mon %p req: %s"
+monitor_qmp_cmd_in_band(const char *id) "%s"
+monitor_qmp_cmd_out_of_band(const char *id) "%s"
# dma-helpers.c
dma_blk_io(void *dbs, void *bs, int64_t offset, bool to_dev) "dbs=%p bs=%p
offset=%" PRId64 " to_dev=%d"
--
2.13.5
- [Qemu-devel] [RFC v2 07/22] monitor: move the cur_mon hack deeper for QMP, (continued)
- [Qemu-devel] [RFC v2 07/22] monitor: move the cur_mon hack deeper for QMP, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 09/22] monitor: create monitor dedicate iothread, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 10/22] monitor: allow to use IO thread for parsing, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 11/22] monitor: introduce monitor_qmp_respond(), Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 12/22] monitor: let mon_list be tail queue, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 13/22] monitor: separate QMP parser and dispatcher, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 14/22] qmp: add new event "request-dropped", Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 15/22] monitor: send event when request queue full, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 16/22] monitor: enable IO thread for (qmp & !mux) typed, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 17/22] qapi: introduce new cmd option "allow-oob", Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 18/22] qmp: support out-of-band (oob) execution,
Peter Xu <=
- [Qemu-devel] [RFC v2 19/22] qmp: let migrate-incoming allow out-of-band, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 20/22] qmp: isolate responses into io thread, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 21/22] qmp: introduce QMPCapability, Peter Xu, 2017/09/28
- [Qemu-devel] [RFC v2 22/22] docs: update QMP documents for OOB commands, Peter Xu, 2017/09/28
- Re: [Qemu-devel] [RFC v2 00/22] QMP: out-of-band (OOB) execution support, no-reply, 2017/09/28
- Re: [Qemu-devel] [RFC v2 00/22] QMP: out-of-band (OOB) execution support, no-reply, 2017/09/29