[PATCH v2] bhyve: add <os firmware='efi'> support

Roman Bogorodskiy posted 1 patch 3 years, 1 month ago
Test syntax-check failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/20210316122016.31998-1-bogorodskiy@gmail.com
po/POTFILES.in                                |  1 +
src/bhyve/bhyve_domain.c                      |  5 +
src/bhyve/bhyve_firmware.c                    | 91 +++++++++++++++++++
src/bhyve/bhyve_firmware.h                    | 30 ++++++
src/bhyve/bhyve_process.c                     | 15 +++
src/bhyve/bhyve_process.h                     |  5 +
src/bhyve/bhyve_utils.h                       |  2 +
src/bhyve/meson.build                         |  1 +
tests/bhyvefirmwaredata/empty/.keepme         |  0
.../three_firmwares/BHYVE_UEFI.fd             |  0
.../three_firmwares/BHYVE_UEFI_CSM.fd         |  0
.../three_firmwares/refind_x64.efi            |  0
.../bhyvexml2argv-firmware-efi.args           | 11 +++
.../bhyvexml2argv-firmware-efi.ldargs         |  1 +
.../bhyvexml2argv-firmware-efi.xml            | 22 +++++
tests/bhyvexml2argvmock.c                     | 33 +++++++
tests/bhyvexml2argvtest.c                     | 52 ++++++++---
17 files changed, 257 insertions(+), 12 deletions(-)
create mode 100644 src/bhyve/bhyve_firmware.c
create mode 100644 src/bhyve/bhyve_firmware.h
create mode 100644 tests/bhyvefirmwaredata/empty/.keepme
create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI.fd
create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_CSM.fd
create mode 100644 tests/bhyvefirmwaredata/three_firmwares/refind_x64.efi
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs
create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml
[PATCH v2] bhyve: add <os firmware='efi'> support
Posted by Roman Bogorodskiy 3 years, 1 month ago
Implement "<os firmware='efi'>" support for bhyve driver.
As there are not really lot of options, try to find
"BHYVE_UEFI.fd" firmware which is installed by the
sysutils/uefi-edk2-bhyve FreeBSD port.

If not found, just use the first found firmware
in the firmwares directory (which is configurable via
config file).

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
---
Changes from v1:

 - Fixed various leaks,
 - Re-implemented testing using opendir() mock.

 po/POTFILES.in                                |  1 +
 src/bhyve/bhyve_domain.c                      |  5 +
 src/bhyve/bhyve_firmware.c                    | 91 +++++++++++++++++++
 src/bhyve/bhyve_firmware.h                    | 30 ++++++
 src/bhyve/bhyve_process.c                     | 15 +++
 src/bhyve/bhyve_process.h                     |  5 +
 src/bhyve/bhyve_utils.h                       |  2 +
 src/bhyve/meson.build                         |  1 +
 tests/bhyvefirmwaredata/empty/.keepme         |  0
 .../three_firmwares/BHYVE_UEFI.fd             |  0
 .../three_firmwares/BHYVE_UEFI_CSM.fd         |  0
 .../three_firmwares/refind_x64.efi            |  0
 .../bhyvexml2argv-firmware-efi.args           | 11 +++
 .../bhyvexml2argv-firmware-efi.ldargs         |  1 +
 .../bhyvexml2argv-firmware-efi.xml            | 22 +++++
 tests/bhyvexml2argvmock.c                     | 33 +++++++
 tests/bhyvexml2argvtest.c                     | 52 ++++++++---
 17 files changed, 257 insertions(+), 12 deletions(-)
 create mode 100644 src/bhyve/bhyve_firmware.c
 create mode 100644 src/bhyve/bhyve_firmware.h
 create mode 100644 tests/bhyvefirmwaredata/empty/.keepme
 create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI.fd
 create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_CSM.fd
 create mode 100644 tests/bhyvefirmwaredata/three_firmwares/refind_x64.efi
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 80c5f145be..413783ee35 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -14,6 +14,7 @@
 @SRCDIR@src/bhyve/bhyve_command.c
 @SRCDIR@src/bhyve/bhyve_domain.c
 @SRCDIR@src/bhyve/bhyve_driver.c
+@SRCDIR@src/bhyve/bhyve_firmware.c
 @SRCDIR@src/bhyve/bhyve_monitor.c
 @SRCDIR@src/bhyve/bhyve_parse_command.c
 @SRCDIR@src/bhyve/bhyve_process.c
diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
index 8fbc554a0a..209e4d3905 100644
--- a/src/bhyve/bhyve_domain.c
+++ b/src/bhyve/bhyve_domain.c
@@ -64,6 +64,9 @@ bhyveDomainDefNeedsISAController(virDomainDefPtr def)
     if (def->os.bootloader == NULL && def->os.loader)
         return true;
 
+    if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_EFI)
+        return true;
+
     if (def->nserials || def->nconsoles)
         return true;
 
@@ -230,6 +233,8 @@ virDomainDefParserConfig virBhyveDriverDomainDefParserConfig = {
     .domainPostParseCallback = bhyveDomainDefPostParse,
     .assignAddressesCallback = bhyveDomainDefAssignAddresses,
     .deviceValidateCallback = bhyveDomainDeviceDefValidate,
+
+    .features = VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT,
 };
 
 static void
diff --git a/src/bhyve/bhyve_firmware.c b/src/bhyve/bhyve_firmware.c
new file mode 100644
index 0000000000..2055f34288
--- /dev/null
+++ b/src/bhyve/bhyve_firmware.c
@@ -0,0 +1,91 @@
+/*
+ * bhyve_firmware.c: bhyve firmware management
+ *
+ * Copyright (C) 2021 Roman Bogorodskiy
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <config.h>
+#include <dirent.h>
+
+#include "viralloc.h"
+#include "virlog.h"
+#include "virfile.h"
+#include "bhyve_conf.h"
+#include "bhyve_firmware.h"
+
+#define VIR_FROM_THIS   VIR_FROM_BHYVE
+
+VIR_LOG_INIT("bhyve.bhyve_firmware");
+
+
+#define BHYVE_DEFAULT_FIRMWARE  "BHYVE_UEFI.fd"
+
+int
+bhyveFirmwareFillDomain(bhyveConnPtr driver,
+                        virDomainDefPtr def,
+                        unsigned int flags)
+{
+    g_autoptr(DIR) dir = NULL;
+    g_autoptr(virBhyveDriverConfig) cfg = virBhyveDriverGetConfig(driver);
+    const char *firmware_dir = cfg->firmwareDir;
+    struct dirent *entry;
+    g_autofree char *matching_firmware = NULL;
+    g_autofree char *first_found = NULL;
+
+    virCheckFlags(0, -1);
+
+    if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE)
+        return 0;
+
+    if (virDirOpenIfExists(&dir, firmware_dir) > 0) {
+        while ((virDirRead(dir, &entry, firmware_dir)) > 0) {
+            if (g_str_has_prefix(entry->d_name, "."))
+                continue;
+
+            if (STREQ(entry->d_name, BHYVE_DEFAULT_FIRMWARE)) {
+                matching_firmware = g_strdup(entry->d_name);
+                break;
+            }
+            if (!first_found)
+                first_found = g_strdup(entry->d_name);
+        }
+    }
+
+    if (!matching_firmware) {
+        if (!first_found) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("no firmwares found in %s"),
+                           firmware_dir);
+            return -1;
+        } else {
+            matching_firmware = g_steal_pointer(&first_found);
+        }
+    }
+
+    if (!def->os.loader)
+        def->os.loader = g_new0(virDomainLoaderDef, 1);
+
+    def->os.loader->type = VIR_DOMAIN_LOADER_TYPE_PFLASH;
+    def->os.loader->readonly = VIR_TRISTATE_BOOL_YES;
+
+    VIR_FREE(def->os.loader->path);
+
+    def->os.loader->path = g_build_filename(firmware_dir, matching_firmware, NULL);
+
+    return 0;
+}
diff --git a/src/bhyve/bhyve_firmware.h b/src/bhyve/bhyve_firmware.h
new file mode 100644
index 0000000000..ae4bc98676
--- /dev/null
+++ b/src/bhyve/bhyve_firmware.h
@@ -0,0 +1,30 @@
+/*
+ * bhyve_firmware.h: bhyve firmware management
+ *
+ * Copyright (C) 2021 Roman Bogorodskiy
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#pragma once
+
+#include "domain_conf.h"
+#include "bhyve_utils.h"
+
+int
+bhyveFirmwareFillDomain(bhyveConnPtr driver,
+                        virDomainDefPtr def,
+                        unsigned int flags);
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index 060018bc70..0cfe69688c 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -33,6 +33,7 @@
 #include "bhyve_device.h"
 #include "bhyve_driver.h"
 #include "bhyve_command.h"
+#include "bhyve_firmware.h"
 #include "bhyve_monitor.h"
 #include "bhyve_process.h"
 #include "datatypes.h"
@@ -251,6 +252,17 @@ virBhyveProcessStartImpl(bhyveConnPtr driver,
     return ret;
 }
 
+int
+bhyveProcessPrepareDomain(bhyveConnPtr driver,
+                          virDomainObjPtr vm,
+                          unsigned int flags)
+{
+    if (bhyveFirmwareFillDomain(driver, vm->def, flags) < 0)
+        return -1;
+
+    return 0;
+}
+
 int
 virBhyveProcessStart(virConnectPtr conn,
                      virDomainObjPtr vm,
@@ -268,6 +280,9 @@ virBhyveProcessStart(virConnectPtr conn,
                              conn, bhyveProcessAutoDestroy) < 0)
         return -1;
 
+    if (bhyveProcessPrepareDomain(driver, vm, flags) < 0)
+        return -1;
+
     return virBhyveProcessStartImpl(driver, vm, reason);
 }
 
diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h
index d7b4e0bd4e..133863c1e0 100644
--- a/src/bhyve/bhyve_process.h
+++ b/src/bhyve/bhyve_process.h
@@ -23,6 +23,11 @@
 
 #include "bhyve_utils.h"
 
+int
+bhyveProcessPrepareDomain(bhyveConnPtr driver,
+                          virDomainObjPtr vm,
+                          unsigned int flags);
+
 int virBhyveProcessStart(virConnectPtr conn,
                          virDomainObjPtr vm,
                          virDomainRunningReason reason,
diff --git a/src/bhyve/bhyve_utils.h b/src/bhyve/bhyve_utils.h
index f3e80b6121..3bf5ae5daf 100644
--- a/src/bhyve/bhyve_utils.h
+++ b/src/bhyve/bhyve_utils.h
@@ -43,6 +43,8 @@ struct _virBhyveDriverConfig {
     char *firmwareDir;
 };
 
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virBhyveDriverConfig, virObjectUnref);
+
 struct _bhyveConn {
     virMutex lock;
 
diff --git a/src/bhyve/meson.build b/src/bhyve/meson.build
index 2b65eecf5e..b3551477b7 100644
--- a/src/bhyve/meson.build
+++ b/src/bhyve/meson.build
@@ -2,6 +2,7 @@ bhyve_sources = files(
   'bhyve_capabilities.c',
   'bhyve_command.c',
   'bhyve_conf.c',
+  'bhyve_firmware.c',
   'bhyve_parse_command.c',
   'bhyve_device.c',
   'bhyve_domain.c',
diff --git a/tests/bhyvefirmwaredata/empty/.keepme b/tests/bhyvefirmwaredata/empty/.keepme
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI.fd b/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI.fd
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_CSM.fd b/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_CSM.fd
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/bhyvefirmwaredata/three_firmwares/refind_x64.efi b/tests/bhyvefirmwaredata/three_firmwares/refind_x64.efi
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args
new file mode 100644
index 0000000000..2f5aa4d783
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args
@@ -0,0 +1,11 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-l bootrom,fakefirmwaredir/BHYVE_UEFI.fd \
+-s 1:0,lpc \
+-s 2:0,ahci,hd:/tmp/freebsd.img \
+-s 3:0,virtio-net,faketapdev,mac=52:54:00:00:00:00 bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs
new file mode 100644
index 0000000000..421376db9e
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs
@@ -0,0 +1 @@
+dummy
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml
new file mode 100644
index 0000000000..302326cb26
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml
@@ -0,0 +1,22 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os firmware='efi'>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd.img'/>
+      <target dev='hda' bus='sata'/>
+      <address type='drive' controller='0' bus='0' target='2' unit='0'/>
+    </disk>
+    <interface type='bridge'>
+      <model type='virtio'/>
+      <source bridge="virbr0"/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvmock.c b/tests/bhyvexml2argvmock.c
index 25b97f5e04..af5e0fd4b9 100644
--- a/tests/bhyvexml2argvmock.c
+++ b/tests/bhyvexml2argvmock.c
@@ -1,13 +1,46 @@
 #include <config.h>
 
+#include <dirent.h>
+
 #include "viralloc.h"
 #include "virstring.h"
 #include "virnetdev.h"
 #include "virnetdevtap.h"
+#include "virmock.h"
 #include "internal.h"
 
 #define VIR_FROM_THIS VIR_FROM_BHYVE
 
+static DIR * (*real_opendir)(const char *name);
+
+static void
+init_syms(void)
+{
+    VIR_MOCK_REAL_INIT(opendir);
+}
+
+#define FAKEFIRMWAREDIR abs_srcdir "/bhyvefirmwaredata/three_firmwares"
+#define FAKEFIRMWAREEMPTYDIR abs_srcdir "/bhyvefirmwaredata/empty"
+
+DIR *
+opendir(const char *path)
+{
+    init_syms();
+
+    g_autofree char *path_override = NULL;
+
+    if (STREQ(path, "fakefirmwaredir")) {
+        path_override = g_strdup(FAKEFIRMWAREDIR);
+    } else if (STREQ(path, "fakefirmwareemptydir")) {
+        path_override = g_strdup(FAKEFIRMWAREEMPTYDIR);
+    }
+
+    if (!path_override)
+        path_override = g_strdup(path);
+
+    return real_opendir(path_override);
+}
+
 void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],
                         virMacAddrPtr addr)
 {
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 197334f9c4..34e40a6438 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -7,17 +7,20 @@
 # include "datatypes.h"
 
 # include "bhyve/bhyve_capabilities.h"
+# include "bhyve/bhyve_conf.h"
 # include "bhyve/bhyve_domain.h"
 # include "bhyve/bhyve_utils.h"
 # include "bhyve/bhyve_command.h"
+# include "bhyve/bhyve_process.h"
 
 # define VIR_FROM_THIS VIR_FROM_BHYVE
 
 static bhyveConn driver;
 
 typedef enum {
-    FLAG_EXPECT_FAILURE     = 1 << 0,
-    FLAG_EXPECT_PARSE_ERROR = 1 << 1,
+    FLAG_EXPECT_FAILURE         = 1 << 0,
+    FLAG_EXPECT_PARSE_ERROR     = 1 << 1,
+    FLAG_EXPECT_PREPARE_ERROR   = 1 << 2,
 } virBhyveXMLToArgvTestFlags;
 
 static int testCompareXMLToArgvFiles(const char *xml,
@@ -29,7 +32,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
     g_autofree char *actualargv = NULL;
     g_autofree char *actualld = NULL;
     g_autofree char *actualdm = NULL;
-    g_autoptr(virDomainDef) vmdef = NULL;
+    g_autoptr(virDomainObj) vm = NULL;
     g_autoptr(virCommand) cmd = NULL;
     g_autoptr(virCommand) ldcmd = NULL;
     g_autoptr(virConnect) conn = NULL;
@@ -38,8 +41,11 @@ static int testCompareXMLToArgvFiles(const char *xml,
     if (!(conn = virGetConnect()))
         goto out;
 
-    if (!(vmdef = virDomainDefParseFile(xml, driver.xmlopt,
-                                        NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) {
+    if (!(vm = virDomainObjNew(driver.xmlopt)))
+        return -1;
+
+    if (!(vm->def = virDomainDefParseFile(xml, driver.xmlopt,
+                                          NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) {
         if (flags & FLAG_EXPECT_PARSE_ERROR) {
             ret = 0;
         } else if (flags & FLAG_EXPECT_FAILURE) {
@@ -54,11 +60,20 @@ static int testCompareXMLToArgvFiles(const char *xml,
 
     conn->privateData = &driver;
 
-    cmd = virBhyveProcessBuildBhyveCmd(&driver, vmdef, false);
-    if (vmdef->os.loader)
+    if (bhyveProcessPrepareDomain(&driver, vm, 0) < 0) {
+        if (flags & FLAG_EXPECT_PREPARE_ERROR) {
+            ret = 0;
+            VIR_TEST_DEBUG("Got expected error: %s",
+                    virGetLastErrorMessage());
+        }
+        goto out;
+    }
+
+    cmd = virBhyveProcessBuildBhyveCmd(&driver, vm->def, false);
+    if (vm->def->os.loader)
         ldcmd = virCommandNew("dummy");
     else
-        ldcmd = virBhyveProcessBuildLoadCmd(&driver, vmdef, "<device.map>",
+        ldcmd = virBhyveProcessBuildLoadCmd(&driver, vm->def, "<device.map>",
                                             &actualdm);
 
     if ((cmd == NULL) || (ldcmd == NULL)) {
@@ -94,10 +109,10 @@ static int testCompareXMLToArgvFiles(const char *xml,
     ret = 0;
 
  out:
-    if (vmdef &&
-        vmdef->ngraphics == 1 &&
-        vmdef->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC)
-        virPortAllocatorRelease(vmdef->graphics[0]->data.vnc.port);
+    if (vm && vm->def &&
+        vm->def->ngraphics == 1 &&
+        vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC)
+        virPortAllocatorRelease(vm->def->graphics[0]->data.vnc.port);
 
     return ret;
 }
@@ -132,6 +147,8 @@ static int
 mymain(void)
 {
     int ret = 0;
+    g_autofree char *fakefirmwaredir = g_strdup("fakefirmwaredir");
+    g_autofree char *fakefirmwareemptydir = g_strdup("fakefirmwareemptydir");
 
     if ((driver.caps = virBhyveCapsBuild()) == NULL)
         return EXIT_FAILURE;
@@ -142,6 +159,10 @@ mymain(void)
     if (!(driver.remotePorts = virPortAllocatorRangeNew("display", 5900, 65535)))
         return EXIT_FAILURE;
 
+    if (!(driver.config = virBhyveDriverConfigNew()))
+        return EXIT_FAILURE;
+
+    driver.config->firmwareDir = fakefirmwaredir;
 
 # define DO_TEST_FULL(name, flags) \
     do { \
@@ -162,6 +183,9 @@ mymain(void)
 # define DO_TEST_PARSE_ERROR(name) \
     DO_TEST_FULL(name, FLAG_EXPECT_PARSE_ERROR)
 
+# define DO_TEST_PREPARE_ERROR(name) \
+    DO_TEST_FULL(name, FLAG_EXPECT_PREPARE_ERROR)
+
     driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV;
     driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_AHCI32SLOT | \
                        BHYVE_CAP_NET_E1000 | BHYVE_CAP_LPC_BOOTROM | \
@@ -209,6 +233,9 @@ mymain(void)
     DO_TEST("sound");
     DO_TEST("isa-controller");
     DO_TEST_FAILURE("isa-multiple-controllers");
+    DO_TEST("firmware-efi");
+    driver.config->firmwareDir = fakefirmwareemptydir;
+    DO_TEST_PREPARE_ERROR("firmware-efi");
     DO_TEST("fs-9p");
     DO_TEST("fs-9p-readonly");
     DO_TEST_FAILURE("fs-9p-unsupported-type");
@@ -267,6 +294,7 @@ mymain(void)
     virObjectUnref(driver.caps);
     virObjectUnref(driver.xmlopt);
     virPortAllocatorRangeFree(driver.remotePorts);
+    virObjectUnref(driver.config);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
-- 
2.30.0

Re: [PATCH v2] bhyve: add <os firmware='efi'> support
Posted by Michal Privoznik 3 years, 1 month ago
On 3/16/21 1:20 PM, Roman Bogorodskiy wrote:
> Implement "<os firmware='efi'>" support for bhyve driver.
> As there are not really lot of options, try to find
> "BHYVE_UEFI.fd" firmware which is installed by the
> sysutils/uefi-edk2-bhyve FreeBSD port.
> 
> If not found, just use the first found firmware
> in the firmwares directory (which is configurable via
> config file).
> 
> Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
> ---
> Changes from v1:
> 
>   - Fixed various leaks,
>   - Re-implemented testing using opendir() mock.
> 
>   po/POTFILES.in                                |  1 +
>   src/bhyve/bhyve_domain.c                      |  5 +
>   src/bhyve/bhyve_firmware.c                    | 91 +++++++++++++++++++
>   src/bhyve/bhyve_firmware.h                    | 30 ++++++
>   src/bhyve/bhyve_process.c                     | 15 +++
>   src/bhyve/bhyve_process.h                     |  5 +
>   src/bhyve/bhyve_utils.h                       |  2 +
>   src/bhyve/meson.build                         |  1 +
>   tests/bhyvefirmwaredata/empty/.keepme         |  0
>   .../three_firmwares/BHYVE_UEFI.fd             |  0
>   .../three_firmwares/BHYVE_UEFI_CSM.fd         |  0
>   .../three_firmwares/refind_x64.efi            |  0
>   .../bhyvexml2argv-firmware-efi.args           | 11 +++
>   .../bhyvexml2argv-firmware-efi.ldargs         |  1 +
>   .../bhyvexml2argv-firmware-efi.xml            | 22 +++++
>   tests/bhyvexml2argvmock.c                     | 33 +++++++
>   tests/bhyvexml2argvtest.c                     | 52 ++++++++---
>   17 files changed, 257 insertions(+), 12 deletions(-)
>   create mode 100644 src/bhyve/bhyve_firmware.c
>   create mode 100644 src/bhyve/bhyve_firmware.h
>   create mode 100644 tests/bhyvefirmwaredata/empty/.keepme
>   create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI.fd
>   create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_CSM.fd
>   create mode 100644 tests/bhyvefirmwaredata/three_firmwares/refind_x64.efi
>   create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.args
>   create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.ldargs
>   create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-firmware-efi.xml

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

Michal