[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 20/38] QmpSession: add json parser and use it in
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v3 20/38] QmpSession: add json parser and use it in qga |
Date: |
Mon, 26 Mar 2018 17:08:58 +0200 |
Move JSON parser to QmpSession, and implement a simple handler to check
the parsed tokens and call qmp_dispatch(). This is enough for a simple
QMP client, like QGA.
The QEMU monitor has more complicated handling of dispatching which
will be adressed in following patch to benefit more common code.
Signed-off-by: Marc-André Lureau <address@hidden>
---
include/qapi/qmp/dispatch.h | 9 ++++++++
monitor.c | 7 ++-----
qapi/qmp-dispatch.c | 32 +++++++++++++++++++++++++++++
qga/main.c | 41 +------------------------------------
4 files changed, 44 insertions(+), 45 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 7bf0b6a437..cd425b8574 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -15,6 +15,7 @@
#define QAPI_QMP_DISPATCH_H
#include "qemu/queue.h"
+#include "qapi/qmp/json-streamer.h"
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
@@ -40,6 +41,7 @@ typedef struct QmpSession QmpSession;
typedef void (QmpDispatchReturn) (QmpSession *session, QDict *rsp);
struct QmpSession {
+ JSONMessageParser parser;
QmpDispatchReturn *return_cb;
QmpCommandList *cmds;
};
@@ -48,9 +50,16 @@ void qmp_register_command(QmpCommandList *cmds, const char
*name,
QmpCommandFunc *fn, QmpCommandOptions options);
void qmp_unregister_command(QmpCommandList *cmds, const char *name);
QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name);
+
void qmp_session_init(QmpSession *session,
QmpCommandList *cmds, QmpDispatchReturn *return_cb);
+static inline void
+qmp_session_feed(QmpSession *session, const char *buf, size_t count)
+{
+ json_message_parser_feed(&session->parser, buf, count);
+}
+
void qmp_session_destroy(QmpSession *session);
void qmp_dispatch(QmpSession *session, QDict *request);
void qmp_disable_command(QmpCommandList *cmds, const char *name);
diff --git a/monitor.c b/monitor.c
index 93ecb03d04..66046d4854 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3934,11 +3934,8 @@ static void dispatch_return_cb(QmpSession *session,
QDict *rsp)
*/
static void monitor_qmp_dispatch_one(QMPRequest *req_obj)
{
- Monitor *mon, *old_mon;
- QDict *req;
-
- req = req_obj->req;
- mon = req_obj->mon;
+ Monitor *old_mon, *mon = req_obj->mon;
+ QDict *req = req_obj->req;
g_free(req_obj);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 5274aa59cc..5352b25e90 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -146,12 +146,43 @@ bool qmp_is_oob(const QDict *dict)
return qbool_get_bool(bool_obj);
}
+static void qmp_json_parser_emit(JSONMessageParser *parser, GQueue *tokens)
+{
+ QmpSession *session = container_of(parser, QmpSession, parser);
+ QObject *obj;
+ QDict *req;
+ Error *err = NULL;
+
+ obj = json_parser_parse_err(tokens, NULL, &err);
+ if (err) {
+ goto end;
+ }
+
+ req = qmp_dispatch_check_obj(obj, &err);
+ if (err) {
+ goto end;
+ }
+
+ qmp_dispatch(session, req);
+
+end:
+ if (err) {
+ QDict *rsp = qdict_new();
+ qdict_put_obj(rsp, "error", qmp_build_error_object(err));
+ error_free(err);
+ session->return_cb(session, rsp);
+ QDECREF(rsp);
+ }
+ qobject_decref(obj);
+}
+
void qmp_session_init(QmpSession *session,
QmpCommandList *cmds, QmpDispatchReturn *return_cb)
{
assert(return_cb);
assert(!session->return_cb);
+ json_message_parser_init(&session->parser, qmp_json_parser_emit);
session->cmds = cmds;
session->return_cb = return_cb;
}
@@ -164,6 +195,7 @@ void qmp_session_destroy(QmpSession *session)
session->cmds = NULL;
session->return_cb = NULL;
+ json_message_parser_destroy(&session->parser);
}
void qmp_dispatch(QmpSession *session, QDict *req)
diff --git a/qga/main.c b/qga/main.c
index 46349395ba..ce7efff3b4 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -72,7 +72,6 @@ typedef struct GAPersistentState {
struct GAState {
QmpSession session;
- JSONMessageParser parser;
GMainLoop *main_loop;
GAChannel *channel;
bool virtio; /* fastpath to check for virtio to deal with poll() quirks */
@@ -589,42 +588,6 @@ static void dispatch_return_cb(QmpSession *session, QDict
*rsp)
}
}
-/* handle requests/control events coming in over the channel */
-static void process_event(JSONMessageParser *parser, GQueue *tokens)
-{
- GAState *s = container_of(parser, GAState, parser);
- QObject *obj;
- QDict *req;
- Error *err = NULL;
-
- g_assert(s && parser);
-
- g_debug("process_event: called");
-
- obj = json_parser_parse_err(tokens, NULL, &err);
- if (err) {
- goto end;
- }
-
- req = qmp_dispatch_check_obj(obj, &err);
- if (err) {
- goto end;
- }
-
- g_debug("processing command");
- qmp_dispatch(&s->session, req);
-
-end:
- if (err) {
- QDict *rsp = qdict_new();
- qdict_put_obj(rsp, "error", qmp_build_error_object(err));
- error_free(err);
- dispatch_return_cb(&s->session, rsp);
- QDECREF(rsp);
- }
- qobject_decref(obj);
-}
-
/* false return signals GAChannel to close the current client connection */
static gboolean channel_event_cb(GIOCondition condition, gpointer data)
{
@@ -639,7 +602,7 @@ static gboolean channel_event_cb(GIOCondition condition,
gpointer data)
case G_IO_STATUS_NORMAL:
buf[count] = 0;
g_debug("read data, count: %d, data: %s", (int)count, buf);
- json_message_parser_feed(&s->parser, (char *)buf, (int)count);
+ qmp_session_feed(&s->session, buf, count);
break;
case G_IO_STATUS_EOF:
g_debug("received EOF");
@@ -1307,7 +1270,6 @@ static int run_agent(GAState *s, 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);
- json_message_parser_init(&s->parser, process_event);
qmp_session_init(&s->session, &ga_commands, dispatch_return_cb);
#ifndef _WIN32
if (!register_signal_handlers()) {
@@ -1431,7 +1393,6 @@ end:
qmp_session_destroy(&s->session);
ga_command_state_cleanup_all(s->command_state);
ga_command_state_free(s->command_state);
- json_message_parser_destroy(&s->parser);
}
if (s->channel) {
ga_channel_free(s->channel);
--
2.17.0.rc1.1.g4c4f2b46a3
- [Qemu-devel] [PATCH v3 07/38] json-parser: always set an error if return NULL, (continued)
- [Qemu-devel] [PATCH v3 07/38] json-parser: always set an error if return NULL, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 10/38] tests: add a few qemu-qmp tests, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 13/38] qga: process_event() simplification, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 14/38] monitor: simplify monitor_qmp_respond(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 11/38] tests: change /0.15/* tests to /qmp/*, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 12/38] tests: add a qmp success-response test, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 15/38] qmp: pass and return a QDict to qmp_dispatch(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 17/38] qmp: constify qmp_is_oob(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 16/38] qmp: move 'id' copy to qmp_dispatch(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 18/38] qmp: add QmpSession, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 20/38] QmpSession: add json parser and use it in qga,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v3 19/38] QmpSession: add a return_cb, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 21/38] QmpSession: add a dispatch callback, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 22/38] monitor: use QmpSession parsing and common dispatch code, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 24/38] qmp: remove qmp_build_error_object(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 23/38] QmpSession: introduce QmpReturn, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 26/38] qmp: fold do_qmp_dispatch() in qmp_dispatch(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 27/38] QmpSession: keep a queue of pending commands, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 25/38] qmp: remove need for qobject_from_jsonf(), Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 28/38] QmpSession: return orderly, Marc-André Lureau, 2018/03/26
- [Qemu-devel] [PATCH v3 30/38] scripts: learn 'async' qapi commands, Marc-André Lureau, 2018/03/26