[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 03/16] monitor: Split monitor_init in HMP and QMP fun
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PULL 03/16] monitor: Split monitor_init in HMP and QMP function |
Date: |
Mon, 17 Jun 2019 20:48:50 +0200 |
From: Kevin Wolf <address@hidden>
Instead of mixing HMP and QMP monitors in the same function, separate
the monitor creation function for both.
While in theory, one could pass both MONITOR_USE_CONTROL and
MONITOR_USE_READLINE before this patch and both flags would do
something, readline support is tightly coupled with HMP: QMP never feeds
its input to readline, and the tab completion function treats the input
as an HMP command. Therefore, this configuration is useless.
After this patch, the QMP path asserts that MONITOR_USE_READLINE is not
set. The HMP path can be used with or without MONITOR_USE_READLINE, like
before.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Markus Armbruster <address@hidden>
Message-Id: <address@hidden>
[Zero initialization of Monitor moved from monitor_data_init() to
callers]
Signed-off-by: Markus Armbruster <address@hidden>
---
monitor.c | 95 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 55 insertions(+), 40 deletions(-)
diff --git a/monitor.c b/monitor.c
index 8e9851ae15..261342a0f6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -704,13 +704,12 @@ static void handle_hmp_command(Monitor *mon, const char
*cmdline);
static void monitor_iothread_init(void);
-static void monitor_data_init(Monitor *mon, bool skip_flush,
+static void monitor_data_init(Monitor *mon, int flags, bool skip_flush,
bool use_io_thread)
{
if (use_io_thread && !mon_iothread) {
monitor_iothread_init();
}
- memset(mon, 0, sizeof(Monitor));
qemu_mutex_init(&mon->mon_lock);
qemu_mutex_init(&mon->qmp.qmp_queue_lock);
mon->outbuf = qstring_new();
@@ -719,6 +718,7 @@ static void monitor_data_init(Monitor *mon, bool skip_flush,
mon->skip_flush = skip_flush;
mon->use_io_thread = use_io_thread;
mon->qmp.qmp_requests = g_queue_new();
+ mon->flags = flags;
}
static void monitor_data_destroy(Monitor *mon)
@@ -740,9 +740,10 @@ char *qmp_human_monitor_command(const char *command_line,
bool has_cpu_index,
int64_t cpu_index, Error **errp)
{
char *output = NULL;
- Monitor *old_mon, hmp;
+ Monitor *old_mon;
+ Monitor hmp = {};
- monitor_data_init(&hmp, true, false);
+ monitor_data_init(&hmp, 0, true, false);
old_mon = cur_mon;
cur_mon = &hmp;
@@ -4605,19 +4606,51 @@ static void monitor_qmp_setup_handlers_bh(void *opaque)
monitor_list_append(mon);
}
-void monitor_init(Chardev *chr, int flags)
+static void monitor_init_qmp(Chardev *chr, int flags)
{
- Monitor *mon = g_malloc(sizeof(*mon));
- bool use_readline = flags & MONITOR_USE_READLINE;
+ Monitor *mon = g_new0(Monitor, 1);
+
+ /* Only HMP supports readline */
+ assert(!(flags & MONITOR_USE_READLINE));
/* Note: we run QMP monitor in I/O thread when @chr supports that */
- monitor_data_init(mon, false,
- (flags & MONITOR_USE_CONTROL)
- && qemu_chr_has_feature(chr,
- QEMU_CHAR_FEATURE_GCONTEXT));
+ monitor_data_init(mon, flags, false,
+ qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_GCONTEXT));
qemu_chr_fe_init(&mon->chr, chr, &error_abort);
- mon->flags = flags;
+ 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
+ * e.g. the chardev is in client mode, with wait=on.
+ */
+ remove_fd_in_watch(chr);
+ /*
+ * We can't call qemu_chr_fe_set_handlers() directly here
+ * since chardev might be running in the monitor I/O
+ * thread. Schedule a bottom half.
+ */
+ aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
+ monitor_qmp_setup_handlers_bh, mon);
+ /* The bottom half will add @mon to @mon_list */
+ } else {
+ qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read,
+ monitor_qmp_read, monitor_qmp_event,
+ NULL, mon, NULL, true);
+ monitor_list_append(mon);
+ }
+}
+
+static void monitor_init_hmp(Chardev *chr, int flags)
+{
+ Monitor *mon = g_new0(Monitor, 1);
+ bool use_readline = flags & MONITOR_USE_READLINE;
+
+ monitor_data_init(mon, flags, false, false);
+ qemu_chr_fe_init(&mon->chr, chr, &error_abort);
+
if (use_readline) {
mon->rs = readline_init(monitor_readline_printf,
monitor_readline_flush,
@@ -4626,36 +4659,18 @@ void monitor_init(Chardev *chr, int flags)
monitor_read_command(mon, 0);
}
- 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
- * e.g. the chardev is in client mode, with wait=on.
- */
- remove_fd_in_watch(chr);
- /*
- * We can't call qemu_chr_fe_set_handlers() directly here
- * since chardev might be running in the monitor I/O
- * thread. Schedule a bottom half.
- */
- aio_bh_schedule_oneshot(iothread_get_aio_context(mon_iothread),
- monitor_qmp_setup_handlers_bh, mon);
- /* The bottom half will add @mon to @mon_list */
- return;
- } else {
- qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read,
- monitor_qmp_read, monitor_qmp_event,
- NULL, mon, NULL, true);
- }
+ qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_read,
+ monitor_event, NULL, mon, NULL, true);
+ monitor_list_append(mon);
+}
+
+void monitor_init(Chardev *chr, int flags)
+{
+ if (flags & MONITOR_USE_CONTROL) {
+ monitor_init_qmp(chr, flags);
} else {
- qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_read,
- monitor_event, NULL, mon, NULL, true);
+ monitor_init_hmp(chr, flags);
}
-
- monitor_list_append(mon);
}
void monitor_cleanup(void)
--
2.21.0
- [Qemu-devel] [PULL 00/16] Monitor patches for 2019-06-17, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 03/16] monitor: Split monitor_init in HMP and QMP function,
Markus Armbruster <=
- [Qemu-devel] [PULL 01/16] monitor: Fix return type of monitor_fdset_dup_fd_find, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 04/16] monitor: Make MonitorQMP a child class of Monitor, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 09/16] monitor: Move {hmp, qmp}.c to monitor/{hmp, qmp}-cmds.c, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 08/16] Move monitor.c to monitor/misc.c, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 14/16] monitor: Split Monitor.flags into separate bools, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 06/16] monitor: Remove Monitor.cmd_table indirection, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 02/16] monitor: Remove unused password prompting fields, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 11/16] monitor: Split out monitor/qmp.c, Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 15/16] monitor: Replace monitor_init() with monitor_init_{hmp, qmp}(), Markus Armbruster, 2019/06/17
- [Qemu-devel] [PULL 05/16] monitor: Create MonitorHMP with readline state, Markus Armbruster, 2019/06/17