]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Fix coldplug of vcpus
authorPeter Krempa <pkrempa@redhat.com>
Wed, 21 Sep 2016 05:46:25 +0000 (07:46 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 30 Sep 2016 06:25:20 +0000 (08:25 +0200)
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

index db99c414d4586f42c13e0d1ed1f4def394cf5821..487bafc7d6e3e7eb2940cdcce2d84c9ad99ce734 100644 (file)
@@ -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;