From cdbb21bc590fc687b1eb58ab9f3d0c9a9ec14e8f Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 12 Nov 2014 17:31:53 -0500 Subject: [PATCH] drvbhyve: Use boot-order for grub-bhyve boot device Rather than just picking the first CD (or failing that, HDD) we come across, if the user has picked a boot device ordering with , respect that (and just try to boot the lowest-index device). Adds two sets of tests to bhyve2xmlargv; 'grub-bootorder' shows that we pick a user-specified device over the first device in the domain; 'grub-bootorder2' shows that we pick the first (lowest index) device. --- docs/drvbhyve.html.in | 9 +-- src/bhyve/bhyve_command.c | 68 +++++++++++++------ .../bhyvexml2argv-grub-bootorder.args | 6 ++ .../bhyvexml2argv-grub-bootorder.devmap | 1 + .../bhyvexml2argv-grub-bootorder.ldargs | 2 + .../bhyvexml2argv-grub-bootorder.xml | 36 ++++++++++ .../bhyvexml2argv-grub-bootorder2.args | 6 ++ .../bhyvexml2argv-grub-bootorder2.devmap | 1 + .../bhyvexml2argv-grub-bootorder2.ldargs | 2 + .../bhyvexml2argv-grub-bootorder2.xml | 38 +++++++++++ tests/bhyvexml2argvtest.c | 2 + 11 files changed, 148 insertions(+), 23 deletions(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.devmap create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.devmap create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.xml diff --git a/docs/drvbhyve.html.in b/docs/drvbhyve.html.in index bd4b35eb1e..5479511e4b 100644 --- a/docs/drvbhyve.html.in +++ b/docs/drvbhyve.html.in @@ -234,10 +234,11 @@ management.

It's possible to boot non-FreeBSD guests by specifying an explicit bootloader, e.g. grub-bhyve(1). Arguments to the bootloader may be specified as well. If the bootloader is grub-bhyve and arguments -are omitted, libvirt will try and boot the first disk in the domain (either -cdrom- or disk-type devices). If the disk type is -disk, it will attempt to boot from the first partition in the disk -image.

+are omitted, libvirt will try and infer boot ordering from user-supplied +<boot order='N'> configuration in the domain. Failing that, it will boot +the first disk in the domain (either cdrom- or +disk-type devices). If the disk type is disk, it will +attempt to boot from the first partition in the disk image.

   ...
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 26d4797465..6e3bf0357b 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -381,38 +381,62 @@ virBhyveUsableDisk(virConnectPtr conn, virDomainDiskDefPtr disk)
     return true;
 }
 
