]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: hotplug: Validate that vcpu-hotplug does not break config
authorPeter Krempa <pkrempa@redhat.com>
Fri, 31 Mar 2017 11:34:16 +0000 (13:34 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 4 Apr 2017 07:20:02 +0000 (09:20 +0200)
Make sure that non-hotpluggable vcpus stay clustered at the beginning
after modifying persistent definition.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1437010

src/qemu/qemu_hotplug.c

index 999c8b8049b3cce1318896fc6ea5997b36b16329..a6dac6f095ed25dd4b7d41a426fdad77867253e9 100644 (file)
@@ -5876,9 +5876,14 @@ qemuDomainFilterHotplugVcpuEntities(virDomainDefPtr def,
 
 
 static int
-qemuDomainVcpuValidateConfig(virBitmapPtr map,
+qemuDomainVcpuValidateConfig(virDomainDefPtr def,
+                             virBitmapPtr map,
                              bool state)
 {
+    virDomainVcpuDefPtr vcpu;
+    size_t maxvcpus = virDomainDefGetVcpusMax(def);
+    ssize_t next;
+
     /* vcpu 0 can't be disabled */
     if (!state && virBitmapIsBitSet(map, 0)) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -5886,6 +5891,23 @@ qemuDomainVcpuValidateConfig(virBitmapPtr map,
         return -1;
     }
 
+    /* non-hotpluggable vcpus need to stay clustered starting from vcpu 0 */
+    for (next = virBitmapNextSetBit(map, -1) + 1; next < maxvcpus; next++) {
+        if (!(vcpu = virDomainDefGetVcpu(def, next)))
+            continue;
+
+        /* skip vcpus being modified */
+        if (virBitmapIsBitSet(map, next))
+            continue;
+
+        if (vcpu->online && vcpu->hotpluggable == VIR_TRISTATE_BOOL_NO) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("vcpu '%zd' can't be modified as it is followed "
+                             "by non-hotpluggable online vcpus"), next);
+            return -1;
+        }
+    }
+
     return 0;
 }
 
@@ -5925,7 +5947,7 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver,
     }
 
     if (persistentDef) {
-        if (qemuDomainVcpuValidateConfig(map, state) < 0)
+        if (qemuDomainVcpuValidateConfig(persistentDef, map, state) < 0)
             goto cleanup;
     }