[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 18/18] RFC: qmp: common 'id' handling & make QGA
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v2 18/18] RFC: qmp: common 'id' handling & make QGA conform to QMP spec |
Date: |
Thu, 19 Jul 2018 20:41:11 +0200 |
Let qmp_dispatch() copy the 'id' field. That way any qmp client will
conform to the specification, including QGA. Furthermore, it
simplifies the work for qemu monitor.
CC: Michael Roth <address@hidden>
Signed-off-by: Marc-André Lureau <address@hidden>
---
monitor.c | 30 +++++++++++-------------------
qapi/qmp-dispatch.c | 12 +++++++++---
tests/test-qga.c | 13 +++++--------
3 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/monitor.c b/monitor.c
index 5a41a230b9..11249e7018 100644
--- a/monitor.c
+++ b/monitor.c
@@ -249,8 +249,6 @@ QEMUBH *qmp_dispatcher_bh;
struct QMPRequest {
/* Owner of the request */
Monitor *mon;
- /* "id" field of the request */
- QObject *id;
/*
* Request object to be handled or Error to be reported
* (exactly one of them is non-null)
@@ -351,7 +349,6 @@ int monitor_read_password(Monitor *mon, ReadLineFunc
*readline_func,
static void qmp_request_free(QMPRequest *req)
{
- qobject_unref(req->id);
qobject_unref(req->req);
error_free(req->err);
g_free(req);
@@ -3991,18 +3988,14 @@ static int monitor_can_read(void *opaque)
* Null @rsp can only happen for commands with QCO_NO_SUCCESS_RESP.
* Nothing is emitted then.
*/
-static void monitor_qmp_respond(Monitor *mon, QDict *rsp, QObject *id)
+static void monitor_qmp_respond(Monitor *mon, QDict *rsp)
{
if (rsp) {
- if (id) {
- qdict_put_obj(rsp, "id", qobject_ref(id));
- }
-
qmp_send_response(mon, rsp);
}
}
-static void monitor_qmp_dispatch(Monitor *mon, QObject *req, QObject *id)
+static void monitor_qmp_dispatch(Monitor *mon, QObject *req)
{
Monitor *old_mon;
QDict *rsp;
@@ -4027,7 +4020,7 @@ static void monitor_qmp_dispatch(Monitor *mon, QObject
*req, QObject *id)
}
}
- monitor_qmp_respond(mon, rsp, id);
+ monitor_qmp_respond(mon, rsp);
qobject_unref(rsp);
}
@@ -4082,13 +4075,15 @@ static void monitor_qmp_bh_dispatcher(void *data)
/* qmp_oob_enabled() might change after "qmp_capabilities" */
need_resume = !qmp_oob_enabled(req_obj->mon);
if (req_obj->req) {
- trace_monitor_qmp_cmd_in_band(qobject_get_try_str(req_obj->id) ?: "");
- monitor_qmp_dispatch(req_obj->mon, req_obj->req, req_obj->id);
+ QDict *qdict = qobject_to(QDict, req_obj->req);
+ QObject *id = qdict ? qdict_get(qdict, "id") : NULL;
+ trace_monitor_qmp_cmd_in_band(qobject_get_try_str(id) ?: "");
+ monitor_qmp_dispatch(req_obj->mon, req_obj->req);
} else {
assert(req_obj->err);
rsp = qmp_error_response(req_obj->err);
req_obj->err = NULL;
- monitor_qmp_respond(req_obj->mon, rsp, NULL);
+ monitor_qmp_respond(req_obj->mon, rsp);
qobject_unref(rsp);
}
@@ -4117,8 +4112,7 @@ static void handle_qmp_command(JSONMessageParser *parser,
GQueue *tokens)
qdict = qobject_to(QDict, req);
if (qdict) {
- id = qobject_ref(qdict_get(qdict, "id"));
- qdict_del(qdict, "id");
+ id = qdict_get(qdict, "id");
} /* else will fail qmp_dispatch() */
if (req && trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND)) {
@@ -4129,15 +4123,13 @@ static void handle_qmp_command(JSONMessageParser
*parser, GQueue *tokens)
if (qdict && qmp_is_oob(qdict)) {
/* OOB commands are executed immediately */
- trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(id)
- ?: "");
- monitor_qmp_dispatch(mon, req, id);
+ trace_monitor_qmp_cmd_out_of_band(qobject_get_try_str(id) ?: "");
+ monitor_qmp_dispatch(mon, req);
return;
}
req_obj = g_new0(QMPRequest, 1);
req_obj->mon = mon;
- req_obj->id = id;
req_obj->req = req;
req_obj->err = err;
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 90ba5e3074..e714cfb8ff 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -59,6 +59,8 @@ static QDict *qmp_dispatch_check_obj(const QObject *request,
bool allow_oob,
"QMP input member 'arguments' must be an object");
return NULL;
}
+ } else if (!strcmp(arg_name, "id")) {
+ continue;
} else {
error_setg(errp, "QMP input member '%s' is unexpected",
arg_name);
@@ -166,11 +168,11 @@ QDict *qmp_dispatch(QmpCommandList *cmds, QObject
*request,
bool allow_oob)
{
Error *err = NULL;
- QObject *ret;
+ QDict *dict = qobject_to(QDict, request);
+ QObject *id = dict ? qdict_get(dict, "id") : NULL;
+ QObject *ret = do_qmp_dispatch(cmds, request, allow_oob, &err);
QDict *rsp;
- ret = do_qmp_dispatch(cmds, request, allow_oob, &err);
-
if (err) {
rsp = qmp_error_response(err);
} else if (ret) {
@@ -181,5 +183,9 @@ QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request,
rsp = NULL;
}
+ if (rsp && id) {
+ qdict_put_obj(rsp, "id", qobject_ref(id));
+ }
+
return rsp;
}
diff --git a/tests/test-qga.c b/tests/test-qga.c
index d638b1571a..4ee8b405f4 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -227,18 +227,15 @@ static void test_qga_ping(gconstpointer fix)
qobject_unref(ret);
}
-static void test_qga_invalid_id(gconstpointer fix)
+static void test_qga_id(gconstpointer fix)
{
const TestFixture *fixture = fix;
- QDict *ret, *error;
- const char *class;
+ QDict *ret;
ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping', 'id': 1}");
g_assert_nonnull(ret);
-
- error = qdict_get_qdict(ret, "error");
- class = qdict_get_try_str(error, "class");
- g_assert_cmpstr(class, ==, "GenericError");
+ qmp_assert_no_error(ret);
+ g_assert_cmpint(qdict_get_int(ret, "id"), ==, 1);
qobject_unref(ret);
}
@@ -1014,7 +1011,7 @@ int main(int argc, char **argv)
g_test_add_data_func("/qga/file-ops", &fix, test_qga_file_ops);
g_test_add_data_func("/qga/file-write-read", &fix,
test_qga_file_write_read);
g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
- g_test_add_data_func("/qga/invalid-id", &fix, test_qga_invalid_id);
+ g_test_add_data_func("/qga/id", &fix, test_qga_id);
g_test_add_data_func("/qga/invalid-oob", &fix, test_qga_invalid_oob);
g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
g_test_add_data_func("/qga/invalid-args", &fix, test_qga_invalid_args);
--
2.18.0.129.ge3331758f1
- [Qemu-devel] [PATCH v2 06/18] qga: process_event() simplification and leak fix, (continued)
- [Qemu-devel] [PATCH v2 06/18] qga: process_event() simplification and leak fix, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 07/18] qmp: drop json_parser_parse() wrapper, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 13/18] json-parser: set an error if parsing returned NULL, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 15/18] tests: add a few qemu-qmp tests, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 14/18] json-lexer: make it safe to call multiple times, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 12/18] qjson: return parsing error if unterminated input, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 18/18] RFC: qmp: common 'id' handling & make QGA conform to QMP spec,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v2 16/18] tests: add a qmp success-response test, Marc-André Lureau, 2018/07/19
- [Qemu-devel] [PATCH v2 17/18] qga: process_event() simplification, Marc-André Lureau, 2018/07/19