]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Allow setting boot menu on/off
authorCole Robinson <crobinso@redhat.com>
Mon, 26 Jul 2010 14:28:58 +0000 (10:28 -0400)
committerCole Robinson <crobinso@redhat.com>
Tue, 27 Jul 2010 20:38:32 +0000 (16:38 -0400)
Add a new element to the <os> block:

  <bootmenu enable="yes|no"/>

Which maps to -boot,menu=on|off on the QEMU command line.

I decided to use an explicit 'enable' attribute rather than just make the
bootmenu element boolean. This allows us to treat lack of a bootmenu element
as 'use hypervisor default'.

13 files changed:
docs/formatdomain.html.in
docs/schemas/domain.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_conf.c
src/qemu/qemu_conf.h
tests/qemuhelptest.c
tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmltest.c

index 3e803125707c9f86f0a0ad0042c196861467e653..c79b6065781d5fd0ae723acdfcaf9deb4bc904a9 100644 (file)
@@ -79,6 +79,8 @@
     &lt;type&gt;hvm&lt;/type&gt;
     &lt;loader&gt;/usr/lib/xen/boot/hvmloader&lt;/loader&gt;
     &lt;boot dev='hd'/&gt;
+    &lt;boot dev='cdrom'/&gt;
+    &lt;bootmenu enable='yes'/&gt;
   &lt;/os&gt;
   ...</pre>
 
         times to setup a priority list of boot devices to try in turn.
         <span class="since">Since 0.1.3</span>
       </dd>
+      <dt><code>bootmenu</code></dt>
+      <dd> Whether or not to enable an interactive boot menu prompt on guest
+      startup. The <code>enable</code> attribute can be either "yes" or "no".
+      If not specified, the hypervisor default is used. <span class="since">
+      Since 0.8.3</span>
+      </dd>
     </dl>
 
     <h4><a name="elementsOSBootloader">Host bootloader</a></h4>
index 2d22ce4028d3bb345974d81cc3a41cd17b146f7b..f36bb1fa9f1eea51116ea0344382ac0ba26c47c9 100644 (file)
             <ref name="osbootdev"/>
           </oneOrMore>
         </choice>
+        <optional>
+          <element name="bootmenu">
+            <attribute name="enable">
+              <choice>
+                <value>yes</value>
+                <value>no</value>
+              </choice>
+            </attribute>
+          </element>
+        </optional>
       </interleave>
     </element>
   </define>
index 5b59c0143a9fb76192e71efdf123c64709730563..dc775e8b5907ab893d52064f3285828cca7c7716 100644 (file)
@@ -4300,6 +4300,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
     }
 
     if (STREQ(def->os.type, "hvm")) {
+        char *bootstr;
+
         /* analysis of the boot devices */
         if ((n = virXPathNodeSet("./os/boot", ctxt, &nodes)) < 0) {
             virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4329,6 +4331,15 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
             def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
         }
         VIR_FREE(nodes);
+
+        bootstr = virXPathString("string(./os/bootmenu[1]/@enable)", ctxt);
+        if (bootstr) {
+            if (STREQ(bootstr, "yes"))
+                def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_ENABLED;
+            else
+                def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_DISABLED;
+            VIR_FREE(bootstr);
+        }
     }
 
     def->emulator = virXPathString("string(./devices/emulator[1])", ctxt);
@@ -6275,6 +6286,13 @@ char *virDomainDefFormat(virDomainDefPtr def,
             }
             virBufferVSprintf(&buf, "    <boot dev='%s'/>\n", boottype);
         }
+
+        if (def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) {
+            const char *enabled = (def->os.bootmenu ==
+                                   VIR_DOMAIN_BOOT_MENU_ENABLED ? "yes"
+                                                                : "no");
+            virBufferVSprintf(&buf, "    <bootmenu enable='%s'/>\n", enabled);
+        }
     }
 
     virBufferAddLit(&buf, "  </os>\n");
