diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index b7bdd2bb2a..db1112552c 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -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); diff --git a/monitor/monitor.c b/monitor/monitor.c index c1a6c4460f..f8a6ef795b 100644 --- a/monitor/monitor.c +++ b/monitor/monitor.c @@ -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; } diff --git a/qapi/control.json b/qapi/control.json index 759c20e76f..3ee086aec7 100644 --- a/qapi/control.json +++ b/qapi/control.json @@ -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' + } }