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");