From: Conrad Meyer
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.
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;
+ diskdef = def->disks[i];
+
+ if (diskdef->info.bootIndex && diskdef->info.bootIndex < best_idx) {
+ userdef = diskdef;
+ best_idx = userdef->info.bootIndex;
+ 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));
+ cd = diskdef;
+ VIR_INFO("Picking %s as CD", virDomainDiskGetSource(cd));
}
- if (disk == NULL &&
+ 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");