From f47031d4e6439d1daf5711d4117c0fa647196944 Mon Sep 17 00:00:00 2001 Message-ID: From: Andrea Bolognani Date: Thu, 22 Jan 2026 19:27:03 +0100 Subject: [PATCH] conf: Update validation to consider varstore element MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code is reworked quite significantly, but most of the existing checks are preserved. Those that aren't, notably the one that allowed pflash as the only acceptable non-stateless firmware type, are intentionally removed because they will no longer reflect reality once support for the uefi-vars QEMU device is introduced. As a side effect, reworking the function in this fashion resolves a subtle bug: due to the early exits that were being performed when the loader element was missing, the checks at the bottom of the function (related to the shim and kernel elements) were effectively never performed. This is no longer the case. Signed-off-by: Andrea Bolognani Reviewed-by: Michal Privoznik Acked-by: Gerd Hoffmann Reviewed-by: Daniel P. Berrangé (cherry picked from commit 1c2dbdf3ac5bed84caeacf585d5143dcf32df75e) https://issues.redhat.com/browse/RHEL-82645 Signed-off-by: Andrea Bolognani --- src/conf/domain_validate.c | 100 +++++++----------- ...-auto-bios-not-stateless.x86_64-latest.err | 2 +- ...-auto-bios-not-stateless.x86_64-latest.xml | 35 ++++++ ...firmware-auto-bios-nvram.x86_64-latest.err | 2 +- ...nual-bios-not-stateless.x86_64-latest.args | 32 ++++++ ...anual-bios-not-stateless.x86_64-latest.err | 1 - ...anual-bios-not-stateless.x86_64-latest.xml | 28 +++++ ...nual-efi-nvram-stateless.x86_64-latest.err | 2 +- ...nvram-template-stateless.x86_64-latest.err | 2 +- ...ware-manual-efi-rw-nvram.x86_64-latest.err | 2 +- tests/qemuxmlconftest.c | 7 +- 11 files changed, 144 insertions(+), 69 deletions(-) create mode 100644 tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.args delete mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.err create mode 100644 tests/qemuxmlconfdata/firmware-manual-bios-not-stateless.x86_64-latest.xml diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 7346a61731..163095d55c 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1723,95 +1723,46 @@ virDomainDefOSValidate(const virDomainDef *def, virDomainXMLOption *xmlopt) { virDomainLoaderDef *loader = def->os.loader; + virDomainVarstoreDef *varstore = def->os.varstore; + virDomainOsDefFirmware firmware = def->os.firmware; + int *firmwareFeatures = def->os.firmwareFeatures; + bool usesNvram = loader && (loader->nvram || loader->nvramTemplate || loader->nvramTemplateFormat); - if (def->os.firmware) { + if (firmware) { if (xmlopt && !(xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_FW_AUTOSELECT)) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("firmware auto selection not implemented for this driver")); return -1; } - if (def->os.firmwareFeatures && - def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES && - def->os.firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) { + if (firmwareFeatures && + firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_ENROLLED_KEYS] == VIR_TRISTATE_BOOL_YES && + firmwareFeatures[VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_SECURE_BOOT] == VIR_TRISTATE_BOOL_NO) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("firmware feature 'enrolled-keys' cannot be enabled when firmware feature 'secure-boot' is disabled")); return -1; } - - if (!loader) - return 0; - - if (loader->nvram && def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { - virReportError(VIR_ERR_XML_DETAIL, - _("firmware type '%1$s' does not support nvram"), - virDomainOsDefFirmwareTypeToString(def->os.firmware)); - return -1; - } } else { - if (def->os.firmwareFeatures) { + if (firmwareFeatures) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("cannot use feature-based firmware autoselection when firmware autoselection is disabled")); return -1; } - if (!loader) - return 0; - - if (!loader->path) { + if (loader && !loader->path) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("no loader path specified and firmware auto selection disabled")); return -1; } } - if (loader->readonly == VIR_TRISTATE_BOOL_NO) { - if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { + if (loader && loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { + if (loader->readonly == VIR_TRISTATE_BOOL_NO) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("ROM loader type cannot be used as read/write")); return -1; } - if (loader->nvramTemplate) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("NVRAM template is not permitted when loader is read/write")); - return -1; - } - - if (loader->nvram) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("NVRAM is not permitted when loader is read/write")); - return -1; - } - } - - if (loader->stateless == VIR_TRISTATE_BOOL_YES) { - if (loader->nvramTemplate) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("NVRAM template is not permitted when loader is stateless")); - return -1; - } - - if (loader->nvram) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("NVRAM is not permitted when loader is stateless")); - return -1; - } - } else if (loader->stateless == VIR_TRISTATE_BOOL_NO) { - if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { - if (def->os.loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("Only pflash loader type permits NVRAM")); - return -1; - } - } else if (def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { - virReportError(VIR_ERR_XML_DETAIL, "%s", - _("Only EFI firmware permits NVRAM")); - return -1; - } - } - - if (loader->type == VIR_DOMAIN_LOADER_TYPE_ROM) { if (loader->format && loader->format != VIR_STORAGE_FILE_RAW) { virReportError(VIR_ERR_XML_DETAIL, @@ -1821,6 +1772,33 @@ virDomainDefOSValidate(const virDomainDef *def, } } + if (usesNvram && varstore) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Only one of NVRAM/varstore can be used")); + return -1; + } + + if (usesNvram || varstore) { + if (firmware && firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) { + virReportError(VIR_ERR_XML_DETAIL, + _("Firmware type '%1$s' does not support variable storage (NVRAM/varstore)"), + virDomainOsDefFirmwareTypeToString(firmware)); + return -1; + } + + if (loader && loader->stateless == VIR_TRISTATE_BOOL_YES) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Variable storage (NVRAM/varstore) is not permitted when loader is stateless")); + return -1; + } + + if (loader && loader->readonly == VIR_TRISTATE_BOOL_NO) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("Variable storage (NVRAM/varstore) is not permitted when loader is read/write")); + return -1; + } + } + if (def->os.shim && !def->os.kernel) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("shim only allowed with kernel option")); diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err index b058f970a4..743fe27a97 100644 --- a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err +++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.err @@ -1 +1 @@ -Only EFI firmware permits NVRAM +operation failed: Unable to find 'bios' firmware that is compatible with the current configuration diff --git a/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml new file mode 100644 index 0000000000..062835e351 --- /dev/null +++ b/tests/qemuxmlconfdata/firmware-auto-bios-not-stateless.x86_64-latest.xml @@ -0,0 +1,35 @@ + + guest + 63840878-0deb-4095-97e6-fc444d9bc9fa + 1048576 + 1048576 + 1 + + hvm + + + + + + + + qemu64 + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + +
+ + + + +