index 9ef687b4c38755819911e79639d781f66a7f676f..afd172f041a2492a1754fc7e2022683f0a839e3d 100644 (file)
@@ -615,7 +615,6 @@ struct _virDomainDeviceDef {
 
 # define VIR_DOMAIN_MAX_BOOT_DEVS 4
 
-/* 3 possible boot devices */
 enum virDomainBootOrder {
     VIR_DOMAIN_BOOT_FLOPPY,
     VIR_DOMAIN_BOOT_CDROM,
@@ -625,6 +624,12 @@ enum virDomainBootOrder {
     VIR_DOMAIN_BOOT_LAST,
 };
 
+enum virDomainBootMenu {
+    VIR_DOMAIN_BOOT_MENU_DEFAULT = 0,
+    VIR_DOMAIN_BOOT_MENU_ENABLED,
+    VIR_DOMAIN_BOOT_MENU_DISABLED,
+};
+
 enum virDomainFeature {
     VIR_DOMAIN_FEATURE_ACPI,
     VIR_DOMAIN_FEATURE_APIC,
@@ -651,6 +656,7 @@ struct _virDomainOSDef {
     char *machine;
     int nBootDevs;
     int bootDevs[VIR_DOMAIN_BOOT_LAST];
+    int bootmenu;
     char *init;
     char *kernel;
     char *initrd;
index 05ad67de6de9f65757677994cb2831c0a9baf289..84f4e6f6c090a487a720e9245acf867d0e4e6df9 100644 (file)
@@ -1205,6 +1205,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
         flags |= QEMUD_CMD_FLAG_NO_KVM_PIT;
     if (strstr(help, "-tdf"))
         flags |= QEMUD_CMD_FLAG_TDF;
+    if (strstr(help, ",menu=on"))
+        flags |= QEMUD_CMD_FLAG_BOOT_MENU;
 
     /* Keep disabled till we're actually ready to turn on netdev mode
      * The plan is todo it in 0.13.0 QEMU, but lets wait & see... */
@@ -4078,9 +4080,27 @@ int qemudBuildCommandLine(virConnectPtr conn,
             }
         }
         if (def->os.nBootDevs) {
-            boot[def->os.nBootDevs] = '\0';
+            virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
             ADD_ARG_LIT("-boot");
-            ADD_ARG_LIT(boot);
+
+            boot[def->os.nBootDevs] = '\0';
+
+            if (qemuCmdFlags & QEMUD_CMD_FLAG_BOOT_MENU &&
+                def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) {
+                if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED)
+                    virBufferVSprintf(&boot_buf, "order=%s,menu=on", boot);
+                else if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_DISABLED)
+                    virBufferVSprintf(&boot_buf, "order=%s,menu=off", boot);
+            } else {
+                virBufferVSprintf(&boot_buf, "%s", boot);
+            }
+
+            if (virBufferError(&boot_buf)) {
+                virReportOOMError();
+                goto error;
+            }
+
+            ADD_ARG_LIT(virBufferContentAndReset(&boot_buf));
         }
 
         if (def->os.kernel) {
@@ -6207,8 +6227,13 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
                     def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM;
                 else if (val[n] == 'n')
                     def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET;
+                else if (val[n] == ',')
+                    break;
             }
             def->os.nBootDevs = b;
+
+            if (strstr(val, "menu=on"))
+                def->os.bootmenu = 1;
         } else if (STREQ(arg, "-name")) {
             WANT_VALUE();
             if (!(def->name = strdup(val)))
index 8c17e26c4b5a9a069834cba2d6d1e74610cb47b7..1aa9d2e6dc6dc35835d88fe5c415ca9d456920ed 100644 (file)
@@ -91,6 +91,7 @@ enum qemud_cmd_flags {
     QEMUD_CMD_FLAG_TDF           = (1LL << 35), /* -tdf flag (user-mode pit catchup) */
     QEMUD_CMD_FLAG_PCI_CONFIGFD  = (1LL << 36), /* pci-assign.configfd */
     QEMUD_CMD_FLAG_NODEFCONFIG   = (1LL << 37), /* -nodefconfig */
+    QEMUD_CMD_FLAG_BOOT_MENU     = (1LL << 38), /* -boot menu=on support */
 };
 
 /* Main driver state */
index 517a8fe0017fbe80fba8eb25db6df7474e7b422d..56a49fd130386c1559683d4efbfe0119e14c1d6b 100644 (file)
@@ -220,7 +220,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_RTC_TD_HACK |
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
-            QEMUD_CMD_FLAG_TDF,
+            QEMUD_CMD_FLAG_TDF |
+            QEMUD_CMD_FLAG_BOOT_MENU,
             10092, 1,  0);
     DO_TEST("qemu-0.12.1",
             QEMUD_CMD_FLAG_VNC_COLON |
@@ -244,7 +245,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_DEVICE |
             QEMUD_CMD_FLAG_SMP_TOPOLOGY |
             QEMUD_CMD_FLAG_RTC |
-            QEMUD_CMD_FLAG_NO_HPET,
+            QEMUD_CMD_FLAG_NO_HPET |
+            QEMUD_CMD_FLAG_BOOT_MENU,
             12001, 0,  0);
     DO_TEST("qemu-kvm-0.12.3",
             QEMUD_CMD_FLAG_VNC_COLON |
@@ -274,7 +276,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_VNET_HOST |
             QEMUD_CMD_FLAG_NO_HPET |
             QEMUD_CMD_FLAG_NO_KVM_PIT |
-            QEMUD_CMD_FLAG_TDF,
+            QEMUD_CMD_FLAG_TDF |
+            QEMUD_CMD_FLAG_BOOT_MENU,
             12003, 1,  0);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args
