* Extract filling bhyve capabilities from virBhyveDomainCapsBuild()
into a new function virBhyveDomainCapsFill() to make testing
easier by not having to mock firmware directory listing and
hypervisor capabilities probing
* Also, just presence of the firmware files is not sufficient
to enable os.loader.supported, hypervisor should support UEFI
boot too
* Add tests to domaincapstest for the main caps possible flows:
- when UEFI bootrom is supported
- when video (fbus) is supported
- neither of above is supported
---
src/bhyve/bhyve_capabilities.c | 72 +++++++++++++++--------
src/bhyve/bhyve_capabilities.h | 3 +
tests/Makefile.am | 4 ++
tests/domaincapsschemadata/bhyve_basic.x86_64.xml | 32 ++++++++++
tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml | 49 +++++++++++++++
tests/domaincapsschemadata/bhyve_uefi.x86_64.xml | 41 +++++++++++++
tests/domaincapstest.c | 65 ++++++++++++++++++++
7 files changed, 242 insertions(+), 24 deletions(-)
create mode 100644 tests/domaincapsschemadata/bhyve_basic.x86_64.xml
create mode 100644 tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml
create mode 100644 tests/domaincapsschemadata/bhyve_uefi.x86_64.xml
diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index 4bf1d84fa..6f8be45c4 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -87,6 +87,44 @@ virBhyveCapsBuild(void)
return NULL;
}
+int
+virBhyveDomainCapsFill(virDomainCapsPtr caps,
+ unsigned int bhyvecaps,
+ virDomainCapsStringValuesPtr firmwares)
+{
+ caps->disk.supported = true;
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->disk.diskDevice,
+ VIR_DOMAIN_DISK_DEVICE_DISK,
+ VIR_DOMAIN_DISK_DEVICE_CDROM);
+
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->disk.bus,
+ VIR_DOMAIN_DISK_BUS_SATA,
+ VIR_DOMAIN_DISK_BUS_VIRTIO);
+
+ caps->os.supported = true;
+
+ if (bhyvecaps & BHYVE_CAP_LPC_BOOTROM) {
+ caps->os.loader.supported = true;
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.type,
+ VIR_DOMAIN_LOADER_TYPE_PFLASH);
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.readonly,
+ VIR_TRISTATE_BOOL_YES);
+
+ caps->os.loader.values.values = firmwares->values;
+ caps->os.loader.values.nvalues = firmwares->nvalues;
+ }
+
+
+ if (bhyvecaps & BHYVE_CAP_FBUF) {
+ caps->graphics.supported = true;
+ caps->video.supported = true;
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->graphics.type, VIR_DOMAIN_GRAPHICS_TYPE_VNC);
+ VIR_DOMAIN_CAPS_ENUM_SET(caps->video.modelType, VIR_DOMAIN_VIDEO_TYPE_GOP);
+ }
+ return 0;
+}
+
+
virDomainCapsPtr
virBhyveDomainCapsBuild(bhyveConnPtr conn,
const char *emulatorbin,
@@ -101,6 +139,7 @@ virBhyveDomainCapsBuild(bhyveConnPtr conn,
size_t firmwares_alloc = 0;
virBhyveDriverConfigPtr cfg = virBhyveDriverGetConfig(conn);
const char *firmware_dir = cfg->firmwareDir;
+ virDomainCapsStringValuesPtr firmwares = NULL;
if (!(caps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
goto cleanup;
@@ -111,46 +150,31 @@ virBhyveDomainCapsBuild(bhyveConnPtr conn,
goto cleanup;
}
- caps->os.supported = true;
- caps->os.loader.supported = true;
- VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.type,
- VIR_DOMAIN_LOADER_TYPE_PFLASH);
- VIR_DOMAIN_CAPS_ENUM_SET(caps->os.loader.readonly,
- VIR_TRISTATE_BOOL_YES);
+ if (VIR_ALLOC(firmwares) < 0)
+ goto cleanup;
if (virDirOpenIfExists(&dir, firmware_dir) > 0) {
while ((virDirRead(dir, &entry, firmware_dir)) > 0) {
- if (VIR_RESIZE_N(caps->os.loader.values.values,
- firmwares_alloc, caps->os.loader.values.nvalues, 2) < 0)
+ if (VIR_RESIZE_N(firmwares->values,
+ firmwares_alloc, firmwares->nvalues, 1) < 0)
goto cleanup;
if (virAsprintf(
-
&caps->os.loader.values.values[caps->os.loader.values.nvalues],
+ &firmwares->values[firmwares->nvalues],
"%s/%s", firmware_dir, entry->d_name) < 0)
goto cleanup;
- caps->os.loader.values.nvalues++;
+ firmwares->nvalues++;
}
} else {
VIR_WARN("Cannot open firmware directory %s", firmware_dir);
}
- caps->disk.supported = true;
- VIR_DOMAIN_CAPS_ENUM_SET(caps->disk.diskDevice,
- VIR_DOMAIN_DISK_DEVICE_DISK,
- VIR_DOMAIN_DISK_DEVICE_CDROM);
-
- VIR_DOMAIN_CAPS_ENUM_SET(caps->disk.bus,
- VIR_DOMAIN_DISK_BUS_SATA,
- VIR_DOMAIN_DISK_BUS_VIRTIO);
+ if (virBhyveDomainCapsFill(caps, bhyve_caps, firmwares) < 0)
+ goto cleanup;
- if (bhyve_caps & BHYVE_CAP_FBUF) {
- caps->graphics.supported = true;
- caps->video.supported = true;
- VIR_DOMAIN_CAPS_ENUM_SET(caps->graphics.type, VIR_DOMAIN_GRAPHICS_TYPE_VNC);
- VIR_DOMAIN_CAPS_ENUM_SET(caps->video.modelType, VIR_DOMAIN_VIDEO_TYPE_GOP);
- }
cleanup:
+ VIR_FREE(firmwares);
VIR_DIR_CLOSE(dir);
virObjectUnref(cfg);
return caps;
diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h
index 3db4f1b88..194061fde 100644
--- a/src/bhyve/bhyve_capabilities.h
+++ b/src/bhyve/bhyve_capabilities.h
@@ -28,6 +28,9 @@
# include "bhyve_utils.h"
virCapsPtr virBhyveCapsBuild(void);
+int virBhyveDomainCapsFill(virDomainCapsPtr caps,
+ unsigned int bhyvecaps,
+ virDomainCapsStringValuesPtr firmwares);
virDomainCapsPtr virBhyveDomainCapsBuild(bhyveConnPtr,
const char *emulatorbin,
const char *machine,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index af69a3a84..d4eedaf17 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -964,6 +964,10 @@ domaincapstest_SOURCES += testutilsxen.c testutilsxen.h
domaincapstest_LDADD += ../src/libvirt_driver_libxl_impl.la $(GNULIB_LIBS)
endif WITH_LIBXL
+if WITH_BHYVE
+domaincapstest_LDADD += ../src/libvirt_driver_bhyve_impl.la $(GNULIB_LIBS)
+endif WITH_BHYVE
+
virnetmessagetest_SOURCES = \
virnetmessagetest.c testutils.h testutils.c
virnetmessagetest_CFLAGS = $(XDR_CFLAGS) $(AM_CFLAGS)
diff --git a/tests/domaincapsschemadata/bhyve_basic.x86_64.xml
b/tests/domaincapsschemadata/bhyve_basic.x86_64.xml
new file mode 100644
index 000000000..f6dfabed2
--- /dev/null
+++ b/tests/domaincapsschemadata/bhyve_basic.x86_64.xml
@@ -0,0 +1,32 @@
+<domainCapabilities>
+ <path>/usr/sbin/bhyve</path>
+ <domain>bhyve</domain>
+ <machine>(null)</machine>
+ <arch>x86_64</arch>
+ <os supported='yes'>
+ <loader supported='no'/>
+ </os>
+ <cpu>
+ <mode name='host-passthrough' supported='no'/>
+ <mode name='host-model' supported='no'/>
+ <mode name='custom' supported='no'/>
+ </cpu>
+ <devices>
+ <disk supported='yes'>
+ <enum name='diskDevice'>
+ <value>disk</value>
+ <value>cdrom</value>
+ </enum>
+ <enum name='bus'>
+ <value>virtio</value>
+ <value>sata</value>
+ </enum>
+ </disk>
+ <graphics supported='no'/>
+ <video supported='no'/>
+ <hostdev supported='no'/>
+ </devices>
+ <features>
+ <gic supported='no'/>
+ </features>
+</domainCapabilities>
diff --git a/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml
b/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml
new file mode 100644
index 000000000..6fec72c89
--- /dev/null
+++ b/tests/domaincapsschemadata/bhyve_fbuf.x86_64.xml
@@ -0,0 +1,49 @@
+<domainCapabilities>
+ <path>/usr/sbin/bhyve</path>
+ <domain>bhyve</domain>
+ <machine>(null)</machine>
+ <arch>x86_64</arch>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <value>/foo/bar</value>
+ <value>/foo/baz</value>
+ <enum name='type'>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ </enum>
+ </loader>
+ </os>
+ <cpu>
+ <mode name='host-passthrough' supported='no'/>
+ <mode name='host-model' supported='no'/>
+ <mode name='custom' supported='no'/>
+ </cpu>
+ <devices>
+ <disk supported='yes'>
+ <enum name='diskDevice'>
+ <value>disk</value>
+ <value>cdrom</value>
+ </enum>
+ <enum name='bus'>
+ <value>virtio</value>
+ <value>sata</value>
+ </enum>
+ </disk>
+ <graphics supported='yes'>
+ <enum name='type'>
+ <value>vnc</value>
+ </enum>
+ </graphics>
+ <video supported='yes'>
+ <enum name='modelType'>
+ <value>gop</value>
+ </enum>
+ </video>
+ <hostdev supported='no'/>
+ </devices>
+ <features>
+ <gic supported='no'/>
+ </features>
+</domainCapabilities>
diff --git a/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml
b/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml
new file mode 100644
index 000000000..c0b5c161b
--- /dev/null
+++ b/tests/domaincapsschemadata/bhyve_uefi.x86_64.xml
@@ -0,0 +1,41 @@
+<domainCapabilities>
+ <path>/usr/sbin/bhyve</path>
+ <domain>bhyve</domain>
+ <machine>(null)</machine>
+ <arch>x86_64</arch>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <value>/foo/bar</value>
+ <value>/foo/baz</value>
+ <enum name='type'>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ </enum>
+ </loader>
+ </os>
+ <cpu>
+ <mode name='host-passthrough' supported='no'/>
+ <mode name='host-model' supported='no'/>
+ <mode name='custom' supported='no'/>
+ </cpu>
+ <devices>
+ <disk supported='yes'>
+ <enum name='diskDevice'>
+ <value>disk</value>
+ <value>cdrom</value>
+ </enum>
+ <enum name='bus'>
+ <value>virtio</value>
+ <value>sata</value>
+ </enum>
+ </disk>
+ <graphics supported='no'/>
+ <video supported='no'/>
+ <hostdev supported='no'/>
+ </devices>
+ <features>
+ <gic supported='no'/>
+ </features>
+</domainCapabilities>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index a4bc8d6d0..c61a5c05f 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -273,12 +273,37 @@ fillXenCaps(virDomainCapsPtr domCaps)
}
#endif /* WITH_LIBXL */
+#ifdef WITH_BHYVE
+# include "bhyve/bhyve_capabilities.h"
+
+static int
+fillBhyveCaps(virDomainCapsPtr domCaps, unsigned int *bhyve_caps)
+{
+ virDomainCapsStringValuesPtr firmwares = NULL;
+ int ret = -1;
+
+ if (VIR_ALLOC(firmwares) < 0)
+ return -1;
+
+ if (fillStringValues(firmwares, "/foo/bar", "/foo/baz", NULL)
< 0)
+ goto cleanup;
+
+ if (virBhyveDomainCapsFill(domCaps, *bhyve_caps, firmwares) < 0)
+ goto cleanup;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(firmwares);
+ return ret;
+}
+#endif /* WITH_BHYVE */
enum testCapsType {
CAPS_NONE,
CAPS_ALL,
CAPS_QEMU,
CAPS_LIBXL,
+ CAPS_BHYVE,
};
struct testData {
@@ -333,6 +358,12 @@ test_virDomainCapsFormat(const void *opaque)
goto cleanup;
#endif
break;
+ case CAPS_BHYVE:
+#if WITH_BHYVE
+ if (fillBhyveCaps(domCaps, data->capsOpaque) < 0)
+ goto cleanup;
+#endif
+ break;
}
if (!(domCapsXML = virDomainCapsFormat(domCaps)))
@@ -354,6 +385,10 @@ mymain(void)
{
int ret = 0;
+#if WITH_BHYVE
+ unsigned int bhyve_caps = 0;
+#endif
+
#if WITH_QEMU
virQEMUDriverConfigPtr cfg = virQEMUDriverConfigNew(false);
@@ -419,6 +454,26 @@ mymain(void)
DO_TEST("full", "/bin/emulatorbin", "my-machine-type",
"x86_64", VIR_DOMAIN_VIRT_KVM, CAPS_ALL);
+#define DO_TEST_BHYVE(Name, Emulator, BhyveCaps, Type) \
+ do { \
+ char *name = NULL; \
+ if (virAsprintf(&name, "bhyve_%s.x86_64", Name) < 0) {
\
+ ret = -1; \
+ break; \
+ } \
+ struct testData data = { \
+ .name = name, \
+ .emulator = Emulator, \
+ .arch = "x86_64", \
+ .type = Type, \
+ .capsType = CAPS_BHYVE, \
+ .capsOpaque = BhyveCaps, \
+ }; \
+ if (virTestRun(name, test_virDomainCapsFormat, &data) < 0) \
+ ret = -1; \
+ VIR_FREE(name); \
+ } while (0)
+
#if WITH_QEMU
DO_TEST_QEMU("1.7.0", "caps_1.7.0",
@@ -488,6 +543,16 @@ mymain(void)
#endif /* WITH_LIBXL */
+#if WITH_BHYVE
+ DO_TEST_BHYVE("basic", "/usr/sbin/bhyve", &bhyve_caps,
VIR_DOMAIN_VIRT_BHYVE);
+
+ bhyve_caps |= BHYVE_CAP_LPC_BOOTROM;
+ DO_TEST_BHYVE("uefi", "/usr/sbin/bhyve", &bhyve_caps,
VIR_DOMAIN_VIRT_BHYVE);
+
+ bhyve_caps |= BHYVE_CAP_FBUF;
+ DO_TEST_BHYVE("fbuf", "/usr/sbin/bhyve", &bhyve_caps,
VIR_DOMAIN_VIRT_BHYVE);
+#endif /* WITH_BHYVE */
+
return ret;
}
--
2.11.0