aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-02-17 13:32:25 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-02-17 13:32:25 +0000
commit6c599282f8ab382fe59f03a6cae755b89561a7b3 (patch)
tree85492f9cb8329bb9fff18aeef2f0f8a4c948e2c8
parent652c5bbd7e7d3cb3d27a2e0590118dc79fb6f4d8 (diff)
parentec95fcc8bae624e87c7601d2d4baf7c519c3814e (diff)
Merge remote-tracking branch 'remotes/armbru/tags/pull-monitor-2020-02-15-v2' into staging
Monitor patches for 2020-02-15 # gpg: Signature made Mon 17 Feb 2020 13:26:20 GMT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * remotes/armbru/tags/pull-monitor-2020-02-15-v2: qemu-doc: Clarify extent of build platform support monitor: Move qmp_query_qmp_schema to qmp-cmds-control.c monitor: Collect "control" command handlers in qmp-cmds.control.c qapi: Split control.json off misc.json monitor: Move monitor option parsing to monitor/monitor.c Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--include/monitor/monitor.h3
-rw-r--r--include/sysemu/sysemu.h1
-rw-r--r--monitor/Makefile.objs3
-rw-r--r--monitor/hmp-cmds.c1
-rw-r--r--monitor/misc.c127
-rw-r--r--monitor/monitor-internal.h4
-rw-r--r--monitor/monitor.c48
-rw-r--r--monitor/qmp-cmds-control.c169
-rw-r--r--monitor/qmp-cmds.c15
-rw-r--r--monitor/qmp.c2
-rw-r--r--qapi/Makefile.objs6
-rw-r--r--qapi/control.json218
-rw-r--r--qapi/misc.json212
-rw-r--r--qapi/qapi-schema.json1
-rw-r--r--qemu-doc.texi9
-rw-r--r--tests/qtest/qmp-test.c2
-rw-r--r--ui/gtk.c1
-rw-r--r--vl.c45
18 files changed, 460 insertions, 407 deletions
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index a81eeff5f8..b7bdd2bb2a 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -10,12 +10,15 @@ typedef struct MonitorHMP MonitorHMP;
#define QMP_REQ_QUEUE_LEN_MAX 8
+extern QemuOptsList qemu_mon_opts;
+
bool monitor_cur_is_qmp(void);
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_opts(QemuOpts *opts, Error **errp);
void monitor_cleanup(void);
int monitor_suspend(Monitor *mon);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 7956e9054a..c0678c1ca3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -125,7 +125,6 @@ extern QemuOptsList qemu_netdev_opts;
extern QemuOptsList qemu_nic_opts;
extern QemuOptsList qemu_net_opts;
extern QemuOptsList qemu_global_opts;
-extern QemuOptsList qemu_mon_opts;
extern QemuOptsList qemu_semihosting_config_opts;
#endif
diff --git a/monitor/Makefile.objs b/monitor/Makefile.objs
index e91a8581cd..9244d90859 100644
--- a/monitor/Makefile.objs
+++ b/monitor/Makefile.objs
@@ -1,3 +1,4 @@
obj-y += misc.o
common-obj-y += monitor.o qmp.o hmp.o
-common-obj-y += qmp-cmds.o hmp-cmds.o
+common-obj-y += qmp-cmds.o qmp-cmds-control.o
+common-obj-y += hmp-cmds.o
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 558fe06b8f..b237613e0d 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -31,6 +31,7 @@
#include "qapi/qapi-builtin-visit.h"
#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-char.h"
+#include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-net.h"
diff --git a/monitor/misc.c b/monitor/misc.c
index 9c3484d0a7..6c41293102 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -67,15 +67,14 @@
#include "qemu/thread.h"
#include "block/qapi.h"
#include "qapi/qapi-commands-char.h"
+#include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-qom.h"
#include "qapi/qapi-commands-trace.h"
-#include "qapi/qapi-emit-events.h"
#include "qapi/qapi-init-commands.h"
#include "qapi/error.h"
#include "qapi/qmp-event.h"
-#include "qapi/qapi-introspect.h"
#include "sysemu/cpus.h"
#include "qemu/cutils.h"
#include "tcg/tcg.h"
@@ -232,73 +231,6 @@ static void hmp_info_help(Monitor *mon, const QDict *qdict)
help_cmd(mon, "info");
}
-static void query_commands_cb(QmpCommand *cmd, void *opaque)
-{
- CommandInfoList *info, **list = opaque;
-
- if (!cmd->enabled) {
- return;
- }
-
- info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(cmd->name);
- info->next = *list;
- *list = info;
-}
-
-CommandInfoList *qmp_query_commands(Error **errp)
-{
- CommandInfoList *list = NULL;
- MonitorQMP *mon;
-
- assert(monitor_is_qmp(cur_mon));
- mon = container_of(cur_mon, MonitorQMP, common);
-
- qmp_for_each_command(mon->commands, query_commands_cb, &list);
-
- return list;
-}
-
-EventInfoList *qmp_query_events(Error **errp)
-{
- /*
- * TODO This deprecated command is the only user of
- * QAPIEvent_str() and QAPIEvent_lookup[]. When the command goes,
- * they should go, too.
- */
- EventInfoList *info, *ev_list = NULL;
- QAPIEvent e;
-
- for (e = 0 ; e < QAPI_EVENT__MAX ; e++) {
- const char *event_name = QAPIEvent_str(e);
- assert(event_name != NULL);
- info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(event_name);
-
- info->next = ev_list;
- ev_list = info;
- }
-
- return ev_list;
-}
-
-/*
- * Minor hack: generated marshalling suppressed for this command
- * ('gen': false in the schema) so we can parse the JSON string
- * directly into QObject instead of first parsing it with
- * visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it
- * to QObject with generated output marshallers, every time. Instead,
- * we do it in test-qobject-input-visitor.c, just to make sure
- * qapi-gen.py's output actually conforms to the schema.
- */
-static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
- Error **errp)
-{
- *ret_data = qobject_from_qlit(&qmp_schema_qlit);
-}
-
static void monitor_init_qmp_commands(void)
{
/*
@@ -322,63 +254,6 @@ static void monitor_init_qmp_commands(void)
qmp_marshal_qmp_capabilities, QCO_ALLOW_PRECONFIG);
}
-/*
- * Accept QMP capabilities in @list for @mon.
- * On success, set mon->qmp.capab[], and return true.
- * On error, set @errp, and return false.
- */
-static bool qmp_caps_accept(MonitorQMP *mon, QMPCapabilityList *list,
- Error **errp)
-{
- GString *unavailable = NULL;
- bool capab[QMP_CAPABILITY__MAX];
-
- memset(capab, 0, sizeof(capab));
-
- for (; list; list = list->next) {
- if (!mon->capab_offered[list->value]) {
- if (!unavailable) {
- unavailable = g_string_new(QMPCapability_str(list->value));
- } else {
- g_string_append_printf(unavailable, ", %s",
- QMPCapability_str(list->value));
- }
- }
- capab[list->value] = true;
- }
-
- if (unavailable) {
- error_setg(errp, "Capability %s not available", unavailable->str);
- g_string_free(unavailable, true);
- return false;
- }
-
- memcpy(mon->capab, capab, sizeof(capab));
- return true;
-}
-
-void qmp_qmp_capabilities(bool has_enable, QMPCapabilityList *enable,
- Error **errp)
-{
- MonitorQMP *mon;
-
- assert(monitor_is_qmp(cur_mon));
- mon = container_of(cur_mon, MonitorQMP, common);
-
- if (mon->commands == &qmp_commands) {
- error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
- "Capabilities negotiation is already complete, command "
- "ignored");
- return;
- }
-
- if (!qmp_caps_accept(mon, enable, errp)) {
- return;
- }
-
- mon->commands = &qmp_commands;
-}
-
/* Set the current CPU defined by the user. Callers must hold BQL. */
int monitor_set_cpu(int cpu_index)
{
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h
index d78f5ca190..3e6baba88f 100644
--- a/monitor/monitor-internal.h
+++ b/monitor/monitor-internal.h
@@ -27,6 +27,7 @@
#include "chardev/char-fe.h"
#include "monitor/monitor.h"
+#include "qapi/qapi-types-control.h"
#include "qapi/qmp/dispatch.h"
#include "qapi/qmp/json-parser.h"
#include "qemu/readline.h"
@@ -179,4 +180,7 @@ void help_cmd(Monitor *mon, const char *name);
void handle_hmp_command(MonitorHMP *mon, const char *cmdline);
int hmp_compare_cmd(const char *name, const char *list);
+void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
+ Error **errp);
+
#endif
diff --git a/monitor/monitor.c b/monitor/monitor.c
index 12898b6448..c1a6c4460f 100644
--- a/monitor/monitor.c
+++ b/monitor/monitor.c
@@ -609,6 +609,54 @@ void monitor_init_globals_core(void)
NULL);
}
+int monitor_init_opts(QemuOpts *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);
+ if (chr == NULL) {
+ error_setg(errp, "chardev \"%s\" not found", chardev);
+ return -1;
+ }
+
+ if (qmp) {
+ monitor_init_qmp(chr, pretty);
+ } else {
+ monitor_init_hmp(chr, true);
+ }
+ return 0;
+}
+
QemuOptsList qemu_mon_opts = {
.name = "mon",
.implied_opt_name = "chardev",
diff --git a/monitor/qmp-cmds-control.c b/monitor/qmp-cmds-control.c
new file mode 100644
index 0000000000..5cd9bb817c
--- /dev/null
+++ b/monitor/qmp-cmds-control.c
@@ -0,0 +1,169 @@
+/*
+ * QMP commands related to the monitor (common to sysemu and tools)
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include "monitor-internal.h"
+#include "qemu-version.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-control.h"
+#include "qapi/qapi-emit-events.h"
+#include "qapi/qapi-introspect.h"
+
+/*
+ * Accept QMP capabilities in @list for @mon.
+ * On success, set mon->qmp.capab[], and return true.
+ * On error, set @errp, and return false.
+ */
+static bool qmp_caps_accept(MonitorQMP *mon, QMPCapabilityList *list,
+ Error **errp)
+{
+ GString *unavailable = NULL;
+ bool capab[QMP_CAPABILITY__MAX];
+
+ memset(capab, 0, sizeof(capab));
+
+ for (; list; list = list->next) {
+ if (!mon->capab_offered[list->value]) {
+ if (!unavailable) {
+ unavailable = g_string_new(QMPCapability_str(list->value));
+ } else {
+ g_string_append_printf(unavailable, ", %s",
+ QMPCapability_str(list->value));
+ }
+ }
+ capab[list->value] = true;
+ }
+
+ if (unavailable) {
+ error_setg(errp, "Capability %s not available", unavailable->str);
+ g_string_free(unavailable, true);
+ return false;
+ }
+
+ memcpy(mon->capab, capab, sizeof(capab));
+ return true;
+}
+
+void qmp_qmp_capabilities(bool has_enable, QMPCapabilityList *enable,
+ Error **errp)
+{
+ MonitorQMP *mon;
+
+ assert(monitor_is_qmp(cur_mon));
+ mon = container_of(cur_mon, MonitorQMP, common);
+
+ if (mon->commands == &qmp_commands) {
+ error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+ "Capabilities negotiation is already complete, command "
+ "ignored");
+ return;
+ }
+
+ if (!qmp_caps_accept(mon, enable, errp)) {
+ return;
+ }
+
+ mon->commands = &qmp_commands;
+}
+
+VersionInfo *qmp_query_version(Error **errp)
+{
+ VersionInfo *info = g_new0(VersionInfo, 1);
+
+ info->qemu = g_new0(VersionTriple, 1);
+ info->qemu->major = QEMU_VERSION_MAJOR;
+ info->qemu->minor = QEMU_VERSION_MINOR;
+ info->qemu->micro = QEMU_VERSION_MICRO;
+ info->package = g_strdup(QEMU_PKGVERSION);
+
+ return info;
+}
+
+static void query_commands_cb(QmpCommand *cmd, void *opaque)
+{
+ CommandInfoList *info, **list = opaque;
+
+ if (!cmd->enabled) {
+ return;
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = g_strdup(cmd->name);
+ info->next = *list;
+ *list = info;
+}
+
+CommandInfoList *qmp_query_commands(Error **errp)
+{
+ CommandInfoList *list = NULL;
+ MonitorQMP *mon;
+
+ assert(monitor_is_qmp(cur_mon));
+ mon = container_of(cur_mon, MonitorQMP, common);
+
+ qmp_for_each_command(mon->commands, query_commands_cb, &list);
+
+ return list;
+}
+
+EventInfoList *qmp_query_events(Error **errp)
+{
+ /*
+ * TODO This deprecated command is the only user of
+ * QAPIEvent_str() and QAPIEvent_lookup[]. When the command goes,
+ * they should go, too.
+ */
+ EventInfoList *info, *ev_list = NULL;
+ QAPIEvent e;
+
+ for (e = 0 ; e < QAPI_EVENT__MAX ; e++) {
+ const char *event_name = QAPIEvent_str(e);
+ assert(event_name != NULL);
+ info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = g_strdup(event_name);
+
+ info->next = ev_list;
+ ev_list = info;
+ }
+
+ return ev_list;
+}
+
+/*
+ * Minor hack: generated marshalling suppressed for this command
+ * ('gen': false in the schema) so we can parse the JSON string
+ * directly into QObject instead of first parsing it with
+ * visit_type_SchemaInfoList() into a SchemaInfoList, then marshal it
+ * to QObject with generated output marshallers, every time. Instead,
+ * we do it in test-qobject-input-visitor.c, just to make sure
+ * qapi-gen.py's output actually conforms to the schema.
+ */
+void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
+ Error **errp)
+{
+ *ret_data = qobject_from_qlit(&qmp_schema_qlit);
+}
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index c6faa3eaf0..da7083087e 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -15,7 +15,6 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/option.h"
#include "monitor/monitor.h"
@@ -32,6 +31,7 @@
#include "sysemu/block-backend.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-ui.h"
@@ -51,19 +51,6 @@ NameInfo *qmp_query_name(Error **errp)
return info;
}
-VersionInfo *qmp_query_version(Error **errp)
-{
- VersionInfo *info = g_new0(VersionInfo, 1);
-
- info->qemu = g_new0(VersionTriple, 1);
- info->qemu->major = QEMU_VERSION_MAJOR;
- info->qemu->minor = QEMU_VERSION_MINOR;
- info->qemu->micro = QEMU_VERSION_MICRO;
- info->package = g_strdup(QEMU_PKGVERSION);
-
- return info;
-}
-
KvmInfo *qmp_query_kvm(Error **errp)
{
KvmInfo *info = g_malloc0(sizeof(*info));
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 54c06ba824..8379c8f96e 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -27,7 +27,7 @@
#include "chardev/char-io.h"
#include "monitor-internal.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-commands-control.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qlist.h"
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index a8f1f4c35e..20fcc37c2c 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -5,9 +5,9 @@ util-obj-y += opts-visitor.o qapi-clone-visitor.o
util-obj-y += qmp-event.o
util-obj-y += qapi-util.o
-QAPI_COMMON_MODULES = audio authz block-core block char common crypto
-QAPI_COMMON_MODULES += dump error introspect job machine migration misc net
-QAPI_COMMON_MODULES += qdev qom rdma rocker run-state sockets tpm
+QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
+QAPI_COMMON_MODULES += dump error introspect job machine migration misc
+QAPI_COMMON_MODULES += net qdev qom rdma rocker run-state sockets tpm
QAPI_COMMON_MODULES += trace transaction ui
QAPI_TARGET_MODULES = machine-target misc-target
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
diff --git a/qapi/control.json b/qapi/control.json
new file mode 100644
index 0000000000..759c20e76f
--- /dev/null
+++ b/qapi/control.json
@@ -0,0 +1,218 @@
+# -*- Mode: Python -*-
+#
+
+##
+# = QMP monitor control
+##
+
+##
+# @qmp_capabilities:
+#
+# Enable QMP capabilities.
+#
+# Arguments:
+#
+# @enable: An optional list of QMPCapability values to enable. The
+# client must not enable any capability that is not
+# mentioned in the QMP greeting message. If the field is not
+# provided, it means no QMP capabilities will be enabled.
+# (since 2.12)
+#
+# Example:
+#
+# -> { "execute": "qmp_capabilities",
+# "arguments": { "enable": [ "oob" ] } }
+# <- { "return": {} }
+#
+# Notes: This command is valid exactly when first connecting: it must be
+# issued before any other command will be accepted, and will fail once the
+# monitor is accepting other commands. (see qemu docs/interop/qmp-spec.txt)
+#
+# The QMP client needs to explicitly enable QMP capabilities, otherwise
+# all the QMP capabilities will be turned off by default.
+#
+# Since: 0.13
+#
+##
+{ 'command': 'qmp_capabilities',
+ 'data': { '*enable': [ 'QMPCapability' ] },
+ 'allow-preconfig': true }
+
+##
+# @QMPCapability:
+#
+# Enumeration of capabilities to be advertised during initial client
+# connection, used for agreeing on particular QMP extension behaviors.
+#
+# @oob: QMP ability to support out-of-band requests.
+# (Please refer to qmp-spec.txt for more information on OOB)
+#
+# Since: 2.12
+#
+##
+{ 'enum': 'QMPCapability',
+ 'data': [ 'oob' ] }
+
+##
+# @VersionTriple:
+#
+# A three-part version number.
+#
+# @major: The major version number.
+#
+# @minor: The minor version number.
+#
+# @micro: The micro version number.
+#
+# Since: 2.4
+##
+{ 'struct': 'VersionTriple',
+ 'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} }
+
+
+##
+# @VersionInfo:
+#
+# A description of QEMU's version.
+#
+# @qemu: The version of QEMU. By current convention, a micro
+# version of 50 signifies a development branch. A micro version
+# greater than or equal to 90 signifies a release candidate for
+# the next minor version. A micro version of less than 50
+# signifies a stable release.
+#
+# @package: QEMU will always set this field to an empty string. Downstream
+# versions of QEMU should set this to a non-empty string. The
+# exact format depends on the downstream however it highly
+# recommended that a unique name is used.
+#
+# Since: 0.14.0
+##
+{ 'struct': 'VersionInfo',
+ 'data': {'qemu': 'VersionTriple', 'package': 'str'} }
+
+##
+# @query-version:
+#
+# Returns the current version of QEMU.
+#
+# Returns: A @VersionInfo object describing the current version of QEMU.
+#
+# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-version" }
+# <- {
+# "return":{
+# "qemu":{
+# "major":0,
+# "minor":11,
+# "micro":5
+# },
+# "package":""
+# }
+# }
+#
+##
+{ 'command': 'query-version', 'returns': 'VersionInfo',
+ 'allow-preconfig': true }
+
+##
+# @CommandInfo:
+#
+# Information about a QMP command
+#
+# @name: The command name
+#
+# Since: 0.14.0
+##
+{ 'struct': 'CommandInfo', 'data': {'name': 'str'} }
+
+##
+# @query-commands:
+#
+# Return a list of supported QMP commands by this server
+#
+# Returns: A list of @CommandInfo for all supported commands
+#
+# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-commands" }
+# <- {
+# "return":[
+# {
+# "name":"query-balloon"
+# },
+# {
+# "name":"system_powerdown"
+# }
+# ]
+# }
+#
+# Note: This example has been shortened as the real response is too long.
+#
+##
+{ 'command': 'query-commands', 'returns': ['CommandInfo'],
+ 'allow-preconfig': true }
+
+##
+# @EventInfo:
+#
+# Information about a QMP event
+#
+# @name: The event name
+#
+# Since: 1.2.0
+##
+{ 'struct': 'EventInfo', 'data': {'name': 'str'} }
+
+##
+# @query-events:
+#
+# Return information on QMP events.
+#
+# Returns: A list of @EventInfo.
+#
+# Since: 1.2.0
+#
+# Note: This command is deprecated, because its output doesn't reflect
+# compile-time configuration. Use query-qmp-schema instead.
+#
+# Example:
+#
+# -> { "execute": "query-events" }
+# <- {
+# "return": [
+# {
+# "name":"SHUTDOWN"
+# },
+# {
+# "name":"RESET"
+# }
+# ]
+# }
+#
+# Note: This example has been shortened as the real response is too long.
+#
+##
+{ 'command': 'query-events', 'returns': ['EventInfo'] }
+
+##
+# @quit:
+#
+# This command will cause the QEMU process to exit gracefully. While every
+# attempt is made to send the QMP response before terminating, this is not
+# guaranteed. When using this interface, a premature EOF would not be
+# unexpected.
+#
+# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "quit" }
+# <- { "return": {} }
+##
+{ 'command': 'quit' }
diff --git a/qapi/misc.json b/qapi/misc.json
index af00279e7b..c18fe681fb 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -8,159 +8,6 @@
{ 'include': 'common.json' }
##
-# @qmp_capabilities:
-#
-# Enable QMP capabilities.
-#
-# Arguments:
-#
-# @enable: An optional list of QMPCapability values to enable. The
-# client must not enable any capability that is not
-# mentioned in the QMP greeting message. If the field is not
-# provided, it means no QMP capabilities will be enabled.
-# (since 2.12)
-#
-# Example:
-#
-# -> { "execute": "qmp_capabilities",
-# "arguments": { "enable": [ "oob" ] } }
-# <- { "return": {} }
-#
-# Notes: This command is valid exactly when first connecting: it must be
-# issued before any other command will be accepted, and will fail once the
-# monitor is accepting other commands. (see qemu docs/interop/qmp-spec.txt)
-#
-# The QMP client needs to explicitly enable QMP capabilities, otherwise
-# all the QMP capabilities will be turned off by default.
-#
-# Since: 0.13
-#
-##
-{ 'command': 'qmp_capabilities',
- 'data': { '*enable': [ 'QMPCapability' ] },
- 'allow-preconfig': true }
-
-##
-# @QMPCapability:
-#
-# Enumeration of capabilities to be advertised during initial client
-# connection, used for agreeing on particular QMP extension behaviors.
-#
-# @oob: QMP ability to support out-of-band requests.
-# (Please refer to qmp-spec.txt for more information on OOB)
-#
-# Since: 2.12
-#
-##
-{ 'enum': 'QMPCapability',
- 'data': [ 'oob' ] }
-
-##
-# @VersionTriple:
-#
-# A three-part version number.
-#
-# @major: The major version number.
-#
-# @minor: The minor version number.
-#
-# @micro: The micro version number.
-#
-# Since: 2.4
-##
-{ 'struct': 'VersionTriple',
- 'data': {'major': 'int', 'minor': 'int', 'micro': 'int'} }
-
-
-##
-# @VersionInfo:
-#
-# A description of QEMU's version.
-#
-# @qemu: The version of QEMU. By current convention, a micro
-# version of 50 signifies a development branch. A micro version
-# greater than or equal to 90 signifies a release candidate for
-# the next minor version. A micro version of less than 50
-# signifies a stable release.
-#
-# @package: QEMU will always set this field to an empty string. Downstream
-# versions of QEMU should set this to a non-empty string. The
-# exact format depends on the downstream however it highly
-# recommended that a unique name is used.
-#
-# Since: 0.14.0
-##
-{ 'struct': 'VersionInfo',
- 'data': {'qemu': 'VersionTriple', 'package': 'str'} }
-
-##
-# @query-version:
-#
-# Returns the current version of QEMU.
-#
-# Returns: A @VersionInfo object describing the current version of QEMU.
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "query-version" }
-# <- {
-# "return":{
-# "qemu":{
-# "major":0,
-# "minor":11,
-# "micro":5
-# },
-# "package":""
-# }
-# }
-#
-##
-{ 'command': 'query-version', 'returns': 'VersionInfo',
- 'allow-preconfig': true }
-
-##
-# @CommandInfo:
-#
-# Information about a QMP command
-#
-# @name: The command name
-#
-# Since: 0.14.0
-##
-{ 'struct': 'CommandInfo', 'data': {'name': 'str'} }
-
-##
-# @query-commands:
-#
-# Return a list of supported QMP commands by this server
-#
-# Returns: A list of @CommandInfo for all supported commands
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "query-commands" }
-# <- {
-# "return":[
-# {
-# "name":"query-balloon"
-# },
-# {
-# "name":"system_powerdown"
-# }
-# ]
-# }
-#
-# Note: This example has been shortened as the real response is too long.
-#
-##
-{ 'command': 'query-commands', 'returns': ['CommandInfo'],
- 'allow-preconfig': true }
-
-##
# @LostTickPolicy:
#
# Policy for handling lost ticks in timer devices. Ticks end up getting
@@ -313,48 +160,6 @@
{ 'command': 'query-uuid', 'returns': 'UuidInfo', 'allow-preconfig': true }
##
-# @EventInfo:
-#
-# Information about a QMP event
-#
-# @name: The event name
-#
-# Since: 1.2.0
-##
-{ 'struct': 'EventInfo', 'data': {'name': 'str'} }
-
-##
-# @query-events:
-#
-# Return information on QMP events.
-#
-# Returns: A list of @EventInfo.
-#
-# Since: 1.2.0
-#
-# Note: This command is deprecated, because its output doesn't reflect
-# compile-time configuration. Use query-qmp-schema instead.
-#
-# Example:
-#
-# -> { "execute": "query-events" }
-# <- {
-# "return": [
-# {
-# "name":"SHUTDOWN"
-# },
-# {
-# "name":"RESET"
-# }
-# ]
-# }
-#
-# Note: This example has been shortened as the real response is too long.
-#
-##
-{ 'command': 'query-events', 'returns': ['EventInfo'] }
-
-##
# @IOThreadInfo:
#
# Information about an iothread
@@ -775,23 +580,6 @@
{ 'command': 'query-pci', 'returns': ['PciInfo'] }
##
-# @quit:
-#
-# This command will cause the QEMU process to exit gracefully. While every
-# attempt is made to send the QMP response before terminating, this is not
-# guaranteed. When using this interface, a premature EOF would not be
-# unexpected.
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "quit" }
-# <- { "return": {} }
-##
-{ 'command': 'quit' }
-
-##
# @stop:
#
# Stop all guest VCPU execution.
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 9751b11f8f..fe980ce437 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -98,6 +98,7 @@
{ 'include': 'migration.json' }
{ 'include': 'transaction.json' }
{ 'include': 'trace.json' }
+{ 'include': 'control.json' }
{ 'include': 'introspect.json' }
{ 'include': 'qom.json' }
{ 'include': 'qdev.json' }
diff --git a/qemu-doc.texi b/qemu-doc.texi
index a1ef6b6484..33b9597b1d 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2880,10 +2880,11 @@ lifetime distros will be assumed to ship similar software versions.
For distributions with long-lifetime releases, the project will aim to support
the most recent major version at all times. Support for the previous major
-version will be dropped 2 years after the new major version is released. For
-the purposes of identifying supported software versions, the project will look
-at RHEL, Debian, Ubuntu LTS, and SLES distros. Other long-lifetime distros will
-be assumed to ship similar software versions.
+version will be dropped 2 years after the new major version is released,
+or when it reaches ``end of life''. For the purposes of identifying
+supported software versions, the project will look at RHEL, Debian,
+Ubuntu LTS, and SLES distros. Other long-lifetime distros will be
+assumed to ship similar software versions.
@section Windows
diff --git a/tests/qtest/qmp-test.c b/tests/qtest/qmp-test.c
index 1b0eb69832..1a8876b6ca 100644
--- a/tests/qtest/qmp-test.c
+++ b/tests/qtest/qmp-test.c
@@ -13,7 +13,7 @@
#include "qemu/osdep.h"
#include "libqtest.h"
#include "qapi/error.h"
-#include "qapi/qapi-visit-misc.h"
+#include "qapi/qapi-visit-control.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qobject-input-visitor.h"
diff --git a/ui/gtk.c b/ui/gtk.c
index f3f0af8921..030b251c61 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -32,6 +32,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-misc.h"
#include "qemu/cutils.h"
diff --git a/vl.c b/vl.c
index b0ee318f99..794f2e5733 100644
--- a/vl.c
+++ b/vl.c
@@ -2127,50 +2127,7 @@ static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
static int mon_init_func(void *opaque, QemuOpts *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);
- if (chr == NULL) {
- error_setg(errp, "chardev \"%s\" not found", chardev);
- return -1;
- }
-
- if (qmp) {
- monitor_init_qmp(chr, pretty);
- } else {
- monitor_init_hmp(chr, true);
- }
- return 0;
+ return monitor_init_opts(opts, errp);
}
static void monitor_parse(const char *optarg, const char *mode, bool pretty)