[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v6 06/25] monitor: use qmp session to parse json feed
From: |
Marc-André Lureau |
Subject: |
[PATCH v6 06/25] monitor: use qmp session to parse json feed |
Date: |
Fri, 8 Nov 2019 19:01:04 +0400 |
Use the QmpSession json parser introduced in previous patch to
generalize the handling in both qemu & qemu-ga. Unfortunately, since
the introduction of OOB, it's not as common as it was before that. We
may want to move some of OOB logic in common qmp-dispatch.c/QmpSession
though.
The QEMU monitor has peculiar handling of the stream of commands, for
OOB command processing, which can be solved by overriding the json
emit callback.
Signed-off-by: Marc-André Lureau <address@hidden>
---
include/qapi/qmp/dispatch.h | 1 +
include/qapi/qmp/json-parser.h | 7 ++++---
monitor/monitor-internal.h | 1 -
monitor/qmp.c | 13 +++++--------
qapi/qmp-dispatch.c | 4 +++-
qga/main.c | 2 +-
qobject/json-streamer.c | 3 +--
tests/test-qmp-cmds.c | 11 ++++++-----
8 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index c84edff7d2..b3ca6c9ff2 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -53,6 +53,7 @@ const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
const char *name);
void qmp_session_init(QmpSession *session,
const QmpCommandList *cmds,
+ JSONMessageEmit *emit,
QmpDispatchReturn *return_cb);
static inline void
qmp_session_feed(QmpSession *session, const char *buf, size_t count)
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
index 7345a9bd5c..6f168e8007 100644
--- a/include/qapi/qmp/json-parser.h
+++ b/include/qapi/qmp/json-parser.h
@@ -14,6 +14,8 @@
#ifndef QAPI_QMP_JSON_PARSER_H
#define QAPI_QMP_JSON_PARSER_H
+typedef void (JSONMessageEmit)(void *opaque, QObject *json, Error *err);
+
typedef struct JSONLexer {
int start_state, state;
GString *token;
@@ -21,7 +23,7 @@ typedef struct JSONLexer {
} JSONLexer;
typedef struct JSONMessageParser {
- void (*emit)(void *opaque, QObject *json, Error *err);
+ JSONMessageEmit *emit;
void *opaque;
va_list *ap;
JSONLexer lexer;
@@ -32,8 +34,7 @@ typedef struct JSONMessageParser {
} JSONMessageParser;
void json_message_parser_init(JSONMessageParser *parser,
- void (*emit)(void *opaque, QObject *json,
- Error *err),
+ JSONMessageEmit *emit,
void *opaque, va_list *ap);
void json_message_parser_feed(JSONMessageParser *parser,
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index b15266e77b..b8994f896a 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -124,7 +124,6 @@ struct MonitorHMP {
typedef struct {
Monitor common;
- JSONMessageParser parser;
bool pretty;
/*
* When a client connects, we're in capabilities negotiation mode.
diff --git a/monitor/qmp.c b/monitor/qmp.c
index b215cb70f3..cd29494e28 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -217,7 +217,7 @@ void monitor_qmp_bh_dispatcher(void *data)
static void handle_qmp_command(void *opaque, QObject *req, Error *err)
{
- MonitorQMP *mon = opaque;
+ MonitorQMP *mon = container_of(opaque, MonitorQMP, session);
QObject *id = NULL;
QDict *qdict;
QMPRequest *req_obj;
@@ -279,7 +279,7 @@ static void monitor_qmp_read(void *opaque, const uint8_t
*buf, int size)
{
MonitorQMP *mon = opaque;
- json_message_parser_feed(&mon->parser, (const char *) buf, size);
+ qmp_session_feed(&mon->session, (const char *) buf, size);
}
static QDict *qmp_greeting(MonitorQMP *mon)
@@ -309,7 +309,9 @@ static void monitor_qmp_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_OPENED:
qmp_session_init(&mon->session,
- &qmp_cap_negotiation_commands, dispatch_return_cb);
+ &qmp_cap_negotiation_commands,
+ handle_qmp_command,
+ dispatch_return_cb);
monitor_qmp_caps_reset(mon);
data = qmp_greeting(mon);
qmp_send_response(mon, data);
@@ -325,9 +327,6 @@ static void monitor_qmp_event(void *opaque, int event)
*/
monitor_qmp_cleanup_queues(mon);
qmp_session_destroy(&mon->session);
- json_message_parser_destroy(&mon->parser);
- json_message_parser_init(&mon->parser, handle_qmp_command,
- mon, NULL);
mon_refcount--;
monitor_fdsets_cleanup();
break;
@@ -337,7 +336,6 @@ static void monitor_qmp_event(void *opaque, int event)
void monitor_data_destroy_qmp(MonitorQMP *mon)
{
qmp_session_destroy(&mon->session);
- json_message_parser_destroy(&mon->parser);
qemu_mutex_destroy(&mon->qmp_queue_lock);
monitor_qmp_cleanup_req_queue_locked(mon);
g_queue_free(mon->qmp_requests);
@@ -373,7 +371,6 @@ void monitor_init_qmp(Chardev *chr, bool pretty)
qemu_chr_fe_init(&mon->common.chr, chr, &error_abort);
qemu_chr_fe_set_echo(&mon->common.chr, true);
- json_message_parser_init(&mon->parser, handle_qmp_command, mon, NULL);
if (mon->common.use_io_thread) {
/*
* Make sure the old iowatch is gone. It's possible when
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index f8c491924d..b004d7506f 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -183,12 +183,14 @@ static void qmp_json_emit(void *opaque, QObject *obj,
Error *err)
void qmp_session_init(QmpSession *session,
const QmpCommandList *cmds,
+ JSONMessageEmit *emit,
QmpDispatchReturn *return_cb)
{
assert(return_cb);
assert(!session->return_cb);
- json_message_parser_init(&session->parser, qmp_json_emit, session, NULL);
+ json_message_parser_init(&session->parser, emit ?: qmp_json_emit,
+ session, NULL);
session->cmds = cmds;
session->return_cb = return_cb;
}
diff --git a/qga/main.c b/qga/main.c
index 057368eb16..b005550c70 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1319,7 +1319,7 @@ static GAState *initialize_agent(GAConfig *config, int
socket_activation)
s->command_state = ga_command_state_new();
ga_command_state_init(s, s->command_state);
ga_command_state_init_all(s->command_state);
- qmp_session_init(&s->session, &ga_commands, dispatch_return_cb);
+ qmp_session_init(&s->session, &ga_commands, NULL, dispatch_return_cb);
#ifndef _WIN32
if (!register_signal_handlers()) {
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
index 47dd7ea576..2a440f2a9e 100644
--- a/qobject/json-streamer.c
+++ b/qobject/json-streamer.c
@@ -100,8 +100,7 @@ out_emit:
}
void json_message_parser_init(JSONMessageParser *parser,
- void (*emit)(void *opaque, QObject *json,
- Error *err),
+ JSONMessageEmit *emit,
void *opaque, va_list *ap)
{
parser->emit = emit;
diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c
index cca15e79ba..d9623d10b6 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -155,7 +155,7 @@ static void test_dispatch_cmd(void)
QmpSession session = { 0, };
QDict *req = qdict_new();
- qmp_session_init(&session, &qmp_commands, dispatch_cmd_return);
+ qmp_session_init(&session, &qmp_commands, NULL, dispatch_cmd_return);
qdict_put_str(req, "execute", "user_def_cmd");
qmp_dispatch(&session, QOBJECT(req), false);
@@ -169,7 +169,7 @@ static void test_dispatch_cmd_oob(void)
QmpSession session = { 0, };
QDict *req = qdict_new();
- qmp_session_init(&session, &qmp_commands, dispatch_cmd_return);
+ qmp_session_init(&session, &qmp_commands, NULL, dispatch_cmd_return);
qdict_put_str(req, "exec-oob", "test-flags-command");
qmp_dispatch(&session, QOBJECT(req), true);
@@ -191,7 +191,8 @@ static void test_dispatch_cmd_failure(void)
QDict *req = qdict_new();
QDict *args = qdict_new();
- qmp_session_init(&session, &qmp_commands, dispatch_cmd_failure_return);
+ qmp_session_init(&session, &qmp_commands, NULL,
+ dispatch_cmd_failure_return);
qdict_put_str(req, "execute", "user_def_cmd2");
qmp_dispatch(&session, QOBJECT(req), false);
@@ -217,7 +218,7 @@ static void test_dispatch_cmd_success_response(void)
QmpSession session = { 0, };
QDict *req = qdict_new();
- qmp_session_init(&session, &qmp_commands, (QmpDispatchReturn *)abort);
+ qmp_session_init(&session, &qmp_commands, NULL, (QmpDispatchReturn
*)abort);
qdict_put_str(req, "execute", "cmd-success-response");
qmp_dispatch(&session, QOBJECT(req), false);
@@ -238,7 +239,7 @@ static QObject *test_qmp_dispatch(QDict *req)
QmpSession session = { 0, };
QObject *ret;
- qmp_session_init(&session, &qmp_commands, dispatch_return);
+ qmp_session_init(&session, &qmp_commands, NULL, dispatch_return);
qmp_dispatch(&session, QOBJECT(req), false);
ret = dispatch_ret;
dispatch_ret = NULL;
--
2.24.0
- [PATCH v6 00/25] monitor: add asynchronous command type, Marc-André Lureau, 2019/11/08
- [PATCH v6 01/25] qmp: constify QmpCommand and list, Marc-André Lureau, 2019/11/08
- [PATCH v6 02/25] json-lexer: make it safe to call destroy multiple times, Marc-André Lureau, 2019/11/08
- [PATCH v6 03/25] qmp: add QmpSession, Marc-André Lureau, 2019/11/08
- [PATCH v6 04/25] QmpSession: add a return callback, Marc-André Lureau, 2019/11/08
- [PATCH v6 05/25] QmpSession: add json parser and use it in qga, Marc-André Lureau, 2019/11/08
- [PATCH v6 06/25] monitor: use qmp session to parse json feed,
Marc-André Lureau <=
- [PATCH v6 07/25] qga: simplify dispatch_return_cb, Marc-André Lureau, 2019/11/08
- [PATCH v6 08/25] QmpSession: introduce QmpReturn, Marc-André Lureau, 2019/11/08
- [PATCH v6 09/25] qmp: simplify qmp_return_error(), Marc-André Lureau, 2019/11/08
- [PATCH v6 10/25] QmpSession: keep a queue of pending commands, Marc-André Lureau, 2019/11/08
- [PATCH v6 11/25] QmpSession: return orderly, Marc-André Lureau, 2019/11/08
- [PATCH v6 12/25] qmp: introduce asynchronous command type, Marc-André Lureau, 2019/11/08
- [PATCH v6 14/25] qmp: add qmp_return_is_cancelled(), Marc-André Lureau, 2019/11/08
- [PATCH v6 13/25] scripts: learn 'async' qapi commands, Marc-André Lureau, 2019/11/08
- [PATCH v6 15/25] console: add graphic_hw_update_done(), Marc-André Lureau, 2019/11/08
- [PATCH v6 16/25] ppm-save: pass opened fd, Marc-André Lureau, 2019/11/08