From patchwork Thu Jan 28 13:42:59 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 43865 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7BC91B7CFD for ; Fri, 29 Jan 2010 00:57:03 +1100 (EST) Received: from localhost ([127.0.0.1]:39146 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NaUrk-00061C-FH for incoming@patchwork.ozlabs.org; Thu, 28 Jan 2010 08:57:00 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NaUel-0000OM-0k for qemu-devel@nongnu.org; Thu, 28 Jan 2010 08:43:35 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NaUef-0000Lq-OD for qemu-devel@nongnu.org; Thu, 28 Jan 2010 08:43:34 -0500 Received: from [199.232.76.173] (port=57175 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NaUef-0000Lb-GS for qemu-devel@nongnu.org; Thu, 28 Jan 2010 08:43:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:28658) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NaUee-0003z9-Im for qemu-devel@nongnu.org; Thu, 28 Jan 2010 08:43:28 -0500 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o0SDhR6T027316 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 28 Jan 2010 08:43:27 -0500 Received: from localhost (vpn-10-249.rdu.redhat.com [10.11.10.249]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o0SDhQ15020974 for ; Thu, 28 Jan 2010 08:43:26 -0500 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Thu, 28 Jan 2010 11:42:59 -0200 Message-Id: <1264686180-29845-8-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1264686180-29845-1-git-send-email-lcapitulino@redhat.com> References: <1264686180-29845-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Subject: [Qemu-devel] [PATCH 7/8] QMP: Enable feature negotiation support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org It's done by starting QMP in handshake mode, where (apart from a few exceptions) only commands to query/enable/disable protocol capabilities are allowed. Asynchronous messages are also disabled in this mode. Clients can change to the operational mode (where capabilities' changes take effect and most commands are allowed) at any time. When the issued command is not allowed to be executed on the running mode, QMP will return the CommandNotFound error, as suggested by Markus. All these changes should have no effect in the user Monitor. Signed-off-by: Luiz Capitulino --- monitor.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 40 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 5851b6d..28a8c32 100644 --- a/monitor.c +++ b/monitor.c @@ -403,10 +403,12 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) } QLIST_FOREACH(mon, &mon_list, entry) { - if (monitor_ctrl_mode(mon)) { + if (monitor_ctrl_mode(mon) && + mon->mc->mode == QMODE_OPERATIONAL) { monitor_json_emitter(mon, QOBJECT(qmp)); } } + QDECREF(qmp); } @@ -4242,12 +4244,34 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args) return err; } +static int qmp_invalid_mode(const Monitor *mon, unsigned int cmd_flags) +{ + switch (mon->mc->mode) { + case QMODE_OPERATIONAL: + if (cmd_flags & HANDLER_HANDSHAKE_ONLY) { + return 1; + } + break; + case QMODE_HANDSHAKE: + if (!((cmd_flags & HANDLER_HANDSHAKE) || + (cmd_flags & HANDLER_HANDSHAKE_ONLY))) { + return 1; + } + break; + default: + abort(); + } + + return 0; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; QObject *obj; QDict *input, *args; const mon_cmd_t *cmd; + unsigned int cmd_flags; Monitor *mon = cur_mon; const char *cmd_name, *info_item; @@ -4289,6 +4313,15 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_input; } else if (strstart(cmd_name, "query-", &info_item)) { + /* check if it exists and get its flags */ + cmd = monitor_find_info_command(info_item); + if (!cmd) { + qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name); + goto err_input; + } + cmd_flags = cmd->flags; + + /* setup 'info' to call it */ cmd = monitor_find_command("info"); qdict_put_obj(input, "arguments", qobject_from_jsonf("{ 'item': %s }", info_item)); @@ -4298,6 +4331,12 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_input; } + cmd_flags = cmd->flags; + } + + if (qmp_invalid_mode(mon, cmd_flags)) { + qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name); + goto err_input; } obj = qdict_get(input, "arguments");