Patchwork [3/4] Add -defaults option to allow default devices to be overridden

login
register
mail settings
Submitter Anthony Liguori
Date Jan. 21, 2010, 6:48 p.m.
Message ID <1264099733-29666-4-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/43445/
State New
Headers show

Comments

Anthony Liguori - Jan. 21, 2010, 6:48 p.m.
This option can be used to toggle whether each default device is enabled or
disabled.  For character devices, the default backend can also be overridden.

For devices, we'll have to take a different approach to changing the defaults
which will be covered in the next patch.

N.B. I took special care with -nographic.  Now -nographic pretty clearly acts
as a mechanism to override the default backend devices.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qemu-config.c   |   45 +++++++++++++++++++++++++++++++++
 qemu-config.h   |    1 +
 qemu-options.hx |    7 +++++
 vl.c            |   75 +++++++++++++++++++++++++++++++++++++++++--------------
 4 files changed, 109 insertions(+), 19 deletions(-)
Markus Armbruster - Jan. 22, 2010, 10:15 a.m.
Anthony Liguori <aliguori@us.ibm.com> writes:

> This option can be used to toggle whether each default device is enabled or
> disabled.  For character devices, the default backend can also be overridden.
>
> For devices, we'll have to take a different approach to changing the defaults
> which will be covered in the next patch.
>
> N.B. I took special care with -nographic.  Now -nographic pretty clearly acts
> as a mechanism to override the default backend devices.
>
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  qemu-config.c   |   45 +++++++++++++++++++++++++++++++++
>  qemu-config.h   |    1 +
>  qemu-options.hx |    7 +++++
>  vl.c            |   75 +++++++++++++++++++++++++++++++++++++++++--------------
>  4 files changed, 109 insertions(+), 19 deletions(-)
>
> diff --git a/qemu-config.c b/qemu-config.c
> index c3203c8..82ca399 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -242,6 +242,50 @@ QemuOptsList qemu_mon_opts = {
>      },
>  };
>  
> +QemuOptsList qemu_default_opts = {
> +    .name = "default",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_default_opts.head),
> +    .desc = {
> +        {
> +            .name = "serial",
> +            .type = QEMU_OPT_STRING,
> +        },
[...]
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 57f453d..e81ecb5 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1919,6 +1919,13 @@ STEXI
>  Don't create default devices.
>  ETEXI
>  
> +DEF("default", HAS_ARG, QEMU_OPTION_default, \
> +    "-default arg    specify default devices\n")

Isn't this too terse?

> +STEXI
> +@item -defaults
> +Override builtin default devices
> +ETEXI

This *is* too terse :)

Oh, and it's -default (sans 's').  Same typo in subject.

While we're talking about naming: isn't -default a bit too generic a
name for something that manipulates devices?  Not sure we care, as
-nodefaults is much worse, already.

[...]
Anthony Liguori - Jan. 22, 2010, 3:45 p.m.
On 01/22/2010 04:15 AM, Markus Armbruster wrote:
> Anthony Liguori<aliguori@us.ibm.com>  writes:
>
>    
>> This option can be used to toggle whether each default device is enabled or
>> disabled.  For character devices, the default backend can also be overridden.
>>
>> For devices, we'll have to take a different approach to changing the defaults
>> which will be covered in the next patch.
>>
>> N.B. I took special care with -nographic.  Now -nographic pretty clearly acts
>> as a mechanism to override the default backend devices.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>>   qemu-config.c   |   45 +++++++++++++++++++++++++++++++++
>>   qemu-config.h   |    1 +
>>   qemu-options.hx |    7 +++++
>>   vl.c            |   75 +++++++++++++++++++++++++++++++++++++++++--------------
>>   4 files changed, 109 insertions(+), 19 deletions(-)
>>
>> diff --git a/qemu-config.c b/qemu-config.c
>> index c3203c8..82ca399 100644
>> --- a/qemu-config.c
>> +++ b/qemu-config.c
>> @@ -242,6 +242,50 @@ QemuOptsList qemu_mon_opts = {
>>       },
>>   };
>>
>> +QemuOptsList qemu_default_opts = {
>> +    .name = "default",
>> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_default_opts.head),
>> +    .desc = {
>> +        {
>> +            .name = "serial",
>> +            .type = QEMU_OPT_STRING,
>> +        },
>>      
> [...]
>    
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index 57f453d..e81ecb5 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -1919,6 +1919,13 @@ STEXI
>>   Don't create default devices.
>>   ETEXI
>>
>> +DEF("default", HAS_ARG, QEMU_OPTION_default, \
>> +    "-default arg    specify default devices\n")
>>      
> Isn't this too terse?
>    

Yes.  Thanks for pointing that out.

>> +STEXI
>> +@item -defaults
>> +Override builtin default devices
>> +ETEXI
>>      
> This *is* too terse :)
>
> Oh, and it's -default (sans 's').  Same typo in subject.
>
> While we're talking about naming: isn't -default a bit too generic a
> name for something that manipulates devices?  Not sure we care, as
> -nodefaults is much worse, already.
>    