+static void
+virBhyveFormatGrubDevice(virBufferPtr devicemap, virDomainDiskDefPtr def)
+{
+
+    if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+        virBufferAsprintf(devicemap, "(cd) %s\n",
+                          virDomainDiskGetSource(def));
+    else
+        virBufferAsprintf(devicemap, "(hd0) %s\n",
+                          virDomainDiskGetSource(def));
+}
+
 static virCommandPtr
 virBhyveProcessBuildGrubbhyveCmd(virDomainDefPtr def,
                                  virConnectPtr conn,
                                  const char *devmap_file,
                                  char **devicesmap_out)
 {
-    virDomainDiskDefPtr disk, cd;
+    virDomainDiskDefPtr hdd, cd, userdef, diskdef;
     virBuffer devicemap;
     virCommandPtr cmd;
+    int best_idx;
     size_t i;
 
     if (def->os.bootloaderArgs != NULL)
         return virBhyveProcessBuildCustomLoaderCmd(def);
 
+    best_idx = INT_MAX;
     devicemap = (virBuffer)VIR_BUFFER_INITIALIZER;
 
-    /* Search disk list for CD or HDD device. */
-    cd = disk = NULL;
+    /* Search disk list for CD or HDD device. We'll respect  if
+     * present and otherwise pick the first CD or failing that HDD we come
+     * across. */
+    cd = hdd = userdef = NULL;
     for (i = 0; i < def->ndisks; i++) {
         if (!virBhyveUsableDisk(conn, def->disks[i]))
             continue;
 
-        if (cd == NULL &&
-            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
-            cd = def->disks[i];
-            VIR_INFO("Picking %s as boot CD", virDomainDiskGetSource(cd));
+        diskdef = def->disks[i];
+
+        if (diskdef->info.bootIndex && diskdef->info.bootIndex < best_idx) {
+            userdef = diskdef;
+            best_idx = userdef->info.bootIndex;
+            continue;
         }
 
-        if (disk == NULL &&
+        if (cd == NULL &&
+            def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+            cd = diskdef;
+            VIR_INFO("Picking %s as CD", virDomainDiskGetSource(cd));
+        }
+
+        if (hdd == NULL &&
             def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
-            disk = def->disks[i];
-            VIR_INFO("Picking %s as HDD", virDomainDiskGetSource(disk));
+            hdd = diskdef;
+            VIR_INFO("Picking %s as HDD", virDomainDiskGetSource(hdd));
         }
     }
 
@@ -422,22 +446,28 @@ virBhyveProcessBuildGrubbhyveCmd(virDomainDefPtr def,
 
     if (devicesmap_out != NULL) {
         /* Grub device.map (just for boot) */
-        if (disk != NULL)
-            virBufferAsprintf(&devicemap, "(hd0) %s\n",
-                              virDomainDiskGetSource(disk));
+        if (userdef != NULL) {
+            virBhyveFormatGrubDevice(&devicemap, userdef);
+        } else {
+            if (hdd != NULL)
+                virBhyveFormatGrubDevice(&devicemap, hdd);
 
-        if (cd != NULL)
-            virBufferAsprintf(&devicemap, "(cd) %s\n",
-                              virDomainDiskGetSource(cd));
+            if (cd != NULL)
+                virBhyveFormatGrubDevice(&devicemap, cd);
+        }
 
         *devicesmap_out = virBufferContentAndReset(&devicemap);
     }
 
-    if (cd != NULL) {
-        virCommandAddArg(cmd, "--root");
+    virCommandAddArg(cmd, "--root");
+    if (userdef != NULL) {
+        if (userdef->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+            virCommandAddArg(cmd, "cd");
+        else
+            virCommandAddArg(cmd, "hd0,msdos1");
+    } else if (cd != NULL) {
         virCommandAddArg(cmd, "cd");
     } else {
-        virCommandAddArg(cmd, "--root");
         virCommandAddArg(cmd, "hd0,msdos1");
     }
 
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.args b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.args
new file mode 100644
index 0000000000..eaba3708a1
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.args
@@ -0,0 +1,6 @@
+/usr/sbin/bhyve -c 1 -m 214 -H -P -s 0:0,hostbridge \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \
+-s 2:0,ahci-hd,/tmp/freebsd1.img \
+-s 2:0,ahci-hd,/tmp/freebsd2.img \
+-s 2:0,ahci-hd,/tmp/freebsd3.img \
+bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.devmap b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.devmap
new file mode 100644
index 0000000000..1be3b50dad
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.devmap
@@ -0,0 +1 @@
+(hd0) /tmp/freebsd3.img
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.ldargs
new file mode 100644
index 0000000000..91c15ce736
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.ldargs
@@ -0,0 +1,2 @@
+/usr/local/sbin/grub-bhyve --root hd0,msdos1 --device-map '' \
+--memory 214 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.xml
new file mode 100644
index 0000000000..e372024405
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder.xml
@@ -0,0 +1,36 @@
+
+  bhyve
+  df3be7e7-a104-11e3-aeb0-50e5492bd3dc
+  219136
+  1
+  /usr/local/sbin/grub-bhyve
+  
+    hvm
+  
+  
+    
+      
+      
+      
+      
+ + + + + +
+ + + + + + +
+ + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.args b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.args new file mode 100644 index 0000000000..eaba3708a1 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.args @@ -0,0 +1,6 @@ +/usr/sbin/bhyve -c 1 -m 214 -H -P -s 0:0,hostbridge \ +-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 \ +-s 2:0,ahci-hd,/tmp/freebsd1.img \ +-s 2:0,ahci-hd,/tmp/freebsd2.img \ +-s 2:0,ahci-hd,/tmp/freebsd3.img \ +bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.devmap b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.devmap new file mode 100644 index 0000000000..1be3b50dad --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.devmap @@ -0,0 +1 @@ +(hd0) /tmp/freebsd3.img diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.ldargs new file mode 100644 index 0000000000..91c15ce736 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.ldargs @@ -0,0 +1,2 @@ +/usr/local/sbin/grub-bhyve --root hd0,msdos1 --device-map '' \ +--memory 214 bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.xml new file mode 100644 index 0000000000..8742a30a9d --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-grub-bootorder2.xml @@ -0,0 +1,38 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + /usr/local/sbin/grub-bhyve + + hvm + + + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + +
+ + + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index ec57160a8c..cd3aea0c23 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -163,6 +163,8 @@ mymain(void) DO_TEST("serial"); DO_TEST("console"); DO_TEST("grub-defaults"); + DO_TEST("grub-bootorder"); + DO_TEST("grub-bootorder2"); DO_TEST("bhyveload-explicitargs"); DO_TEST("custom-loader"); DO_TEST("disk-cdrom-grub");