提交 ef01addb 编写于 作者: R Roman Bogorodskiy

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.
上级 318ae9f3
......@@ -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);
......
/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
/usr/sbin/bhyveload \
-m 214 \
-d /tmp/cdrom.iso bhyve
<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>
/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
/usr/sbin/bhyveload \
-m 214 \
-d /tmp/freebsd.img bhyve
<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>
<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>
/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
/usr/sbin/bhyveload \
-m 214 \
-d /tmp/cdrom.iso bhyve
<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>
<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>
<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) \
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");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册