diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c index 5f3055d6672ca4a431f61d8104b2cdcb85f603ee..8ac4f71277eaf891d1329bbfa28eca4a1ca39eef 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 0000000000000000000000000000000000000000..01a0290a503e6432f19d74d4c38cbb842c3237bf --- /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 0000000000000000000000000000000000000000..24e0bc2bd93e9535860bdee61acf60dc4625f63c --- /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 0000000000000000000000000000000000000000..e58c5f17e5cfbf3dce9b603033c084a0b983b97b --- /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 0000000000000000000000000000000000000000..01a0290a503e6432f19d74d4c38cbb842c3237bf --- /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 0000000000000000000000000000000000000000..32538b558ef3174217a36f1890713552e64ce9be --- /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 0000000000000000000000000000000000000000..6ea46313074a182eed6734914d2e3d6846409c32 --- /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 0000000000000000000000000000000000000000..2fe87dbc4b9328d7e3b3d548135bc10147a343db --- /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 0000000000000000000000000000000000000000..01a0290a503e6432f19d74d4c38cbb842c3237bf --- /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 0000000000000000000000000000000000000000..24e0bc2bd93e9535860bdee61acf60dc4625f63c --- /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 0000000000000000000000000000000000000000..96a8e5a91fd5ee0000bf01e9cb1aa9f16e9150f1 --- /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 0000000000000000000000000000000000000000..4680358afd4be35cce45f4c66023b464be9882b6 --- /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 0000000000000000000000000000000000000000..b5508a962f86966027c654cffcc024599f5940b5 --- /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 d70219c19a1ffa4882df03ced341b3dfe6ebbe6a..c2afcd42b2db326a3e47ee864808b210c073b17a 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 3e57a78e101bc5da5ad3c1d725c5485c31cd1798..e46c05b77265289934a28f61f652af188bff05b0 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");