]> git.proxmox.com Git - qemu.git/commitdiff
monitor: New argument type 'O'
authorMarkus Armbruster <armbru@redhat.com>
Wed, 10 Feb 2010 19:24:35 +0000 (20:24 +0100)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 16 Mar 2010 16:45:35 +0000 (17:45 +0100)
In the human monitor, it declares a single optional argument to be
parsed according to the QemuOptsList given by its name.

In QMP, it declares an optional argument for each member of the
QemuOptsList.

Restriction: only lists with empty desc are supported for now.  Good
enough for the job at hand.  We'll lift the restriction when we need
that.

monitor.c

index 76c909c04d17c142f9851299c291ed3643c24563..f0ec84d52f4f16d5d13a2cdf04c55444bc581cf8 100644 (file)
--- a/monitor.c
+++ b/monitor.c
  * 'F'          filename
  * 'B'          block device name
  * 's'          string (accept optional quote)
+ * 'O'          option string of the form NAME=VALUE,...
+ *              parsed according to QemuOptsList given by its name
+ *              Example: 'device:O' uses qemu_device_opts.
+ *              Restriction: only lists with empty desc are supported
+ *              TODO lift the restriction
  * 'i'          32 bit integer
  * 'l'          target long (32 or 64 bit)
  * 'M'          just like 'l', except in user mode the value is
@@ -3645,6 +3650,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
                 qdict_put(qdict, key, qstring_from_str(buf));
             }
             break;
+        case 'O':
+            {
+                QemuOptsList *opts_list;
+                QemuOpts *opts;
+
+                opts_list = qemu_find_opts(key);
+                if (!opts_list || opts_list->desc->name) {
+                    goto bad_type;
+                }
+                while (qemu_isspace(*p)) {
+                    p++;
+                }
+                if (!*p)
+                    break;
+                if (get_str(buf, sizeof(buf), &p) < 0) {
+                    goto fail;
+                }
+                opts = qemu_opts_parse(opts_list, buf, 1);
+                if (!opts) {
+                    goto fail;
+                }
+                qemu_opts_to_qdict(opts, qdict);
+                qemu_opts_del(opts);
+            }
+            break;
         case '/':
             {
                 int count, format, size;
@@ -4299,6 +4329,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
                          qint_from_int(qbool_get_int(qobject_to_qbool(value))));
             }
             break;
+        case 'O':
         default:
             /* impossible */
             abort();
@@ -4313,6 +4344,12 @@ static void cmd_args_init(CmdArgs *cmd_args)
     cmd_args->type = cmd_args->flag = cmd_args->optional = 0;
 }
 
+static int check_opts(QemuOptsList *opts_list, QDict *args)
+{
+    assert(!opts_list->desc->name);
+    return 0;
+}
+
 /*
  * This is not trivial, we have to parse Monitor command's argument
  * type syntax to be able to check the arguments provided by clients.
@@ -4325,6 +4362,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
     int err;
     const char *p;
     CmdArgs cmd_args;
+    QemuOptsList *opts_list;
 
     if (cmd->args_type == NULL) {
         return (qdict_size(args) == 0 ? 0 : -1);
@@ -4332,6 +4370,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
 
     err = 0;
     cmd_args_init(&cmd_args);
+    opts_list = NULL;
 
     for (p = cmd->args_type;; p++) {
         if (*p == ':') {
@@ -4340,16 +4379,23 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
             if (cmd_args.type == '-') {
                 cmd_args.flag = *p++;
                 cmd_args.optional = 1;
+            } else if (cmd_args.type == 'O') {
+                opts_list = qemu_find_opts(qstring_get_str(cmd_args.name));
+                assert(opts_list);
             } else if (*p == '?') {
                 cmd_args.optional = 1;
                 p++;
             }
 
             assert(*p == ',' || *p == '\0');
-            err = check_arg(&cmd_args, args);
-
-            QDECREF(cmd_args.name);
-            cmd_args_init(&cmd_args);
+            if (opts_list) {
+                err = check_opts(opts_list, args);
+                opts_list = NULL;
+            } else {
+                err = check_arg(&cmd_args, args);
+                QDECREF(cmd_args.name);
+                cmd_args_init(&cmd_args);
+            }
 
             if (err < 0) {
                 break;