qemu: Prepare for reuse of qemuDomainSetVcpusLive

Extract the call to qemuDomainSelectHotplugVcpuEntities outside of
qemuDomainSetVcpusLive and decide whether to hotplug or unplug the
entities specified by the cpumap using a boolean flag.

This will allow to use qemuDomainSetVcpusLive in cases where we prepare
the list of vcpus to enable or disable by other means.
This commit is contained in:
Peter Krempa 2016-11-09 15:03:34 +01:00
parent fa755dd59a
commit 5570f26763

View File

@ -4784,6 +4784,7 @@ qemuDomainSetVcpusMax(virQEMUDriverPtr driver,
* *
* @def: domain definition * @def: domain definition
* @nvcpus: target vcpu count * @nvcpus: target vcpu count
* @enable: set to true if vcpus should be enabled
* *
* Tries to find which vcpu entities need to be enabled or disabled to reach * Tries to find which vcpu entities need to be enabled or disabled to reach
* @nvcpus. This function works in order of the legacy hotplug but is able to * @nvcpus. This function works in order of the legacy hotplug but is able to
@ -4793,7 +4794,8 @@ qemuDomainSetVcpusMax(virQEMUDriverPtr driver,
*/ */
static virBitmapPtr static virBitmapPtr
qemuDomainSelectHotplugVcpuEntities(virDomainDefPtr def, qemuDomainSelectHotplugVcpuEntities(virDomainDefPtr def,
unsigned int nvcpus) unsigned int nvcpus,
bool *enable)
{ {
virBitmapPtr ret = NULL; virBitmapPtr ret = NULL;
virDomainVcpuDefPtr vcpu; virDomainVcpuDefPtr vcpu;
@ -4806,6 +4808,8 @@ qemuDomainSelectHotplugVcpuEntities(virDomainDefPtr def,
return NULL; return NULL;
if (nvcpus > curvcpus) { if (nvcpus > curvcpus) {
*enable = true;
for (i = 0; i < maxvcpus && curvcpus < nvcpus; i++) { for (i = 0; i < maxvcpus && curvcpus < nvcpus; i++) {
vcpu = virDomainDefGetVcpu(def, i); vcpu = virDomainDefGetVcpu(def, i);
vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu); vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
@ -4828,6 +4832,8 @@ qemuDomainSelectHotplugVcpuEntities(virDomainDefPtr def,
ignore_value(virBitmapSetBit(ret, i)); ignore_value(virBitmapSetBit(ret, i));
} }
} else { } else {
*enable = false;
for (i = maxvcpus - 1; i >= 0 && curvcpus > nvcpus; i--) { for (i = maxvcpus - 1; i >= 0 && curvcpus > nvcpus; i--) {
vcpu = virDomainDefGetVcpu(def, i); vcpu = virDomainDefGetVcpu(def, i);
vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu); vcpupriv = QEMU_DOMAIN_VCPU_PRIVATE(vcpu);
@ -4873,22 +4879,19 @@ static int
qemuDomainSetVcpusLive(virQEMUDriverPtr driver, qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
virQEMUDriverConfigPtr cfg, virQEMUDriverConfigPtr cfg,
virDomainObjPtr vm, virDomainObjPtr vm,
unsigned int nvcpus) virBitmapPtr vcpumap,
bool enable)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL; qemuCgroupEmulatorAllNodesDataPtr emulatorCgroup = NULL;
virBitmapPtr vcpumap = NULL;
ssize_t nextvcpu = -1; ssize_t nextvcpu = -1;
int rc = 0; int rc = 0;
int ret = -1; int ret = -1;
if (!(vcpumap = qemuDomainSelectHotplugVcpuEntities(vm->def, nvcpus)))
goto cleanup;
if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0) if (qemuCgroupEmulatorAllNodesAllow(priv->cgroup, &emulatorCgroup) < 0)
goto cleanup; goto cleanup;
if (nvcpus > virDomainDefGetVcpus(vm->def)) { if (enable) {
while ((nextvcpu = virBitmapNextSetBit(vcpumap, nextvcpu)) != -1) { while ((nextvcpu = virBitmapNextSetBit(vcpumap, nextvcpu)) != -1) {
if ((rc = qemuDomainHotplugAddVcpu(driver, vm, nextvcpu)) < 0) if ((rc = qemuDomainHotplugAddVcpu(driver, vm, nextvcpu)) < 0)
break; break;
@ -4915,7 +4918,6 @@ qemuDomainSetVcpusLive(virQEMUDriverPtr driver,
cleanup: cleanup:
qemuCgroupEmulatorAllNodesRestore(emulatorCgroup); qemuCgroupEmulatorAllNodesRestore(emulatorCgroup);
virBitmapFree(vcpumap);
return ret; return ret;
} }
@ -5001,6 +5003,8 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver,
bool hotpluggable) bool hotpluggable)
{ {
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virBitmapPtr vcpumap = NULL;
bool enable;
int ret = -1; int ret = -1;
if (def && nvcpus > virDomainDefGetVcpusMax(def)) { if (def && nvcpus > virDomainDefGetVcpusMax(def)) {
@ -5019,8 +5023,14 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (def && qemuDomainSetVcpusLive(driver, cfg, vm, nvcpus) < 0) if (def) {
goto cleanup; if (!(vcpumap = qemuDomainSelectHotplugVcpuEntities(vm->def, nvcpus,
&enable)))
goto cleanup;
if (qemuDomainSetVcpusLive(driver, cfg, vm, vcpumap, enable) < 0)
goto cleanup;
}
if (persistentDef) { if (persistentDef) {
qemuDomainSetVcpusConfig(persistentDef, nvcpus, hotpluggable); qemuDomainSetVcpusConfig(persistentDef, nvcpus, hotpluggable);
@ -5032,6 +5042,7 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
virBitmapFree(vcpumap);
virObjectUnref(cfg); virObjectUnref(cfg);
return ret; return ret;
} }