mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
qmp: Redo how the client requests out-of-band execution
Commit cf869d5317
"qmp: support out-of-band (oob) execution" added a
general mechanism for command-independent arguments just for an
out-of-band flag:
The "control" key is introduced to store this extra flag. "control"
field is used to store arguments that are shared by all the commands,
rather than command specific arguments. Let "run-oob" be the first.
However, it failed to reject unknown members of "control". For
instance, in QMP command
{"execute": "query-name", "id": 42, "control": {"crap": true}}
"crap" gets silently ignored.
Instead of fixing this, revert the general "control" mechanism
(because YAGNI), and do it the way I initially proposed, with key
"exec-oob". Simpler code, simpler interface.
An out-of-band command
{"execute": "migrate-pause", "id": 42, "control": {"run-oob": true}}
becomes
{"exec-oob": "migrate-pause", "id": 42}
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180703085358.13941-13-armbru@redhat.com>
[Commit message typo fixed]
This commit is contained in:
parent
674ed7228f
commit
00ecec151d
6 changed files with 39 additions and 53 deletions
|
@ -23,11 +23,11 @@
|
|||
QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
|
||||
Error **errp)
|
||||
{
|
||||
const char *exec_key = NULL;
|
||||
const QDictEntry *ent;
|
||||
const char *arg_name;
|
||||
const QObject *arg_obj;
|
||||
bool has_exec_key = false;
|
||||
QDict *dict = NULL;
|
||||
QDict *dict;
|
||||
|
||||
dict = qobject_to(QDict, request);
|
||||
if (!dict) {
|
||||
|
@ -40,25 +40,25 @@ QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
|
|||
arg_name = qdict_entry_key(ent);
|
||||
arg_obj = qdict_entry_value(ent);
|
||||
|
||||
if (!strcmp(arg_name, "execute")) {
|
||||
if (!strcmp(arg_name, "execute")
|
||||
|| (!strcmp(arg_name, "exec-oob") && allow_oob)) {
|
||||
if (qobject_type(arg_obj) != QTYPE_QSTRING) {
|
||||
error_setg(errp,
|
||||
"QMP input member 'execute' must be a string");
|
||||
error_setg(errp, "QMP input member '%s' must be a string",
|
||||
arg_name);
|
||||
return NULL;
|
||||
}
|
||||
has_exec_key = true;
|
||||
if (exec_key) {
|
||||
error_setg(errp, "QMP input member '%s' clashes with '%s'",
|
||||
arg_name, exec_key);
|
||||
return NULL;
|
||||
}
|
||||
exec_key = arg_name;
|
||||
} else if (!strcmp(arg_name, "arguments")) {
|
||||
if (qobject_type(arg_obj) != QTYPE_QDICT) {
|
||||
error_setg(errp,
|
||||
"QMP input member 'arguments' must be an object");
|
||||
return NULL;
|
||||
}
|
||||
} else if (!strcmp(arg_name, "control") && allow_oob) {
|
||||
if (qobject_type(arg_obj) != QTYPE_QDICT) {
|
||||
error_setg(errp,
|
||||
"QMP input member 'control' must be a dict");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
error_setg(errp, "QMP input member '%s' is unexpected",
|
||||
arg_name);
|
||||
|
@ -66,7 +66,7 @@ QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
|
|||
}
|
||||
}
|
||||
|
||||
if (!has_exec_key) {
|
||||
if (!exec_key) {
|
||||
error_setg(errp, "QMP input lacks member 'execute'");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -88,7 +88,11 @@ static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
command = qdict_get_str(dict, "execute");
|
||||
command = qdict_get_try_str(dict, "execute");
|
||||
if (!command) {
|
||||
assert(allow_oob);
|
||||
command = qdict_get_str(dict, "exec-oob");
|
||||
}
|
||||
cmd = qmp_find_command(cmds, command);
|
||||
if (cmd == NULL) {
|
||||
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
|
||||
|
@ -137,25 +141,12 @@ QObject *qmp_build_error_object(Error *err)
|
|||
}
|
||||
|
||||
/*
|
||||
* Detect whether a request should be run out-of-band, by quickly
|
||||
* peeking at whether we have: { "control": { "run-oob": true } }. By
|
||||
* default commands are run in-band.
|
||||
* Does @qdict look like a command to be run out-of-band?
|
||||
*/
|
||||
bool qmp_is_oob(QDict *dict)
|
||||
{
|
||||
QBool *bool_obj;
|
||||
|
||||
dict = qdict_get_qdict(dict, "control");
|
||||
if (!dict) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool_obj = qobject_to(QBool, qdict_get(dict, "run-oob"));
|
||||
if (!bool_obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return qbool_get_bool(bool_obj);
|
||||
return qdict_haskey(dict, "exec-oob")
|
||||
&& !qdict_haskey(dict, "execute");
|
||||
}
|
||||
|
||||
QObject *qmp_dispatch(QmpCommandList *cmds, QObject *request,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue