mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
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.
This commit is contained in:
parent
318ae9f3be
commit
ef01addb38
@ -522,22 +522,102 @@ virBhyveProcessBuildGrubbhyveCmd(virDomainDefPtr def,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static virDomainDiskDefPtr
|
||||
virBhyveGetBootDisk(virConnectPtr conn, virDomainDefPtr def)
|
||||
{
|
||||
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"));
|
||||
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;
|
||||
|
||||
if (def->ndisks < 1) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("domain should have at least one disk defined"));
|
||||
return NULL;
|
||||
}
|
||||
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);
|
||||
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
/usr/sbin/bhyveload \
|
||||
-m 214 \
|
||||
-d /tmp/cdrom.iso bhyve
|
@ -0,0 +1,29 @@
|
||||
<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>
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
/usr/sbin/bhyveload \
|
||||
-m 214 \
|
||||
-d /tmp/freebsd.img bhyve
|
@ -0,0 +1,29 @@
|
||||
<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>
|
@ -0,0 +1,23 @@
|
||||
<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>
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
/usr/sbin/bhyveload \
|
||||
-m 214 \
|
||||
-d /tmp/cdrom.iso bhyve
|
@ -0,0 +1,29 @@
|
||||
<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>
|
@ -0,0 +1,30 @@
|
||||
<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>
|
@ -0,0 +1,30 @@
|
||||
<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>
|
@ -5,6 +5,7 @@
|
||||
<vcpu>1</vcpu>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<boot dev='cdrom'/>
|
||||
</os>
|
||||
<devices>
|
||||
<disk type='file' device='cdrom'>
|
||||
|
@ -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, "<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);
|
||||
|
||||
@ -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) \
|
||||
# define DO_TEST_FULL(name, flags) \
|
||||
do { \
|
||||
static struct testInfo info = { \
|
||||
name, (flags) \
|
||||
}; \
|
||||
if (virtTestRun("BHYVE XML-2-ARGV " name, \
|
||||
testCompareXMLToArgvHelper, name) < 0) \
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user