From 7e9d1801009613be3313025363380d4598fab702 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 8 Dec 2020 14:27:59 +0100 Subject: [PATCH] qemu: validate: Prefer existing qemuCaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The validation callback always fetched a fresh copy of 'qemuCaps' to use for validation which is wrong in cases when the VM is already running, such as device hotplug. The newly-fetched qemuCaps may contain flags which weren't originally in use when starting the VM e.g. on a libvirtd upgrade. Since the post-parse/validation machinery has a per-run 'parseOpaque' field filled with qemuCaps of the actual process we can reuse the caps in cases when we get them. The code still fetches a fresh copy if parseOpaque doesn't have a per-run copy to preserve existing functionality. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- src/qemu/qemu_validate.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index cb0f830cf1..bf8127a575 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1067,16 +1067,21 @@ qemuValidateDomainDefPanic(const virDomainDef *def, int qemuValidateDomainDef(const virDomainDef *def, void *opaque, - void *parseOpaque G_GNUC_UNUSED) + void *parseOpaque) { virQEMUDriverPtr driver = opaque; g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); - g_autoptr(virQEMUCaps) qemuCaps = NULL; + g_autoptr(virQEMUCaps) qemuCapsLocal = NULL; + virQEMUCapsPtr qemuCaps = parseOpaque; size_t i; - if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, - def->emulator))) - return -1; + if (!qemuCaps) { + if (!(qemuCapsLocal = virQEMUCapsCacheLookup(driver->qemuCapsCache, + def->emulator))) + return -1; + + qemuCaps = qemuCapsLocal; + } if (def->os.type != VIR_DOMAIN_OSTYPE_HVM) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -4666,15 +4671,20 @@ int qemuValidateDomainDeviceDef(const virDomainDeviceDef *dev, const virDomainDef *def, void *opaque, - void *parseOpaque G_GNUC_UNUSED) + void *parseOpaque) { int ret = 0; virQEMUDriverPtr driver = opaque; - g_autoptr(virQEMUCaps) qemuCaps = NULL; + g_autoptr(virQEMUCaps) qemuCapsLocal = NULL; + virQEMUCapsPtr qemuCaps = parseOpaque; - if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, - def->emulator))) - return -1; + if (!qemuCaps) { + if (!(qemuCapsLocal = virQEMUCapsCacheLookup(driver->qemuCapsCache, + def->emulator))) + return -1; + + qemuCaps = qemuCapsLocal; + } if ((ret = qemuValidateDomainDeviceDefAddress(dev, qemuCaps)) < 0) return ret;