diff options
-rw-r--r-- | include/monitor/monitor.h | 3 | ||||
-rw-r--r-- | include/sysemu/sysemu.h | 1 | ||||
-rw-r--r-- | monitor/Makefile.objs | 3 | ||||
-rw-r--r-- | monitor/hmp-cmds.c | 1 | ||||
-rw-r--r-- | monitor/misc.c | 127 | ||||
-rw-r--r-- | monitor/monitor-internal.h | 4 | ||||
-rw-r--r-- | monitor/monitor.c | 48 | ||||
-rw-r--r-- | monitor/qmp-cmds-control.c | 169 | ||||
-rw-r--r-- | monitor/qmp-cmds.c | 15 | ||||
-rw-r--r-- | monitor/qmp.c | 2 | ||||
-rw-r--r-- | qapi/Makefile.objs | 6 | ||||
-rw-r--r-- | qapi/control.json | 218 | ||||
-rw-r--r-- | qapi/misc.json | 212 | ||||
-rw-r--r-- | qapi/qapi-schema.json | 1 | ||||
-rw-r--r-- | qemu-doc.texi | 9 | ||||
-rw-r--r-- | tests/qtest/qmp-test.c | 2 | ||||
-rw-r--r-- | ui/gtk.c | 1 | ||||
-rw-r--r-- | vl.c | 45 |
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" @@ -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" @@ -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) |