monitor: Split monitor_init in HMP and QMP function
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 <kwolf@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20190613153405.24769-3-kwolf@redhat.com> [Zero initialization of Monitor moved from monitor_data_init() to callers] Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
be7633c33e
commit
b6c7c2e4a3
69
monitor.c
69
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,31 +4606,21 @@ 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;
|
||||
if (use_readline) {
|
||||
mon->rs = readline_init(monitor_readline_printf,
|
||||
monitor_readline_flush,
|
||||
mon,
|
||||
monitor_find_completion);
|
||||
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);
|
||||
|
||||
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
|
||||
|
@ -4644,20 +4635,44 @@ void monitor_init(Chardev *chr, int flags)
|
|||
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);
|
||||
monitor_list_append(mon);
|
||||
}
|
||||
} else {
|
||||
qemu_chr_fe_set_handlers(&mon->chr, monitor_can_read, monitor_read,
|
||||
monitor_event, NULL, mon, NULL, true);
|
||||
}
|
||||
|
||||
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,
|
||||
mon,
|
||||
monitor_find_completion);
|
||||
monitor_read_command(mon, 0);
|
||||
}
|
||||
|
||||
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 {
|
||||
monitor_init_hmp(chr, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void monitor_cleanup(void)
|
||||
{
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue