commit d0fef6fbea36c62d29f3e3fa2214b7b52322983e
Author: Gerd Hoffmann <kraxel@redhat.com>
Date:   Tue Dec 8 13:11:34 2009 +0100

    qdev: add command line option to set global defaults for properties.
    
    This patch adds infrastructure and command line option for setting
    global defaults for device properties, i.e. you can for example use
    
      -global virtio-blk-pci.vectors=0
    
    to turn off msi by default for all virtio block devices.  The config
    file syntax is:
    
    [global]
      driver = "virtio-blk-pci"
      property = "vectors"
      value = "0"
    
    This can also be used to set properties for devices which are not
    created via -device but implicitly via machine init, i.e.
    
      -global isa-fdc,driveA=<name>
    
    This patch uses the mechanism which configures properties for the
    compatibility machine types (pc-0.10 & friends).  The command line
    takes precedence over the machine type values.
    
    Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
    Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu-config.c b/qemu-config.c
index 92b5363..a23b125 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -2,6 +2,7 @@
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "sysemu.h"
+#include "hw/qdev.h"
 
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
@@ -205,6 +206,24 @@ QemuOptsList qemu_rtc_opts = {
     },
 };
 
+QemuOptsList qemu_global_opts = {
+    .name = "global",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head),
+    .desc = {
+        {
+            .name = "driver",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "property",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "value",
+            .type = QEMU_OPT_STRING,
+        },
+        { /* end if list */ }
+    },
+};
+
 static QemuOptsList *lists[] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -212,6 +231,7 @@ static QemuOptsList *lists[] = {
     &qemu_netdev_opts,
     &qemu_net_opts,
     &qemu_rtc_opts,
+    &qemu_global_opts,
     NULL,
 };
 
@@ -260,6 +280,42 @@ int qemu_set_option(const char *str)
     return 0;
 }
 
+int qemu_global_option(const char *str)
+{
+    char driver[64], property[64];
+    QemuOpts *opts;
+    int rc, offset;
+
+    rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
+    if (rc < 2 || str[offset] != '=') {
+        qemu_error("can't parse: \"%s\"\n", str);
+        return -1;
+    }
+
+    opts = qemu_opts_create(&qemu_global_opts, NULL, 0);
+    qemu_opt_set(opts, "driver", driver);
+    qemu_opt_set(opts, "property", property);
+    qemu_opt_set(opts, "value", str+offset+1);
+    return 0;
+}
+
+static int qemu_add_one_global(QemuOpts *opts, void *opaque)
+{
+    GlobalProperty *g;
+
+    g = qemu_mallocz(sizeof(*g));
+    g->driver   = qemu_opt_get(opts, "driver");
+    g->property = qemu_opt_get(opts, "property");
+    g->value    = qemu_opt_get(opts, "value");
+    qdev_prop_register_global(g);
+    return 0;
+}
+
+void qemu_add_globals(void)
+{
+    qemu_opts_foreach(&qemu_global_opts, qemu_add_one_global, NULL, 0);
+}
+
 struct ConfigWriteData {
     QemuOptsList *list;
     FILE *fp;
diff --git a/qemu-config.h b/qemu-config.h
index b564851..6246e76 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -9,6 +9,8 @@ extern QemuOptsList qemu_net_opts;
 extern QemuOptsList qemu_rtc_opts;
 
 int qemu_set_option(const char *str);
+int qemu_global_option(const char *str);
+void qemu_add_globals(void);
 
 void qemu_config_write(FILE *fp);
 int qemu_config_parse(FILE *fp);
diff --git a/qemu-options.hx b/qemu-options.hx
index 1b5781a..b6f3075 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -109,6 +109,9 @@ DEF("set", HAS_ARG, QEMU_OPTION_set,
     "-set group.id.arg=value\n"
     "                set <arg> parameter for item <id> of type <group>\n"
     "                i.e. -set drive.$id.file=/path/to/image\n")
+DEF("global", HAS_ARG, QEMU_OPTION_global,
+    "-global driver.property=value\n"
+    "                set a global default for a driver property\n")
 STEXI
 @item -drive @var{option}[,@var{option}[,@var{option}[,...]]]
 
diff --git a/vl.c b/vl.c
index a242a11..f7acdd4 100644
--- a/vl.c
+++ b/vl.c
@@ -4851,6 +4851,10 @@ int main(int argc, char **argv, char **envp)
                 if (qemu_set_option(optarg) != 0)
                     exit(1);
 	        break;
+            case QEMU_OPTION_global:
+                if (qemu_global_option(optarg) != 0)
+                    exit(1);
+	        break;
             case QEMU_OPTION_mtdblock:
                 drive_add(optarg, MTD_ALIAS);
                 break;
@@ -5781,6 +5785,8 @@ int main(int argc, char **argv, char **envp)
     if (machine->compat_props) {
         qdev_prop_register_global_list(machine->compat_props);
     }
+    qemu_add_globals();
+
     machine->init(ram_size, boot_devices,
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
 
