From 80ea1cf6be4ab916fc7e2f8bb2a93d5337b272ac Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Wed, 21 Sep 2016 07:46:25 +0200 Subject: [PATCH] qemu: Fix coldplug of vcpus virDomainDefSetVcpus was not designed to handle coldplug of vcpus now that we can set state of vcpus individually. Introduce qemuDomainSetVcpusConfig that properly handles state changes of vcpus when coldplugging so that invalid configurations are not created. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1375939 --- src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index db99c414d4..487bafc7d6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4901,6 +4901,58 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver, } +/** + * qemuDomainSetVcpusConfig: + * @def: config/offline definition of a domain + * @nvcpus: target vcpu count + * + * Properly handle cold(un)plug of vcpus: + * - plug in inactive vcpus/uplug active rather than rewriting state + * - fix hotpluggable state + */ +static void +qemuDomainSetVcpusConfig(virDomainDefPtr def, + unsigned int nvcpus) +{ + virDomainVcpuDefPtr vcpu; + size_t curvcpus = virDomainDefGetVcpus(def); + size_t maxvcpus = virDomainDefGetVcpusMax(def); + size_t i; + + + if (curvcpus == nvcpus) + return; + + if (curvcpus < nvcpus) { + for (i = 0; i < maxvcpus; i++) { + vcpu = virDomainDefGetVcpu(def, i); + + if (!vcpu || vcpu->online) + continue; + + vcpu->online = true; + vcpu->hotpluggable = VIR_TRISTATE_BOOL_NO; + + if (++curvcpus == nvcpus) + break; + } + } else { + for (i = maxvcpus; i != 0; i--) { + vcpu = virDomainDefGetVcpu(def, i - 1); + + if (!vcpu || !vcpu->online) + continue; + + vcpu->online = false; + vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES; + + if (--curvcpus == nvcpus) + break; + } + } +} + + static int qemuDomainSetVcpusInternal(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -4931,8 +4983,7 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver, goto cleanup; if (persistentDef) { - if (virDomainDefSetVcpus(persistentDef, nvcpus) < 0) - goto cleanup; + qemuDomainSetVcpusConfig(persistentDef, nvcpus); if (virDomainSaveConfig(cfg->configDir, driver->caps, persistentDef) < 0) goto cleanup; -- 2.47.2