From c3e9555182edc8766d67d2f4471774e2aac0500a Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 29 Jan 2020 11:22:36 +0100 Subject: [PATCH 1/5] monitor: Move monitor option parsing to monitor/monitor.c Both the system emulators and tools with QMP support (specifically, the planned storage daemon) will need to parse monitor options, so move that code to monitor/monitor.c, which can be linked into binaries that aren't a system emulator. Signed-off-by: Kevin Wolf Reviewed-by: Markus Armbruster Message-Id: <20200129102239.31435-2-kwolf@redhat.com> Signed-off-by: Markus Armbruster --- include/monitor/monitor.h | 3 +++ include/sysemu/sysemu.h | 1 - monitor/monitor.c | 48 +++++++++++++++++++++++++++++++++++++++ vl.c | 45 +----------------------------------- 4 files changed, 52 insertions(+), 45 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/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/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) From fa4dcf577ea61758bf55b64c8f9590c29897fb82 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 29 Jan 2020 11:22:37 +0100 Subject: [PATCH 2/5] qapi: Split control.json off misc.json misc.json contains definitions that are related to the system emulator, so it can't be used for other tools like the storage daemon. This patch moves basic functionality that is shared between all tools (and mostly related to the monitor itself) into a new control.json, which could be used in tools as well. Signed-off-by: Kevin Wolf Reviewed-by: Markus Armbruster Message-Id: <20200129102239.31435-3-kwolf@redhat.com> [Commit message tweaked] Signed-off-by: Markus Armbruster --- monitor/hmp-cmds.c | 1 + monitor/misc.c | 1 + monitor/monitor-internal.h | 1 + monitor/qmp-cmds.c | 1 + monitor/qmp.c | 2 +- qapi/Makefile.objs | 6 +- qapi/control.json | 218 +++++++++++++++++++++++++++++++++++++ qapi/misc.json | 212 ------------------------------------ qapi/qapi-schema.json | 1 + tests/qtest/qmp-test.c | 2 +- ui/gtk.c | 1 + 11 files changed, 229 insertions(+), 217 deletions(-) create mode 100644 qapi/control.json 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..b4303d42d0 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -67,6 +67,7 @@ #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" diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index d78f5ca190..4d402ded85 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" diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index c6faa3eaf0..a55d2dffc2 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -32,6 +32,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" 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 @@ -7,159 +7,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: # @@ -312,48 +159,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: # @@ -774,23 +579,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: # 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/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" From 567628163ec8c6b76ba3117c3062edc0521dc185 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 29 Jan 2020 11:22:38 +0100 Subject: [PATCH 3/5] monitor: Collect "control" command handlers in qmp-cmds.control.c Move all of the QMP commands handlers to implement the 'control' module (qapi/control.json) that can be shared between the system emulator and tools such as a storage daemon to a new file monitor/qmp-cmds-control.c. Signed-off-by: Kevin Wolf Reviewed-by: Markus Armbruster Message-Id: <20200129102239.31435-4-kwolf@redhat.com> [Commit message tweaked] Signed-off-by: Markus Armbruster --- monitor/Makefile.objs | 3 +- monitor/misc.c | 110 -------------------------- monitor/qmp-cmds-control.c | 153 +++++++++++++++++++++++++++++++++++++ monitor/qmp-cmds.c | 14 ---- 4 files changed, 155 insertions(+), 125 deletions(-) create mode 100644 monitor/qmp-cmds-control.c 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/misc.c b/monitor/misc.c index b4303d42d0..4c4e47fdc4 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -72,7 +72,6 @@ #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" @@ -233,58 +232,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 @@ -323,63 +270,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/qmp-cmds-control.c b/monitor/qmp-cmds-control.c new file mode 100644 index 0000000000..d5f21f90e6 --- /dev/null +++ b/monitor/qmp-cmds-control.c @@ -0,0 +1,153 @@ +/* + * 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" + +/* + * 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; +} diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index a55d2dffc2..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" @@ -52,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)); From 7d3f505359214734d46c159af0a88b522f6692ad Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 29 Jan 2020 11:22:39 +0100 Subject: [PATCH 4/5] monitor: Move qmp_query_qmp_schema to qmp-cmds-control.c monitor/misc.c contains code that works only in the system emulator, so it can't be linked to tools like a storage daemon. In order to make schema introspection available for tools, move the function to monitor/qmp-cmds-control.c, which can be linked into the storage daemon. Signed-off-by: Kevin Wolf Reviewed-by: Markus Armbruster Message-Id: <20200129102239.31435-5-kwolf@redhat.com> Signed-off-by: Markus Armbruster --- monitor/misc.c | 16 ---------------- monitor/monitor-internal.h | 3 +++ monitor/qmp-cmds-control.c | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/monitor/misc.c b/monitor/misc.c index 4c4e47fdc4..6c41293102 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -75,7 +75,6 @@ #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,21 +231,6 @@ static void hmp_info_help(Monitor *mon, const QDict *qdict) help_cmd(mon, "info"); } -/* - * 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) { /* diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 4d402ded85..3e6baba88f 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h @@ -180,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/qmp-cmds-control.c b/monitor/qmp-cmds-control.c index d5f21f90e6..5cd9bb817c 100644 --- a/monitor/qmp-cmds-control.c +++ b/monitor/qmp-cmds-control.c @@ -29,6 +29,7 @@ #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. @@ -151,3 +152,18 @@ EventInfoList *qmp_query_events(Error **errp) 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); +} From ec95fcc8bae624e87c7601d2d4baf7c519c3814e Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 13 Feb 2020 09:43:34 +0100 Subject: [PATCH 5/5] qemu-doc: Clarify extent of build platform support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supporting a build platform beyond its end of life makes no sense. Spell that out just to be clear. Signed-off-by: Markus Armbruster Message-Id: <20200213084335.15100-1-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Eduardo Habkost --- qemu-doc.texi | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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