Absolutely.  I'm going to split out the config loading bits because they 
should be easy to commit.  How to best handle defaults could use some 
more thought.  I think this is a key bit of functionality to get right 
though because it solves a whole class of problems relating to upstream 
policy vs. downstream policy.

I very much like the idea of having a qdev property 'default' to signify 
that this is a default device.  It means we could easily allow a user to 
universally enable usb devices, etc without baking a default_usb concept 
into qemu.  Ideally, we could eliminate the whole default mess we have 
today by doing this, provided that we can implement the right semantics.

Today, those semantics are, if we specify any device of the same 
"class", do not load default devices of that class.  It's unclear how to 
specify the concept of a "class" though.  I know Gerd brought this up 
ages ago and both Paul and I were very opposed to it but I certainly 
appreciate the fact that it would simplify default device handling.

It's definitely clear that each device needs to be able to be part of 
multiple default-class's.  We could potentially introduce a qdev 
property and label every device with a class array but that's a lot of 
ugliness just to support defaults.  I still would prefer that there was 
a more discoverable way to determine the class of a device as opposed to 
explicitly labelling it.

If we need to do class tagging, I guess it's not the end of the world...

Regards,

Anthony Liguori

> [...]
>

Patch

diff --git a/qemu-config.c b/qemu-config.c
index c3203c8..82ca399 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -242,6 +242,50 @@  QemuOptsList qemu_mon_opts = {
     },
 };
 
+QemuOptsList qemu_default_opts = {
+    .name = "default",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_default_opts.head),
+    .desc = {
+        {
+            .name = "serial",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "parallel",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "virtcon",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "monitor",
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = "vga",
+            .type = QEMU_OPT_BOOL,
+        },
+        {
+            .name = "net",
+            .type = QEMU_OPT_BOOL,
+        },
+        {
+            .name = "floppy",
+            .type = QEMU_OPT_BOOL,
+        },
+        {
+            .name = "cdrom",
+            .type = QEMU_OPT_BOOL,
+        },
+        {
+            .name = "sdcard",
+            .type = QEMU_OPT_BOOL,
+        },
+        { /* end if list */ }
+    },
+};
+
 static QemuOptsList *lists[] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -250,6 +294,7 @@  static QemuOptsList *lists[] = {
     &qemu_net_opts,
     &qemu_rtc_opts,
     &qemu_global_opts,
+    &qemu_default_opts,
     &qemu_mon_opts,
     NULL,
 };
diff --git a/qemu-config.h b/qemu-config.h
index dd89ae4..14ed67b 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -9,6 +9,7 @@  extern QemuOptsList qemu_net_opts;
 extern QemuOptsList qemu_rtc_opts;
 extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
+extern QemuOptsList qemu_default_opts;
 
 int qemu_set_option(const char *str);
 int qemu_global_option(const char *str);
diff --git a/qemu-options.hx b/qemu-options.hx
index 57f453d..e81ecb5 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1919,6 +1919,13 @@  STEXI
 Don't create default devices.
 ETEXI
 
+DEF("default", HAS_ARG, QEMU_OPTION_default, \
+    "-default arg    specify default devices\n")
+STEXI
+@item -defaults
+Override builtin default devices
+ETEXI
+
 #ifndef _WIN32
 DEF("chroot", HAS_ARG, QEMU_OPTION_chroot, \
     "-chroot dir     chroot to dir just before starting the VM\n")
diff --git a/vl.c b/vl.c
index cf12ab0..6a3529e 100644
--- a/vl.c
+++ b/vl.c
@@ -280,6 +280,11 @@  static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
 
