monitor: Create QAPIfied monitor_init()

This adds a new QAPI-based monitor_init() function. The existing
monitor_init_opts() is rewritten to simply put its QemuOpts parameter
into a visitor and pass the resulting QAPI object to monitor_init().

This will cause some change in those error messages for the monitor
options in the system emulator that are now generated by the visitor
rather than explicitly checked in monitor_init_opts().

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20200224143008.13362-17-kwolf@redhat.com>
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2020-02-24 15:30:04 +01:00
parent 9a9f909951
commit f2098725aa
3 changed files with 81 additions and 36 deletions

View File

@ -7,6 +7,7 @@
extern __thread Monitor *cur_mon;
typedef struct MonitorHMP MonitorHMP;
typedef struct MonitorOptions MonitorOptions;
#define QMP_REQ_QUEUE_LEN_MAX 8
@ -18,6 +19,7 @@ void monitor_init_globals(void);
void monitor_init_globals_core(void);
void monitor_init_qmp(Chardev *chr, bool pretty);
void monitor_init_hmp(Chardev *chr, bool use_readline);
int monitor_init(MonitorOptions *opts, Error **errp);
int monitor_init_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);

View File

@ -25,7 +25,9 @@
#include "qemu/osdep.h"
#include "monitor-internal.h"
#include "qapi/error.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-emit-events.h"
#include "qapi/qapi-visit-control.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "qemu/error-report.h"
@ -609,50 +611,55 @@ void monitor_init_globals_core(void)
NULL);
}
int monitor_init_opts(QemuOpts *opts, Error **errp)
int monitor_init(MonitorOptions *opts, Error **errp)
{
Chardev *chr;
bool qmp;
bool pretty = false;
const char *chardev;
const char *mode;
mode = qemu_opt_get(opts, "mode");
if (mode == NULL) {
mode = "readline";
}
if (strcmp(mode, "readline") == 0) {
qmp = false;
} else if (strcmp(mode, "control") == 0) {
qmp = true;
} else {
error_setg(errp, "unknown monitor mode \"%s\"", mode);
return -1;
}
if (!qmp && qemu_opt_get(opts, "pretty")) {
warn_report("'pretty' is deprecated for HMP monitors, it has no effect "
"and will be removed in future versions");
}
if (qemu_opt_get_bool(opts, "pretty", 0)) {
pretty = true;
}
chardev = qemu_opt_get(opts, "chardev");
if (!chardev) {
error_report("chardev is required");
exit(1);
}
chr = qemu_chr_find(chardev);
chr = qemu_chr_find(opts->chardev);
if (chr == NULL) {
error_setg(errp, "chardev \"%s\" not found", chardev);
error_setg(errp, "chardev \"%s\" not found", opts->chardev);
return -1;
}
if (qmp) {
monitor_init_qmp(chr, pretty);
} else {
switch (opts->mode) {
case MONITOR_MODE_CONTROL:
monitor_init_qmp(chr, opts->pretty);
break;
case MONITOR_MODE_READLINE:
if (opts->pretty) {
warn_report("'pretty' is deprecated for HMP monitors, it has no "
"effect and will be removed in future versions");
}
monitor_init_hmp(chr, true);
break;
default:
g_assert_not_reached();
}
return 0;
}
int monitor_init_opts(QemuOpts *opts, Error **errp)
{
Visitor *v;
MonitorOptions *options;
Error *local_err = NULL;
v = opts_visitor_new(opts);
visit_type_MonitorOptions(v, NULL, &options, &local_err);
visit_free(v);
if (local_err) {
goto out;
}
monitor_init(options, &local_err);
qapi_free_MonitorOptions(options);
out:
if (local_err) {
error_propagate(errp, local_err);
return -1;
}
return 0;
}

View File

@ -216,3 +216,39 @@
# <- { "return": {} }
##
{ 'command': 'quit' }
##
# @MonitorMode:
#
# An enumeration of monitor modes.
#
# @readline: HMP monitor (human-oriented command line interface)
#
# @control: QMP monitor (JSON-based machine interface)
#
# Since: 5.0
##
{ 'enum': 'MonitorMode', 'data': [ 'readline', 'control' ] }
##
# @MonitorOptions:
#
# Options to be used for adding a new monitor.
#
# @id: Name of the monitor
#
# @mode: Selects the monitor mode (default: readline)
#
# @pretty: Enables pretty printing (QMP only)
#
# @chardev: Name of a character device to expose the monitor on
#
# Since: 5.0
##
{ 'struct': 'MonitorOptions',
'data': {
'*id': 'str',
'*mode': 'MonitorMode',
'*pretty': 'bool',
'chardev': 'str'
} }