From 5aba53a32a3c941e686330d0c15ca5db4bd02b1e Mon Sep 17 00:00:00 2001 Message-Id: <5aba53a32a3c941e686330d0c15ca5db4bd02b1e.1342518105.git.minovotn@redhat.com> In-Reply-To: <27a73856ecc481c66c7afac8171f753887f32e31.1342518105.git.minovotn@redhat.com> References: <27a73856ecc481c66c7afac8171f753887f32e31.1342518105.git.minovotn@redhat.com> From: Luiz Capitulino Date: Tue, 5 Jun 2012 14:58:35 +0200 Subject: [PATCH 26/41] qapi: add support for command options RH-Author: Luiz Capitulino Message-id: <1338908331-15633-21-git-send-email-lcapitulino@redhat.com> Patchwork-id: 39917 O-Subject: [PATCH RHEL6.4 qemu-kvm 20/36] qapi: add support for command options Bugzilla: 827612 RH-Acked-by: Paolo Bonzini RH-Acked-by: Juan Quintela RH-Acked-by: Jeffrey Cody 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: Luiz Capitulino Signed-off-by: Michael Roth (cherry picked from commit d34b867d816585900b72d09d42a34cea3057903d) Signed-off-by: Luiz Capitulino --- qapi/qmp-core.h | 10 +++++++++- qapi/qmp-dispatch.c | 8 ++++++-- qapi/qmp-registry.c | 4 +++- scripts/qapi-commands.py | 14 ++++++++++++-- 4 files changed, 30 insertions(+), 6 deletions(-) Signed-off-by: Michal Novotny --- qapi/qmp-core.h | 10 +++++++++- qapi/qmp-dispatch.c | 8 ++++++-- qapi/qmp-registry.c | 4 +++- scripts/qapi-commands.py | 14 ++++++++++++-- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h index 431ddbb..b0f64ba 100644 --- a/qapi/qmp-core.h +++ b/qapi/qmp-core.h @@ -25,16 +25,24 @@ typedef enum QmpCommandType QCT_NORMAL, } QmpCommandType; +typedef enum QmpCommandOptions +{ + QCO_NO_OPTIONS = 0x0, + QCO_NO_SUCCESS_RESP = 0x1, +} QmpCommandOptions; + typedef struct QmpCommand { const char *name; QmpCommandType type; QmpCommandFunc *fn; + QmpCommandOptions options; QTAILQ_ENTRY(QmpCommand) node; bool enabled; } 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); QObject *qmp_dispatch(QObject *request); void qmp_disable_command(const char *name); diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 43f640a..122c1a2 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -94,8 +94,12 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp) switch (cmd->type) { case QCT_NORMAL: cmd->fn(args, &ret, errp); - if (!error_is_set(errp) && ret == NULL) { - ret = QOBJECT(qdict_new()); + if (!error_is_set(errp)) { + if (cmd->options & QCO_NO_SUCCESS_RESP) { + g_assert(!ret); + } else if (!ret) { + ret = QOBJECT(qdict_new()); + } } break; } diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c index 9ffb542..bec66a2 100644 --- a/qapi/qmp-registry.c +++ b/qapi/qmp-registry.c @@ -17,7 +17,8 @@ static QTAILQ_HEAD(QmpCommandList, QmpCommand) 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 = qemu_mallocz(sizeof(*cmd)); @@ -25,6 +26,7 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn) cmd->type = QCT_NORMAL; cmd->fn = fn; cmd->enabled = true; + cmd->options = options; QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node); } diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py index 30a24d2..5e86a17 100644 --- a/scripts/qapi-commands.py +++ b/scripts/qapi-commands.py @@ -291,14 +291,24 @@ out: 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): registry="" push_indent() for cmd in commands: + options = 'QCO_NO_OPTIONS' + if option_value_matches('success-response', 'no', cmd): + options = 'QCO_NO_SUCCESS_RESP' + 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() ret = mcgen(''' static void qmp_init_marshal(void) -- 1.7.10.4