qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 7/8] QMP: Enable feature negotiation support


From: Luiz Capitulino
Subject: [Qemu-devel] [PATCH 7/8] QMP: Enable feature negotiation support
Date: Thu, 28 Jan 2010 11:42:59 -0200

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 <address@hidden>
---
 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");
-- 
1.6.6





reply via email to

[Prev in Thread] Current Thread [Next in Thread]