提交 d34b867d 编写于 作者: L Luiz Capitulino 提交者: Michael Roth

qapi: add support for command options

Options allow for changes in commands behavior. This commit introduces
the QCO_NO_SUCCESS_RESP option, which causes a command to not emit a
success response.

This is needed by commands such as qemu-ga's guest-shutdown, which
may not be able to complete before the VM vanishes. In this case, it's
useful and simpler not to bother sending a success response.
Signed-off-by: NLuiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: NMichael Roth <mdroth@linux.vnet.ibm.com>
上级 76ee152a
...@@ -25,16 +25,24 @@ typedef enum QmpCommandType ...@@ -25,16 +25,24 @@ typedef enum QmpCommandType
QCT_NORMAL, QCT_NORMAL,
} QmpCommandType; } QmpCommandType;
typedef enum QmpCommandOptions
{
QCO_NO_OPTIONS = 0x0,
QCO_NO_SUCCESS_RESP = 0x1,
} QmpCommandOptions;
typedef struct QmpCommand typedef struct QmpCommand
{ {
const char *name; const char *name;
QmpCommandType type; QmpCommandType type;
QmpCommandFunc *fn; QmpCommandFunc *fn;
QmpCommandOptions options;
QTAILQ_ENTRY(QmpCommand) node; QTAILQ_ENTRY(QmpCommand) node;
bool enabled; bool enabled;
} QmpCommand; } QmpCommand;
void qmp_register_command(const char *name, QmpCommandFunc *fn); void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
QmpCommand *qmp_find_command(const char *name); QmpCommand *qmp_find_command(const char *name);
QObject *qmp_dispatch(QObject *request); QObject *qmp_dispatch(QObject *request);
void qmp_disable_command(const char *name); void qmp_disable_command(const char *name);
......
...@@ -94,8 +94,12 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp) ...@@ -94,8 +94,12 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
switch (cmd->type) { switch (cmd->type) {
case QCT_NORMAL: case QCT_NORMAL:
cmd->fn(args, &ret, errp); cmd->fn(args, &ret, errp);
if (!error_is_set(errp) && ret == NULL) { if (!error_is_set(errp)) {
ret = QOBJECT(qdict_new()); if (cmd->options & QCO_NO_SUCCESS_RESP) {
g_assert(!ret);
} else if (!ret) {
ret = QOBJECT(qdict_new());
}
} }
break; break;
} }
......
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands = static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
QTAILQ_HEAD_INITIALIZER(qmp_commands); QTAILQ_HEAD_INITIALIZER(qmp_commands);
void qmp_register_command(const char *name, QmpCommandFunc *fn) void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options)
{ {
QmpCommand *cmd = g_malloc0(sizeof(*cmd)); QmpCommand *cmd = g_malloc0(sizeof(*cmd));
...@@ -25,6 +26,7 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn) ...@@ -25,6 +26,7 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn)
cmd->type = QCT_NORMAL; cmd->type = QCT_NORMAL;
cmd->fn = fn; cmd->fn = fn;
cmd->enabled = true; cmd->enabled = true;
cmd->options = options;
QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node); QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
} }
......
...@@ -291,14 +291,24 @@ out: ...@@ -291,14 +291,24 @@ out:
return ret return ret
def option_value_matches(opt, val, cmd):
if opt in cmd and cmd[opt] == val:
return True
return False
def gen_registry(commands): def gen_registry(commands):
registry="" registry=""
push_indent() push_indent()
for cmd in commands: for cmd in commands:
options = 'QCO_NO_OPTIONS'
if option_value_matches('success-response', 'no', cmd):
options = 'QCO_NO_SUCCESS_RESP'
registry += mcgen(''' registry += mcgen('''
qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s); qmp_register_command("%(name)s", qmp_marshal_input_%(c_name)s, %(opts)s);
''', ''',
name=cmd['command'], c_name=c_fun(cmd['command'])) name=cmd['command'], c_name=c_fun(cmd['command']),
opts=options)
pop_indent() pop_indent()
ret = mcgen(''' ret = mcgen('''
static void qmp_init_marshal(void) static void qmp_init_marshal(void)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册