From ef01addb38f83330197a85373fd16ed1053ff6ce Mon Sep 17 00:00:00 2001 From: Roman Bogorodskiy Date: Sun, 13 Dec 2015 06:17:15 +0300 Subject: [PATCH] bhyve: bhyveload: respect boot dev and boot order Make bhyveload respect boot order as specified by os.boot section of the domain XML or by "boot order" for specific devices. As bhyve does not support a real boot order specification right now, it's just about choosing a single device to boot from. --- src/bhyve/bhyve_command.c | 94 +++++++++++++++++-- .../bhyvexml2argv-bhyveload-bootorder.args | 10 ++ .../bhyvexml2argv-bhyveload-bootorder.ldargs | 3 + .../bhyvexml2argv-bhyveload-bootorder.xml | 29 ++++++ .../bhyvexml2argv-bhyveload-bootorder1.args | 10 ++ .../bhyvexml2argv-bhyveload-bootorder1.ldargs | 3 + .../bhyvexml2argv-bhyveload-bootorder1.xml | 29 ++++++ .../bhyvexml2argv-bhyveload-bootorder2.xml | 23 +++++ .../bhyvexml2argv-bhyveload-bootorder3.args | 10 ++ .../bhyvexml2argv-bhyveload-bootorder3.ldargs | 3 + .../bhyvexml2argv-bhyveload-bootorder3.xml | 29 ++++++ .../bhyvexml2argv-bhyveload-bootorder4.xml | 30 ++++++ .../bhyvexml2argv-bhyveload-bootorder5.xml | 30 ++++++ .../bhyvexml2argv-disk-cdrom.xml | 1 + tests/bhyvexml2argvtest.c | 75 +++++++++++---- 15 files changed, 354 insertions(+), 25 deletions(-) create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder2.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.args create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.ldargs create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder4.xml create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder5.xml diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 5f3055d667..8ac4f71277 100644 --- a/src/bhyve/bhyve_command.c +++ b/src/bhyve/bhyve_command.c @@ -522,22 +522,102 @@ virBhyveProcessBuildGrubbhyveCmd(virDomainDefPtr def, return cmd; } -virCommandPtr -virBhyveProcessBuildLoadCmd(virConnectPtr conn, virDomainDefPtr def, - const char *devmap_file, char **devicesmap_out) +static virDomainDiskDefPtr +virBhyveGetBootDisk(virConnectPtr conn, virDomainDefPtr def) { - virDomainDiskDefPtr disk; + size_t i; + virDomainDiskDefPtr match = NULL; + int boot_dev = -1; if (def->ndisks < 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("domain should have at least one disk defined")); + _("Domain should have at least one disk defined")); + return NULL; + } + + if (def->os.nBootDevs > 1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only one boot device is supported")); return NULL; + } else if (def->os.nBootDevs == 1) { + switch (def->os.bootDevs[0]) { + case VIR_DOMAIN_BOOT_CDROM: + boot_dev = VIR_DOMAIN_DISK_DEVICE_CDROM; + break; + case VIR_DOMAIN_BOOT_DISK: + boot_dev = VIR_DOMAIN_DISK_DEVICE_DISK; + break; + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Cannot boot from device %s"), + virDomainBootTypeToString(def->os.bootDevs[0])); + return NULL; + } + } + + if (boot_dev != -1) { + /* If boot_dev is set, we return the first device of + * the request type */ + for (i = 0; i < def->ndisks; i++) { + if (!virBhyveUsableDisk(conn, def->disks[i])) + continue; + + if (def->disks[i]->device == boot_dev) { + match = def->disks[i]; + break; + } + } + + if (match == NULL) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Cannot find boot device of requested type %s"), + virDomainBootTypeToString(def->os.bootDevs[0])); + return NULL; + } + } else { + /* Otherwise, if boot_dev is not set, we try to find if bootIndex + * is set for individual device. However, as bhyve does not support + * specifying real boot priority for devices, we allow only single + * device with boot priority set. + */ + int first_usable_disk_index = -1; + + for (i = 0; i < def->ndisks; i++) { + if (!virBhyveUsableDisk(conn, def->disks[i])) + continue; + else + first_usable_disk_index = i; + + if (def->disks[i]->info.bootIndex > 0) { + if (match == NULL) { + match = def->disks[i]; + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Only one boot device is supported")); + return NULL; + } + } + } + + /* If user didn't explicily specify boot priority, + * just return the first usable disk */ + if ((match == NULL) && (first_usable_disk_index >= 0)) + return def->disks[first_usable_disk_index]; } + return match; +} + +virCommandPtr +virBhyveProcessBuildLoadCmd(virConnectPtr conn, virDomainDefPtr def, + const char *devmap_file, char **devicesmap_out) +{ + virDomainDiskDefPtr disk = NULL; + if (def->os.bootloader == NULL) { - disk = def->disks[0]; + disk = virBhyveGetBootDisk(conn, def); - if (!virBhyveUsableDisk(conn, disk)) + if (disk == NULL) return NULL; return virBhyveProcessBuildBhyveloadCmd(def, disk); diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.args b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.args new file mode 100644 index 0000000000..01a0290a50 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.args @@ -0,0 +1,10 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-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/freebsd.img \ +-s 4:0,ahci-cd,/tmp/cdrom.iso bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.ldargs new file mode 100644 index 0000000000..24e0bc2bd9 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/cdrom.iso bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.xml new file mode 100644 index 0000000000..e58c5f17e5 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder.xml @@ -0,0 +1,29 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + +
+ + + + + +
+ + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.args b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.args new file mode 100644 index 0000000000..01a0290a50 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.args @@ -0,0 +1,10 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-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/freebsd.img \ +-s 4:0,ahci-cd,/tmp/cdrom.iso bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.ldargs new file mode 100644 index 0000000000..32538b558e --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/freebsd.img bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.xml new file mode 100644 index 0000000000..6ea4631307 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder1.xml @@ -0,0 +1,29 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + +
+ + + + + +
+ + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder2.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder2.xml new file mode 100644 index 0000000000..2fe87dbc4b --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder2.xml @@ -0,0 +1,23 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + +
+ + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.args b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.args new file mode 100644 index 0000000000..01a0290a50 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.args @@ -0,0 +1,10 @@ +/usr/sbin/bhyve \ +-c 1 \ +-m 214 \ +-u \ +-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/freebsd.img \ +-s 4:0,ahci-cd,/tmp/cdrom.iso bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.ldargs new file mode 100644 index 0000000000..24e0bc2bd9 --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.ldargs @@ -0,0 +1,3 @@ +/usr/sbin/bhyveload \ +-m 214 \ +-d /tmp/cdrom.iso bhyve diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.xml new file mode 100644 index 0000000000..96a8e5a91f --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder3.xml @@ -0,0 +1,29 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + +
+ + + + + +
+ + + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder4.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder4.xml new file mode 100644 index 0000000000..4680358afd --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder4.xml @@ -0,0 +1,30 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + +
+ + + + + +
+ + + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder5.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder5.xml new file mode 100644 index 0000000000..b5508a962f --- /dev/null +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-bhyveload-bootorder5.xml @@ -0,0 +1,30 @@ + + bhyve + df3be7e7-a104-11e3-aeb0-50e5492bd3dc + 219136 + 1 + + hvm + + + + + + + +
+ + + + + +
+ + + + + +
+ + + diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-disk-cdrom.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-cdrom.xml index d70219c19a..c2afcd42b2 100644 --- a/tests/bhyvexml2argvdata/bhyvexml2argv-disk-cdrom.xml +++ b/tests/bhyvexml2argvdata/bhyvexml2argv-disk-cdrom.xml @@ -5,6 +5,7 @@ 1 hvm + diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 3e57a78e10..e46c05b772 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -14,10 +14,16 @@ static bhyveConn driver; +typedef enum { + FLAG_EXPECT_FAILURE = 1 << 0, + FLAG_EXPECT_PARSE_ERROR = 1 << 1, +} virBhyveXMLToArgvTestFlags; + static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, const char *ldcmdline, - const char *dmcmdline) + const char *dmcmdline, + unsigned int flags) { char *actualargv = NULL, *actualld = NULL, *actualdm = NULL; virDomainDefPtr vmdef = NULL; @@ -29,21 +35,31 @@ static int testCompareXMLToArgvFiles(const char *xml, goto out; if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) + VIR_DOMAIN_DEF_PARSE_INACTIVE))) { + if (flags & FLAG_EXPECT_PARSE_ERROR) + ret = 0; goto out; + } conn->privateData = &driver; - if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, vmdef, false))) + cmd = virBhyveProcessBuildBhyveCmd(conn, vmdef, false); + ldcmd = virBhyveProcessBuildLoadCmd(conn, vmdef, "", + &actualdm); + + if ((cmd == NULL) || (ldcmd == NULL)) { + if (flags & FLAG_EXPECT_FAILURE) { + ret = 0; + VIR_TEST_DEBUG("Got expected error: %s\n", + virGetLastErrorMessage()); + virResetLastError(); + } goto out; + } if (!(actualargv = virCommandToString(cmd))) goto out; - if (!(ldcmd = virBhyveProcessBuildLoadCmd(conn, vmdef, "", - &actualdm))) - goto out; - if (actualdm != NULL) virTrimSpaces(actualdm, NULL); @@ -73,25 +89,30 @@ static int testCompareXMLToArgvFiles(const char *xml, return ret; } +struct testInfo { + const char *name; + unsigned int flags; +}; + static int testCompareXMLToArgvHelper(const void *data) { int ret = -1; - const char *name = data; + const struct testInfo *info = data; char *xml = NULL; char *args = NULL, *ldargs = NULL, *dmargs = NULL; if (virAsprintf(&xml, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.xml", - abs_srcdir, name) < 0 || + abs_srcdir, info->name) < 0 || virAsprintf(&args, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.args", - abs_srcdir, name) < 0 || + abs_srcdir, info->name) < 0 || virAsprintf(&ldargs, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.ldargs", - abs_srcdir, name) < 0 || + abs_srcdir, info->name) < 0 || virAsprintf(&dmargs, "%s/bhyvexml2argvdata/bhyvexml2argv-%s.devmap", - abs_srcdir, name) < 0) + abs_srcdir, info->name) < 0) goto cleanup; - ret = testCompareXMLToArgvFiles(xml, args, ldargs, dmargs); + ret = testCompareXMLToArgvFiles(xml, args, ldargs, dmargs, info->flags); cleanup: VIR_FREE(xml); @@ -110,13 +131,25 @@ mymain(void) if ((driver.xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL)) == NULL) return EXIT_FAILURE; -# define DO_TEST(name) \ - do { \ - if (virtTestRun("BHYVE XML-2-ARGV " name, \ - testCompareXMLToArgvHelper, name) < 0) \ - ret = -1; \ +# define DO_TEST_FULL(name, flags) \ + do { \ + static struct testInfo info = { \ + name, (flags) \ + }; \ + if (virtTestRun("BHYVE XML-2-ARGV " name, \ + testCompareXMLToArgvHelper, &info) < 0) \ + ret = -1; \ } while (0) +# define DO_TEST(name) \ + DO_TEST_FULL(name, 0) + +# define DO_TEST_FAILURE(name) \ + DO_TEST_FULL(name, FLAG_EXPECT_FAILURE) + +# define DO_TEST_PARSE_ERROR(name) \ + DO_TEST_FULL(name, FLAG_EXPECT_PARSE_ERROR) + driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV; driver.bhyvecaps = BHYVE_CAP_RTC_UTC; @@ -130,7 +163,13 @@ mymain(void) DO_TEST("grub-defaults"); DO_TEST("grub-bootorder"); DO_TEST("grub-bootorder2"); + DO_TEST("bhyveload-bootorder"); + DO_TEST("bhyveload-bootorder1"); + DO_TEST_FAILURE("bhyveload-bootorder2"); + DO_TEST("bhyveload-bootorder3"); DO_TEST("bhyveload-explicitargs"); + DO_TEST_FAILURE("bhyveload-bootorder4"); + DO_TEST_PARSE_ERROR("bhyveload-bootorder5"); DO_TEST("custom-loader"); DO_TEST("disk-cdrom-grub"); DO_TEST("serial-grub"); -- GitLab