[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 06/20] monitor: use qmp session to parse json fee
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v4 06/20] monitor: use qmp session to parse json feed |
Date: |
Tue, 9 Apr 2019 18:09:55 +0200 |
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.c | 16 +++++-----------
qapi/qmp-dispatch.c | 4 +++-
qga/main.c | 2 +-
qobject/json-streamer.c | 3 +--
tests/test-qmp-cmds.c | 11 ++++++-----
7 files changed, 21 insertions(+), 23 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.c b/monitor.c
index c23ba76f78..71aad8d1ae 100644
--- a/monitor.c
+++ b/monitor.c
@@ -59,7 +59,6 @@
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qjson.h"
-#include "qapi/qmp/json-parser.h"
#include "qapi/qmp/qlist.h"
#include "qom/object_interfaces.h"
#include "trace-root.h"
@@ -167,7 +166,6 @@ struct MonFdset {
};
typedef struct {
- JSONMessageParser parser;
/*
* When a client connects, we're in capabilities negotiation mode.
* @commands is &qmp_cap_negotiation_commands then. When command
@@ -730,7 +728,6 @@ static void monitor_data_destroy(Monitor *mon)
qemu_chr_fe_deinit(&mon->chr, false);
if (monitor_is_qmp(mon)) {
qmp_session_destroy(&mon->qmp.session);
- json_message_parser_destroy(&mon->qmp.parser);
}
readline_free(mon->rs);
qobject_unref(mon->outbuf);
@@ -4216,7 +4213,7 @@ static void monitor_qmp_bh_dispatcher(void *data)
static void handle_qmp_command(void *opaque, QObject *req, Error *err)
{
- Monitor *mon = opaque;
+ Monitor *mon = container_of(opaque, Monitor, qmp);
QObject *id = NULL;
QDict *qdict;
QMPRequest *req_obj;
@@ -4278,7 +4275,7 @@ static void monitor_qmp_read(void *opaque, const uint8_t
*buf, int size)
{
Monitor *mon = opaque;
- json_message_parser_feed(&mon->qmp.parser, (const char *) buf, size);
+ qmp_session_feed(&mon->qmp.session, (const char *) buf, size);
}
static void monitor_read(void *opaque, const uint8_t *buf, int size)
@@ -4391,7 +4388,9 @@ static void monitor_qmp_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_OPENED:
qmp_session_init(&mon->qmp.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);
@@ -4407,9 +4406,6 @@ static void monitor_qmp_event(void *opaque, int event)
*/
monitor_qmp_cleanup_queues(mon);
qmp_session_destroy(&mon->qmp.session);
- json_message_parser_destroy(&mon->qmp.parser);
- json_message_parser_init(&mon->qmp.parser, handle_qmp_command,
- mon, NULL);
mon_refcount--;
monitor_fdsets_cleanup();
break;
@@ -4615,8 +4611,6 @@ void monitor_init(Chardev *chr, int flags)
if (monitor_is_qmp(mon)) {
qemu_chr_fe_set_echo(&mon->chr, true);
- json_message_parser_init(&mon->qmp.parser, handle_qmp_command,
- mon, NULL);
if (mon->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 803ec626cd..f2c376d005 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -182,12 +182,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 9cd27fc4b8..14e418f9a5 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 3f41cc45bb..b4d0b0440a 100644
--- a/tests/test-qmp-cmds.c
+++ b/tests/test-qmp-cmds.c
@@ -121,7 +121,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);
@@ -135,7 +135,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);
@@ -157,7 +157,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);
@@ -183,7 +184,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);
@@ -204,7 +205,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.21.0.196.g041f5ea1cf
- [Qemu-devel] [PATCH v4 00/20] monitor: add asynchronous command type, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 01/20] qmp: constify QmpCommand and list, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 02/20] json-lexer: make it safe to call destroy multiple times, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 03/20] qmp: add QmpSession, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 04/20] QmpSession: add a return callback, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 05/20] QmpSession: add json parser and use it in qga, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 06/20] monitor: use qmp session to parse json feed,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v4 07/20] qga: simplify dispatch_return_cb, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 08/20] QmpSession: introduce QmpReturn, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 09/20] qmp: simplify qmp_return_error(), Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 11/20] QmpSession: return orderly, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 12/20] qmp: introduce asynchronous command type, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 13/20] scripts: learn 'async' qapi commands, Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 14/20] qmp: add qmp_return_is_cancelled(), Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 15/20] monitor: add qmp_return_get_monitor(), Marc-André Lureau, 2019/04/09
- [Qemu-devel] [PATCH v4 16/20] console: add graphic_hw_update_done(), Marc-André Lureau, 2019/04/09