[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/1] qmp: Add support for requesting the list of arg
From: |
Alberto Garcia |
Subject: |
[Qemu-devel] [PATCH 1/1] qmp: Add support for requesting the list of arguments from a command |
Date: |
Tue, 24 Feb 2015 15:51:55 +0200 |
This patch adds the CommandArgumentInfo type that lists the details of
an argument that a QMP command can take. It currently includes its name
and whether it's optional or not, but it can be extended in the future
to include other information.
A new 'query-command-args' command returns a list of all supported
arguments from a particular command. Additionally, 'query-commands'
has a new, optional, 'query-args' argument that makes the return value
include the arguments for all commands.
Signed-off-by: Alberto Garcia <address@hidden>
---
monitor.c | 53 +++++++++++++++++++++++++++++++-
qapi/common.json | 41 +++++++++++++++++++++++--
qmp-commands.hx | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 178 insertions(+), 9 deletions(-)
diff --git a/monitor.c b/monitor.c
index c3cc060..867a1cc 100644
--- a/monitor.c
+++ b/monitor.c
@@ -231,6 +231,8 @@ static const mon_cmd_t qmp_cmds[];
Monitor *cur_mon;
Monitor *default_mon;
+static const mon_cmd_t *qmp_find_cmd(const char *cmdname);
+
static void monitor_command_cb(void *opaque, const char *cmdline,
void *readline_opaque);
@@ -963,7 +965,52 @@ static void do_info_help(Monitor *mon, const QDict *qdict)
help_cmd(mon, "info");
}
-CommandInfoList *qmp_query_commands(Error **errp)
+CommandArgumentInfoList *qmp_query_command_args(const char *command,
+ Error **errp)
+{
+ CommandArgumentInfoList *cmd_list = NULL;
+ const mon_cmd_t *cmd = qmp_find_cmd(command);
+ const char *arg;
+
+ if (cmd == NULL) {
+ error_setg(errp, "Command '%s' not found", command);
+ return NULL;
+ }
+
+ for (arg = cmd->args_type; arg && *arg; arg = index(arg, ',')) {
+ CommandArgumentInfoList *info;
+ const char *type = index(arg, ':');
+
+ /* Skip the comma before the argument name */
+ if (*arg == ',') {
+ arg++;
+ }
+
+ /* Skip the semicolon before the argument type */
+ if (type) {
+ type++;
+ }
+
+ /* Check if the string is malformed */
+ if (!type || !*type) {
+ g_assert_not_reached();
+ return cmd_list;
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = g_strndup(arg, type - arg - 1);
+ info->value->optional = (type[0] == '-' || type[1] == '?');
+
+ info->next = cmd_list;
+ cmd_list = info;
+ }
+
+ return cmd_list;
+}
+
+CommandInfoList *qmp_query_commands(bool has_query_args, bool query_args,
+ Error **errp)
{
CommandInfoList *info, *cmd_list = NULL;
const mon_cmd_t *cmd;
@@ -973,6 +1020,10 @@ CommandInfoList *qmp_query_commands(Error **errp)
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(cmd->name);
+ if (has_query_args && query_args) {
+ info->value->args = qmp_query_command_args(cmd->name, errp);
+ }
+
info->next = cmd_list;
cmd_list = info;
}
diff --git a/qapi/common.json b/qapi/common.json
index 63ef3b4..d812557 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -66,26 +66,63 @@
{ 'command': 'query-version', 'returns': 'VersionInfo' }
##
+# @CommandArgumentInfo:
+#
+# Information about an argument that a QMP command can take.
+#
+# @name: The argument name.
+#
+# @optional: Whether the argument is optional or not
+#
+# Since: 2.3
+##
+{ 'type': 'CommandArgumentInfo',
+ 'data': {'name': 'str', 'optional': 'bool'} }
+
+##
# @CommandInfo:
#
# Information about a QMP command
#
# @name: The command name
#
+# @args: A list of @CommandArgumentInfo that the command can take (Since 2.3)
+#
# Since: 0.14.0
##
-{ 'type': 'CommandInfo', 'data': {'name': 'str'} }
+{ 'type': 'CommandInfo',
+ 'data': {'name': 'str', 'args': ['CommandArgumentInfo'] } }
##
# @query-commands:
#
# Return a list of supported QMP commands by this server
#
+# @query-args: #optional Whether to return the list of arguments
+# for that command. Defaults to false (Since 2.3)
+#
# Returns: A list of @CommandInfo for all supported commands
#
# Since: 0.14.0
##
-{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
+{ 'command': 'query-commands',
+ 'data': {'*query-args': 'bool' },
+ 'returns': ['CommandInfo'] }
+
+##
+# @query-command-args:
+#
+# Return the list of arguments that a QMP command can take
+#
+# @command: Name of the command to query
+#
+# Returns: A list of @CommandArgumentInfo for all supported arguments
+#
+# Since: 2.3
+##
+{ 'command': 'query-command-args',
+ 'data': {'command': 'str' },
+ 'returns': ['CommandArgumentInfo'] }
##
# @OnOffAuto
diff --git a/qmp-commands.hx b/qmp-commands.hx
index a85d847..cab69f9 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1946,25 +1946,52 @@ query-commands
List QMP available commands.
Each command is represented by a json-object, the returned value is a
json-array
-of all commands.
+of all commands, optionally including their arguments.
+
+Arguments:
+
+- "query-args": whether to return the arguments for each command.
+ Defaults to false (json-bool, optional)
Each json-object contain:
- "name": command's name (json-string)
+- "args": a json-array of all arguments for that command. It will be empty if
+ the list of arguments was not requested using "query-args".
+ Each argument contains:
+ - "name": name of the argument (json-string)
+ - "optional": whether the argument is optional or not (json-bool)
Example:
--> { "execute": "query-commands" }
+-> { "execute": "query-commands", "arguments": { "query-args": true } }
<- {
"return":[
{
- "name":"query-balloon"
+ "name": "drive-backup",
+ "args": [
+ { "name": "sync", "optional": false }
+ { "name": "device", "optional": false },
+ { "name": "target", "optional": false },
+ { "name": "speed", "optional": true },
+ { "name": "mode", "optional": true },
+ { "name": "format", "optional": true },
+ { "name": "on-source-error", "optional": true },
+ { "name": "on-target-error", "optional": true },
+ ]
},
{
- "name":"system_powerdown"
+ "name": "block-commit",
+ "args": [
+ { "name": "device", "optional": false }
+ { "name": "base", "optional": true },
+ { "name": "top", "optional": true },
+ { "name": "backing-file", "optional": true },
+ { "name": "speed", "optional": true },
+ ]
}
]
- }
+}
Note: This example has been shortened as the real response is too long.
@@ -1972,11 +1999,65 @@ EQMP
{
.name = "query-commands",
- .args_type = "",
+ .args_type = "query-args:b?",
.mhandler.cmd_new = qmp_marshal_input_query_commands,
},
SQMP
+query-command-args
+------------------
+
+List all arguments from a QMP command.
+
+Each argument is represented by a json-object, the returned value is a
+json-array of all arguments from a particular command.
+
+Arguments:
+
+- "command": the command name (json-string)
+
+Each json-object contain:
+
+- "name": the name of the argument (json-string)
+- "optional": whether that argument is optional or not (json-bool)
+
+Example:
+
+-> { "execute": "query-command-args", "arguments": { "command": "block-commit"
} }
+<- {
+ "return":[
+ {
+ "name": "device",
+ "optional": false
+ },
+ {
+ "name": "base",
+ "optional": true
+ },
+ {
+ "name": "top",
+ "optional": true
+ },
+ {
+ "name": "backing-file",
+ "optional": true
+ },
+ {
+ "name": "speed",
+ "optional": true
+ }
+ ]
+}
+
+EQMP
+
+ {
+ .name = "query-command-args",
+ .args_type = "command:s",
+ .mhandler.cmd_new = qmp_marshal_input_query_command_args,
+ },
+
+SQMP
query-events
--------------
--
2.1.4