Now that NVRAM can be used together with ROM firmware builds, we need to update the matching logic so that it behaves correctly in all scenarios.
This effectively involves taking the logic we currently use when matching firmware descriptors for pflash builds and replicating it pretty much verbatim. The only real difference is that read/write loaders can, by definition, never match. Signed-off-by: Andrea Bolognani <[email protected]> --- src/qemu/qemu_firmware.c | 76 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 0504eef727..f56a4977cf 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1009,6 +1009,12 @@ qemuFirmwareMatchesPaths(const qemuFirmware *fw, if (loader && loader->path && !virFileComparePaths(loader->path, memory->executable.filename)) return false; + if (loader && loader->nvramTemplate) { + if (memory->mode != QEMU_FIRMWARE_MEMORY_MODE_SPLIT) + return false; + if (!virFileComparePaths(loader->nvramTemplate, memory->nvram_template.filename)) + return false; + } break; case QEMU_FIRMWARE_DEVICE_NONE: case QEMU_FIRMWARE_DEVICE_LAST: @@ -1457,32 +1463,88 @@ qemuFirmwareMatchDomain(const virDomainDef *def, } } } else if (fw->mapping.device == QEMU_FIRMWARE_DEVICE_MEMORY) { + const qemuFirmwareMappingMemory *memory = &fw->mapping.data.memory; + if (loader && loader->type && loader->type != VIR_DOMAIN_LOADER_TYPE_ROM) { VIR_DEBUG("Discarding rom loader"); return false; } - if (loader && loader->stateless == VIR_TRISTATE_BOOL_NO) { + /* Explicit requests for either a stateless or stateful + * firmware should be fulfilled, but if no preference is + * provided either one is fine as long as the other match + * criteria are satisfied */ + if (loader && + loader->stateless == VIR_TRISTATE_BOOL_NO && + memory->mode == QEMU_FIRMWARE_MEMORY_MODE_STATELESS) { VIR_DEBUG("Discarding stateless loader"); return false; } + if (loader && + loader->stateless == VIR_TRISTATE_BOOL_YES && + memory->mode != QEMU_FIRMWARE_MEMORY_MODE_STATELESS) { + VIR_DEBUG("Discarding non-stateless loader"); + return false; + } if (loader && loader->readonly == VIR_TRISTATE_BOOL_NO) { VIR_DEBUG("Discarding readonly loader"); return false; } - if (loader && loader->nvram && - (loader->nvram->path || loader->nvram->format)) { - VIR_DEBUG("Discarding rom loader (nvram configured)"); + if (STRNEQ(memory->executable.format, "raw")) { + VIR_DEBUG("Discarding loader with unsupported executable format '%s'", + memory->executable.format); return false; } - if (loader && - (loader->nvramTemplate || loader->nvramTemplateFormat)) { - VIR_DEBUG("Discarding rom loader (nvram template configured)"); + if (loader && loader->format && + STRNEQ(memory->executable.format, virStorageFileFormatTypeToString(loader->format))) { + VIR_DEBUG("Discarding loader with mismatching executable format '%s' != '%s'", + memory->executable.format, + virStorageFileFormatTypeToString(loader->format)); return false; } + if (memory->mode == QEMU_FIRMWARE_MEMORY_MODE_SPLIT) { + if (STRNEQ(memory->nvram_template.format, "json")) { + VIR_DEBUG("Discarding loader with unsupported nvram template format '%s'", + memory->nvram_template.format); + return false; + } + if (loader && loader->nvramTemplateFormat && + STRNEQ(memory->nvram_template.format, virStorageFileFormatTypeToString(loader->nvramTemplateFormat))) { + VIR_DEBUG("Discarding loader with mismatching nvram template format '%s' != '%s'", + memory->nvram_template.format, + virStorageFileFormatTypeToString(loader->format)); + return false; + } + /* If nvram.format was specified and no other information + * that can influence firmware selection was, then treat it + * the same as if nvram.templateFormat had been specified. + * This ensures that <nvram format='foo'/> continues to work + * as a shorthand while not getting in the way otherwise */ + if (loader && loader->nvram && loader->nvram->format && + !loader->readonly && !loader->type && !loader->secure && + !loader->stateless && !loader->format && !loader->path && + !loader->nvramTemplateFormat && !loader->nvramTemplate && + STRNEQ(memory->nvram_template.format, virStorageFileFormatTypeToString(loader->nvram->format))) { + VIR_DEBUG("Discarding loader with mismatching nvram template format '%s' != '%s'", + memory->nvram_template.format, + virStorageFileFormatTypeToString(loader->nvram->format)); + return false; + } + } else { + if (loader && loader->nvram && + (loader->nvram->path || loader->nvram->format)) { + VIR_DEBUG("Discarding non split loader (nvram configured)"); + return false; + } + if (loader && + (loader->nvramTemplate || loader->nvramTemplateFormat)) { + VIR_DEBUG("Discarding non split loader (nvram template configured)"); + return false; + } + } } if (def->sec) { -- 2.52.0
