From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:36053) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QMV2j-0008Gt-Sa for qemu-devel@nongnu.org; Tue, 17 May 2011 20:55:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QMV2h-0006Lz-OP for qemu-devel@nongnu.org; Tue, 17 May 2011 20:55:17 -0400 Received: from mout.perfora.net ([74.208.4.194]:55569) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QMV2h-0006Lq-Jj for qemu-devel@nongnu.org; Tue, 17 May 2011 20:55:15 -0400 From: Michael Roth Date: Tue, 17 May 2011 19:52:04 -0500 Message-Id: <1305679930-4215-18-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1305679930-4215-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1305679930-4215-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v1][ 17/23] qapi: add QMP dispatch functions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@linux.vnet.ibm.com, mdroth@linux.vnet.ibm.com, lcapitulino@redhat.com Given an object recieved via QMP, this code uses the dispatch table provided by qmp_registry.c to call the corresponding marshalling/dispatch function and format return values/errors for delivery to the QMP. Currently only synchronous QMP functions are supported, but this will also be used for async QMP functions and QMP guest proxy dispatch as well. Signed-off-by: Michael Roth --- qapi/qmp-dispatch.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 104 insertions(+), 0 deletions(-) create mode 100644 qapi/qmp-dispatch.c diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c new file mode 100644 index 0000000..733decf --- /dev/null +++ b/qapi/qmp-dispatch.c @@ -0,0 +1,104 @@ +#include +#include "qemu-objects.h" +#include "qapi/qmp-core.h" +#include "json-parser.h" + +static QObject *qmp_dispatch_err(QmpState *state, QObject *request, Error **errp) +{ + const char *command; + QDict *args, *dict; + //QObject *request; + QmpCommand *cmd; + QObject *ret = NULL; + //Error *err = NULL; + + if (qobject_type(request) != QTYPE_QDICT) { + error_set(errp, QERR_JSON_PARSE_ERROR, "request is not a dictionary"); + goto out; + } + + dict = qobject_to_qdict(request); + if (!qdict_haskey(dict, "execute")) { + error_set(errp, QERR_JSON_PARSE_ERROR, "no execute key"); + goto out; + } + + command = qdict_get_str(dict, "execute"); + cmd = qmp_find_command(command); + if (cmd == NULL) { + error_set(errp, QERR_COMMAND_NOT_FOUND, command); + goto out; + } + + if (!qdict_haskey(dict, "arguments")) { + args = qdict_new(); + } else { + args = qdict_get_qdict(dict, "arguments"); + QINCREF(args); + } + + switch (cmd->type) { + case QCT_NORMAL: + cmd->fn(state, args, &ret, errp); + if (ret == NULL) { + ret = QOBJECT(qdict_new()); + } + break; + case QCT_ASYNC: { + QmpCommandState *s = qemu_mallocz(sizeof(*s)); + // FIXME save async commands and do something + // smart if disconnect occurs before completion + s->state = state; + s->tag = NULL; + if (qdict_haskey(dict, "tag")) { + s->tag = qdict_get(dict, "tag"); + qobject_incref(s->tag); + } + cmd->afn(args, errp, s); + ret = NULL; + } + break; + case QCT_PROXY: { + QmpCommandState *s = qemu_mallocz(sizeof(*s)); + // FIXME save async commands and do something + // smart if disconnect occurs before completion + s->state = state; + s->tag = NULL; + if (qdict_haskey(dict, "tag")) { + s->tag = qdict_get(dict, "tag"); + qobject_incref(s->tag); + } + cmd->pfn(args, errp, s); + ret = NULL; + } + break; + } + + QDECREF(args); + +out: + + return ret; +} + +QObject *qmp_dispatch(QmpState *state, QObject *request) +{ + Error *err = NULL; + QObject *ret; + QDict *rsp; + + ret = qmp_dispatch_err(state, request, &err); + + rsp = qdict_new(); + if (err) { + qdict_put_obj(rsp, "error", error_get_qobject(err)); + error_free(err); + } else if (ret) { + qdict_put_obj(rsp, "return", ret); + } else { + QDECREF(rsp); + return NULL; + } + + return QOBJECT(rsp); +} -- 1.7.0.4