qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 1/3] qapi: Allow QMP/QAPI commands to have array inp


From: Jeff Cody
Subject: [Qemu-devel] [PATCH 1/3] qapi: Allow QMP/QAPI commands to have array inputs
Date: Mon, 20 Feb 2012 12:31:10 -0500

The QAPI scripts allow for generating commands that receive parameter
input consisting of a list of custom structs, but the QMP input paramter
checking did not support receiving a qlist as opposed to a qdict for input.

This patch allows for array input parameters, although no argument validation
is performed for commands that accept a list input.

Signed-off-by: Jeff Cody <address@hidden>
---
 monitor.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
 monitor.h |    1 +
 2 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/monitor.c b/monitor.c
index a7df995..98e6017 100644
--- a/monitor.c
+++ b/monitor.c
@@ -125,8 +125,12 @@ typedef struct mon_cmd_t {
         void (*info)(Monitor *mon);
         void (*cmd)(Monitor *mon, const QDict *qdict);
         int  (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
+        int  (*cmd_new_list)(Monitor *mon, const QList *params,
+                             QObject **ret_data);
         int  (*cmd_async)(Monitor *mon, const QDict *params,
                           MonitorCompletion *cb, void *opaque);
+        int  (*cmd_async_list)(Monitor *mon, const QList *params,
+                          MonitorCompletion *cb, void *opaque);
     } mhandler;
     bool qapi;
     int flags;
@@ -353,6 +357,11 @@ static inline bool handler_is_async(const mon_cmd_t *cmd)
     return cmd->flags & MONITOR_CMD_ASYNC;
 }
 
+static inline bool handler_accepts_array(const mon_cmd_t *cmd)
+{
+    return cmd->flags & MONITOR_CMD_ARRAY_INPUT;
+}
+
 static inline int monitor_has_error(const Monitor *mon)
 {
     return mon->error != NULL;
@@ -671,6 +680,12 @@ static int qmp_async_cmd_handler(Monitor *mon, const 
mon_cmd_t *cmd,
     return cmd->mhandler.cmd_async(mon, params, qmp_monitor_complete, mon);
 }
 
+static int qmp_async_cmd_handler_array(Monitor *mon, const mon_cmd_t *cmd,
+                                 const QList *params)
+{
+    return cmd->mhandler.cmd_async_list(mon, params, qmp_monitor_complete, 
mon);
+}
+
 static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
                                    const QDict *params)
 {
@@ -4310,7 +4325,8 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
             }
             has_exec_key = 1;
         } else if (!strcmp(arg_name, "arguments")) {
-            if (qobject_type(arg_obj) != QTYPE_QDICT) {
+            if ((qobject_type(arg_obj) != QTYPE_QDICT) &&
+                (qobject_type(arg_obj) != QTYPE_QLIST)) {
                 qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments",
                               "object");
                 return NULL;
@@ -4345,11 +4361,26 @@ static void qmp_call_cmd(Monitor *mon, const mon_cmd_t 
*cmd,
     qobject_decref(data);
 }
 
+static void qmp_call_cmd_array(Monitor *mon, const mon_cmd_t *cmd,
+                              const QList *params)
+{
+    int ret;
+    QObject *data = NULL;
+
+    mon_print_count_init(mon);
+
+    ret = cmd->mhandler.cmd_new_list(mon, params, &data);
+    handler_audit(mon, cmd, ret);
+    monitor_protocol_emitter(mon, data);
+    qobject_decref(data);
+}
+
 static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
 {
     int err;
     QObject *obj;
     QDict *input, *args;
+    QList *args_list = NULL;
     const mon_cmd_t *cmd;
     const char *cmd_name;
     Monitor *mon = cur_mon;
@@ -4386,26 +4417,42 @@ static void handle_qmp_command(JSONMessageParser 
*parser, QList *tokens)
     }
 
     obj = qdict_get(input, "arguments");
-    if (!obj) {
-        args = qdict_new();
+    if (handler_accepts_array(cmd)) {
+        if (!obj || (qobject_type(obj) != QTYPE_QLIST)) {
+            args_list = qlist_new();
+        } else {
+            args_list = qobject_to_qlist(obj);
+            QINCREF(args_list);
+        }
     } else {
-        args = qobject_to_qdict(obj);
-        QINCREF(args);
-    }
-
-    err = qmp_check_client_args(cmd, args);
-    if (err < 0) {
-        goto err_out;
+        if (!obj || (qobject_type(obj) != QTYPE_QDICT)) {
+            args = qdict_new();
+        } else {
+            args = qobject_to_qdict(obj);
+            QINCREF(args);
+        }
+        err = qmp_check_client_args(cmd, args);
+        if (err < 0) {
+            goto err_out;
+        }
     }
 
     if (handler_is_async(cmd)) {
-        err = qmp_async_cmd_handler(mon, cmd, args);
+        if (handler_accepts_array(cmd)) {
+            err = qmp_async_cmd_handler_array(mon, cmd, args_list);
+        } else {
+            err = qmp_async_cmd_handler(mon, cmd, args);
+        }
         if (err) {
             /* emit the error response */
             goto err_out;
         }
     } else {
-        qmp_call_cmd(mon, cmd, args);
+        if (handler_accepts_array(cmd)) {
+            qmp_call_cmd_array(mon, cmd, args_list);
+        } else {
+            qmp_call_cmd(mon, cmd, args);
+        }
     }
 
     goto out;
@@ -4415,6 +4462,7 @@ err_out:
 out:
     QDECREF(input);
     QDECREF(args);
+    QDECREF(args_list);
 }
 
 /**
diff --git a/monitor.h b/monitor.h
index b72ea07..499fc1f 100644
--- a/monitor.h
+++ b/monitor.h
@@ -19,6 +19,7 @@ extern Monitor *default_mon;
 
 /* flags for monitor commands */
 #define MONITOR_CMD_ASYNC       0x0001
+#define MONITOR_CMD_ARRAY_INPUT 0x0002
 
 /* QMP events */
 typedef enum MonitorEvent {
-- 
1.7.9.rc2.1.g69204




reply via email to

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