new file mode 100644 (file)
index 0000000..ec47281
--- /dev/null
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot order=d,menu=off -cdrom /dev/cdrom -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml
new file mode 100644 (file)
index 0000000..ceb109c
--- /dev/null
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='cdrom'/>
+    <bootmenu enable='no'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='cdrom'>
+      <source dev='/dev/cdrom'/>
+      <target dev='hdc' bus='ide'/>
+      <readonly/>
+      <address type='drive' controller='0' bus='1' unit='0'/>
+    </disk>
+    <controller type='ide' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args
new file mode 100644 (file)
index 0000000..e67f2a1
--- /dev/null
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot order=dcna,menu=on -cdrom /dev/cdrom -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml
new file mode 100644 (file)
index 0000000..48f27aa
--- /dev/null
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='cdrom'/>
+    <boot dev='hd'/>
+    <boot dev='network'/>
+    <boot dev='fd'/>
+    <bootmenu enable='yes'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='cdrom'>
+      <source dev='/dev/cdrom'/>
+      <target dev='hdc' bus='ide'/>
+      <readonly/>
+      <address type='drive' controller='0' bus='1' unit='0'/>
+    </disk>
+    <controller type='ide' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 3d6c583029048ad15049c5b4b99429e4191620e1..0ca98042c2a8481943bb2ad8f15008e097c352dc 100644 (file)
@@ -223,6 +223,8 @@ mymain(int argc, char **argv)
     DO_TEST("boot-cdrom", 0);
     DO_TEST("boot-network", 0);
     DO_TEST("boot-floppy", 0);
+    DO_TEST("boot-multi", QEMUD_CMD_FLAG_BOOT_MENU);
+    DO_TEST("boot-menu-disable", QEMUD_CMD_FLAG_BOOT_MENU);
     DO_TEST("bootloader", QEMUD_CMD_FLAG_DOMID);
     DO_TEST("clock-utc", 0);
     DO_TEST("clock-localtime", 0);
index 69829b1b72a7502eb419e5fcdc4c16e0167f92e5..00b3a1b188b379ab8c1875156627bda905bd9660 100644 (file)
@@ -89,6 +89,8 @@ mymain(int argc, char **argv)
     DO_TEST("boot-cdrom");
     DO_TEST("boot-network");
     DO_TEST("boot-floppy");
+    DO_TEST("boot-multi");
+    DO_TEST("boot-menu-disable");
     DO_TEST("bootloader");
     DO_TEST("clock-utc");
     DO_TEST("clock-localtime");