+static const char *default_serial_opt = "vc:80Cx24C";
+static const char *default_parallel_opt = "vc:80Cx24C";
+static const char *default_monitor_opt = "vc:80Cx24C";
+static const char *default_virtcon_opt = "vc:80Cx24C";
+
 static struct {
     const char *driver;
     int *flag;
@@ -4658,6 +4663,32 @@  static int debugcon_parse(const char *devname)
     return 0;
 }
 
+static int default_opt_init(QemuOpts *opts, void *dummy)
+{
+    const char *opt;
+
+    if ((opt = qemu_opt_get(opts, "serial"))) {
+        default_serial_opt = opt;
+    }
+    if ((opt = qemu_opt_get(opts, "parallel"))) {
+        default_parallel_opt = opt;
+    }
+    if ((opt = qemu_opt_get(opts, "virtcon"))) {
+        default_virtcon_opt = opt;
+    }
+    if ((opt = qemu_opt_get(opts, "monitor"))) {
+        default_monitor_opt = opt;
+    }
+
+    default_vga = qemu_opt_get_bool(opts, "vga", default_vga);
+    default_net = qemu_opt_get_bool(opts, "net", default_net);
+    default_floppy = qemu_opt_get_bool(opts, "floppy", default_floppy);
+    default_cdrom = qemu_opt_get_bool(opts, "cdrom", default_cdrom);
+    default_sdcard = qemu_opt_get_bool(opts, "sdcard", default_sdcard);
+
+    return 0;
+}
+
 int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
@@ -5409,6 +5440,13 @@  int main(int argc, char **argv, char **envp)
                 default_cdrom = 0;
                 default_sdcard = 0;
                 break;
+            case QEMU_OPTION_default:
+                opts = qemu_opts_parse(&qemu_default_opts, optarg, NULL);
+                if (!opts) {
+                    fprintf(stderr, "parse error: %s\n", optarg);
+                    exit(1);
+                }
+                break;
 #ifndef _WIN32
             case QEMU_OPTION_chroot:
                 chroot_dir = optarg;
@@ -5509,6 +5547,7 @@  int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    qemu_opts_foreach(&qemu_default_opts, default_opt_init, NULL, 0);
     qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0);
     qemu_opts_foreach(&qemu_global_opts, default_driver_check, NULL, 0);
 
@@ -5535,30 +5574,28 @@  int main(int argc, char **argv, char **envp)
     }
 
     if (display_type == DT_NOGRAPHIC) {
-        if (default_parallel)
-            add_device_config(DEV_PARALLEL, "null");
+        default_parallel_opt = "null";
+
         if (default_serial && default_monitor) {
-            add_device_config(DEV_SERIAL, "mon:stdio");
+            default_serial_opt = "mon:stdio";
         } else if (default_virtcon && default_monitor) {
-            add_device_config(DEV_VIRTCON, "mon:stdio");
+            default_virtcon_opt = "mon:stdio";
         } else {
-            if (default_serial)
-                add_device_config(DEV_SERIAL, "stdio");
-            if (default_virtcon)
-                add_device_config(DEV_VIRTCON, "stdio");
-            if (default_monitor)
-                monitor_parse("stdio", "readline");
+            default_serial_opt = "stdio";
+            default_virtcon_opt = "stdio";
+            default_monitor_opt = "stdio";
         }
-    } else {
-        if (default_serial)
-            add_device_config(DEV_SERIAL, "vc:80Cx24C");
-        if (default_parallel)
-            add_device_config(DEV_PARALLEL, "vc:80Cx24C");
-        if (default_monitor)
-            monitor_parse("vc:80Cx24C", "readline");
-        if (default_virtcon)
-            add_device_config(DEV_VIRTCON, "vc:80Cx24C");
     }
+
+    if (default_serial)
+        add_device_config(DEV_SERIAL, default_serial_opt);
+    if (default_parallel)
+        add_device_config(DEV_PARALLEL, default_parallel_opt);
+    if (default_monitor)
+        monitor_parse(default_monitor_opt, "readline");
+    if (default_virtcon)
+        add_device_config(DEV_VIRTCON, default_virtcon_opt);
+
     if (default_vga)
         vga_interface_type = VGA_CIRRUS;