Fixing the transient definition bug in a0d2ec63b99c4e0f500d6b61a208be48b3e3b396 exposed another issue: the startup filled firmware data is only available in the live definition. Thus, after shutdown, there is no information about the VARS file, so `virsh undefine --nvram` cannot remove it. Fix that by filling firmware data in the domain XML post-parse stage. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_domain.c | 11 ++++++++++- src/bhyve/bhyve_driver.c | 10 +++++++--- src/bhyve/bhyve_firmware.c | 12 ++++++------ src/bhyve/bhyve_firmware.h | 2 +- src/bhyve/bhyve_process.c | 4 +++- .../three_firmwares/BHYVE_UEFI_VARS.fd | 0 .../x86_64/bhyvexml2xmlout-numa.xml | 2 ++ tests/bhyvexml2xmltest.c | 10 +++++++++- 8 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_VARS.fd diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c index 3b5a9b47a3..08c4156f2b 100644 --- a/src/bhyve/bhyve_domain.c +++ b/src/bhyve/bhyve_domain.c @@ -21,6 +21,7 @@ #include <config.h> +#include "bhyve_firmware.h" #include "bhyve_driver.h" #include "bhyve_conf.h" #include "bhyve_device.h" @@ -119,7 +120,7 @@ bhyveDomainDefNeedsISAController(virDomainDef *def) static int bhyveDomainDefPostParse(virDomainDef *def, - unsigned int parseFlags G_GNUC_UNUSED, + unsigned int parseFlags, void *opaque, void *parseOpaque G_GNUC_UNUSED) { @@ -130,6 +131,8 @@ bhyveDomainDefPostParse(virDomainDef *def, size_t virtio_serial_controllers = 0; size_t virtio_serial_existing_controllers = 0; size_t virtio_serial_controllers_to_create = 0; + bool abiUpdate = !!(parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE); + if (!caps) return -1; @@ -203,6 +206,12 @@ bhyveDomainDefPostParse(virDomainDef *def, } } + if (bhyveFirmwareFillDomain(driver, def, abiUpdate) < 0) { + if (abiUpdate) + return -1; + virResetLastError(); + } + return 0; } diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 2c4ec911a7..41bcf9b559 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -541,7 +541,8 @@ bhyveDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flag virDomainObj *vm = NULL; virObjectEvent *event = NULL; g_autoptr(virCaps) caps = NULL; - unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; + unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_ABI_UPDATE; virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL); @@ -760,7 +761,9 @@ bhyveConnectDomainXMLToNative(virConnectPtr conn, } if (!(def = virDomainDefParseString(xmlData, privconn->xmlopt, - NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) + NULL, + VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_ABI_UPDATE))) return NULL; if (bhyveDomainAssignAddresses(def, NULL) < 0) @@ -951,7 +954,8 @@ bhyveDomainCreateXML(virConnectPtr conn, virDomainObj *vm = NULL; virObjectEvent *event = NULL; unsigned int start_flags = 0; - unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE; + unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_ABI_UPDATE; virCheckFlags(VIR_DOMAIN_START_AUTODESTROY | VIR_DOMAIN_START_VALIDATE, NULL); diff --git a/src/bhyve/bhyve_firmware.c b/src/bhyve/bhyve_firmware.c index 54e3ce296a..9b8eb98ca6 100644 --- a/src/bhyve/bhyve_firmware.c +++ b/src/bhyve/bhyve_firmware.c @@ -41,7 +41,8 @@ VIR_LOG_INIT("bhyve.bhyve_firmware"); static void bhyveFirmwareEnsureNVRAM(virDomainDef *def, - bhyveConn *driver) + bhyveConn *driver, + bool abiUpdate) { g_autoptr(virBhyveDriverConfig) cfg = virBhyveDriverGetConfig(driver); virDomainLoaderDef *loader = def->os.loader; @@ -98,7 +99,8 @@ bhyveFirmwareEnsureNVRAM(virDomainDef *def, * * If we're loading an existing domain, however, we need to * stick with the .fd extension to ensure compatibility */ - if (loader->nvramTemplate && + if (abiUpdate && + loader->nvramTemplate && virStringHasSuffix(loader->nvramTemplate, ".raw")) ext = ".raw"; else @@ -112,7 +114,7 @@ bhyveFirmwareEnsureNVRAM(virDomainDef *def, int bhyveFirmwareFillDomain(bhyveConn *driver, virDomainDef *def, - unsigned int flags) + bool abiUpdate) { g_autoptr(DIR) dir = NULL; g_autoptr(virBhyveDriverConfig) cfg = virBhyveDriverGetConfig(driver); @@ -123,8 +125,6 @@ bhyveFirmwareFillDomain(bhyveConn *driver, g_autofree char *matching_nvram_template = NULL; g_autofree char *first_found = NULL; - virCheckFlags(0, -1); - if (!ARCH_IS_X86(def->os.arch)) return 0; @@ -190,7 +190,7 @@ bhyveFirmwareFillDomain(bhyveConn *driver, loader->path = g_build_filename(firmware_dir, matching_firmware, NULL); out: - bhyveFirmwareEnsureNVRAM(def, driver); + bhyveFirmwareEnsureNVRAM(def, driver, abiUpdate); return 0; } diff --git a/src/bhyve/bhyve_firmware.h b/src/bhyve/bhyve_firmware.h index ae7bd8a2b6..1ff7853909 100644 --- a/src/bhyve/bhyve_firmware.h +++ b/src/bhyve/bhyve_firmware.h @@ -27,4 +27,4 @@ int bhyveFirmwareFillDomain(bhyveConn *driver, virDomainDef *def, - unsigned int flags); + bool abiUpdate); diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c index dee3368cfc..65cf61c578 100644 --- a/src/bhyve/bhyve_process.c +++ b/src/bhyve/bhyve_process.c @@ -449,7 +449,9 @@ bhyveProcessPrepareDomain(bhyveConn *driver, virDomainObj *vm, unsigned int flags) { - if (bhyveFirmwareFillDomain(driver, vm->def, flags) < 0) + virCheckFlags(0, -1); + + if (bhyveFirmwareFillDomain(driver, vm->def, false) < 0) return -1; return 0; diff --git a/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_VARS.fd b/tests/bhyvefirmwaredata/three_firmwares/BHYVE_UEFI_VARS.fd new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/bhyvexml2xmloutdata/x86_64/bhyvexml2xmlout-numa.xml b/tests/bhyvexml2xmloutdata/x86_64/bhyvexml2xmlout-numa.xml index ecc147db78..0066de9d6e 100644 --- a/tests/bhyvexml2xmloutdata/x86_64/bhyvexml2xmlout-numa.xml +++ b/tests/bhyvexml2xmloutdata/x86_64/bhyvexml2xmlout-numa.xml @@ -6,6 +6,8 @@ <vcpu placement='static'>8</vcpu> <os firmware='efi'> <type arch='x86_64'>hvm</type> + <loader readonly='yes' type='pflash' format='raw'>fakefirmwaredir/BHYVE_UEFI.fd</loader> + <nvram template='fakefirmwaredir/BHYVE_UEFI_VARS.fd' format='raw'>fakenvramdir/bhyve_VARS.fd</nvram> <boot dev='hd'/> </os> <cpu> diff --git a/tests/bhyvexml2xmltest.c b/tests/bhyvexml2xmltest.c index 120bdd42e5..9071f5e7f0 100644 --- a/tests/bhyvexml2xmltest.c +++ b/tests/bhyvexml2xmltest.c @@ -56,6 +56,8 @@ testCompareXMLToXMLHelper(const void *data) static int mymain(void) { + g_autofree char *fakefirmwaredir = g_strdup("fakefirmwaredir"); + g_autofree char *fakenvramdir = g_strdup("fakenvramdir"); g_autofree char *fakeubootpath = g_strdup("fakeubootpath/u-boot.bin"); int ret = 0; @@ -68,7 +70,12 @@ mymain(void) if (!(driver.config = virBhyveDriverConfigNew())) return EXIT_FAILURE; - driver.config->ubootPath = fakeubootpath; + VIR_FREE(driver.config->firmwareDir); + VIR_FREE(driver.config->nvramDir); + VIR_FREE(driver.config->ubootPath); + driver.config->firmwareDir = g_steal_pointer(&fakefirmwaredir); + driver.config->nvramDir = g_steal_pointer(&fakenvramdir); + driver.config->ubootPath = g_steal_pointer(&fakeubootpath); # define DO_TEST_FULL(name, flags) \ do { \ @@ -176,6 +183,7 @@ mymain(void) virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); + virObjectUnref(driver.config); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.52.0