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);
--- /dev/null
+/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
--- /dev/null
+/usr/sbin/bhyveload \
+-m 214 \
+-d /tmp/cdrom.iso bhyve
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/cdrom.iso'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
--- /dev/null
+/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
--- /dev/null
+/usr/sbin/bhyveload \
+-m 214 \
+-d /tmp/freebsd.img bhyve
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/cdrom.iso'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
--- /dev/null
+/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
--- /dev/null
+/usr/sbin/bhyveload \
+-m 214 \
+-d /tmp/cdrom.iso bhyve
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/cdrom.iso'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ <boot order='1'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <boot order='2'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/cdrom.iso'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ <boot order='1'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
--- /dev/null
+<domain type='bhyve'>
+ <name>bhyve</name>
+ <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+ <memory>219136</memory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/freebsd.img'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file' type='raw'/>
+ <source file='/tmp/cdrom.iso'/>
+ <target dev='hda' bus='sata'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+ <boot order='1'/>
+ </disk>
+ <interface type='bridge'>
+ <model type='virtio'/>
+ <source bridge="virbr0"/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </interface>
+ </devices>
+</domain>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
+ <boot dev='cdrom'/>
</os>
<devices>
<disk type='file' device='cdrom'>
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;
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, "<device.map>",
+ &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, "<device.map>",
- &actualdm)))
- goto out;
-
if (actualdm != NULL)
virTrimSpaces(actualdm, NULL);
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);
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;
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");