
On 03/19/2017 07:05 AM, Roman Bogorodskiy wrote:
* 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>
This doesn't feel right. We should not output machine if it's NULL. We might need to change docs too: http://libvirt.org/formatdomaincaps.html#elements since there is no machine type in bhyve. I'll post a patch for that after which you'll need to regenerate the output of your tests. After that you have my ACK and you can push this one. Michal