]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: migration: Prepare for non-contiguous vcpu configurations
authorPeter Krempa <pkrempa@redhat.com>
Thu, 4 Aug 2016 11:57:46 +0000 (13:57 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 24 Aug 2016 19:44:47 +0000 (15:44 -0400)
Introduce a new migration cookie flag that will be used for any
configurations that are not compatible with libvirt that would not
support the specific vcpu hotplug approach. This will make sure that old
libvirt does not fail to reproduce the configuration correctly.

src/qemu/qemu_domain.c
src/qemu/qemu_domain.h
src/qemu/qemu_migration.c

index 5f4c642143752c47e8498eb7c1bfe9cb70f1f886..69e1e381be3bb6f52e12e3c263679002e1612d19 100644 (file)
@@ -5964,3 +5964,38 @@ qemuDomainPrepareChannel(virDomainChrDefPtr channel,
 
     return 0;
 }
+
+
+/**
+ * qemuDomainVcpuHotplugIsInOrder:
+ * @def: domain definition
+ *
+ * Returns true if online vcpus were added in order (clustered behind vcpu0
+ * with increasing order).
+ */
+bool
+qemuDomainVcpuHotplugIsInOrder(virDomainDefPtr def)
+{
+    size_t maxvcpus = virDomainDefGetVcpusMax(def);
+    virDomainVcpuDefPtr vcpu;
+    unsigned int prevorder = 0;
+    size_t seenonlinevcpus = 0;
+    size_t i;
+
+    for (i = 0; i < maxvcpus; i++) {
+        vcpu = virDomainDefGetVcpu(def, i);
+
+        if (!vcpu->online)
+            break;
+
+        if (vcpu->order < prevorder)
+            break;
+
+        if (vcpu->order > prevorder)
+            prevorder = vcpu->order;
+
+        seenonlinevcpus++;
+    }
+
+    return seenonlinevcpus == virDomainDefGetVcpus(def);
+}
index b4b3daef36fc973d113c44c657adb3086b6d3747..b873a8b49bc38ea43df4beb9d84a1da991a63728 100644 (file)
@@ -722,4 +722,7 @@ int qemuDomainPrepareChannel(virDomainChrDefPtr chr,
                              const char *domainChannelTargetDir)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
+bool qemuDomainVcpuHotplugIsInOrder(virDomainDefPtr def)
+    ATTRIBUTE_NONNULL(1);
+
 #endif /* __QEMU_DOMAIN_H__ */
index cf2125d5d30887d0e808485fc0a2459e945c2f4a..e451ef6f876b5e0ac89c3a48282300e7bd9b13ba 100644 (file)
@@ -92,6 +92,7 @@ enum qemuMigrationCookieFlags {
     QEMU_MIGRATION_COOKIE_FLAG_NBD,
     QEMU_MIGRATION_COOKIE_FLAG_STATS,
     QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG,
+    QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG,
 
     QEMU_MIGRATION_COOKIE_FLAG_LAST
 };
@@ -105,7 +106,8 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag,
               "network",
               "nbd",
               "statistics",
-              "memory-hotplug");
+              "memory-hotplug",
+              "cpu-hotplug");
 
 enum qemuMigrationCookieFeatures {
     QEMU_MIGRATION_COOKIE_GRAPHICS  = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
@@ -115,6 +117,7 @@ enum qemuMigrationCookieFeatures {
     QEMU_MIGRATION_COOKIE_NBD = (1 << QEMU_MIGRATION_COOKIE_FLAG_NBD),
     QEMU_MIGRATION_COOKIE_STATS = (1 << QEMU_MIGRATION_COOKIE_FLAG_STATS),
     QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG),
+    QEMU_MIGRATION_COOKIE_CPU_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG),
 };
 
 typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -1408,6 +1411,9 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
     if (flags & QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG)
         mig->flagsMandatory |= QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG;
 
+    if (flags & QEMU_MIGRATION_COOKIE_CPU_HOTPLUG)
+        mig->flagsMandatory |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG;
+
     if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
         return -1;
 
@@ -3191,6 +3197,11 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
          vm->newDef && virDomainDefHasMemoryHotplug(vm->newDef)))
         cookieFlags |= QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG;
 
+    if (!qemuDomainVcpuHotplugIsInOrder(vm->def) ||
+        ((flags & VIR_MIGRATE_PERSIST_DEST) &&
+         vm->newDef && !qemuDomainVcpuHotplugIsInOrder(vm->newDef)))
+        cookieFlags |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG;
+
     if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
         goto cleanup;
 
@@ -3686,7 +3697,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
     if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
                                        QEMU_MIGRATION_COOKIE_LOCKSTATE |
                                        QEMU_MIGRATION_COOKIE_NBD |
-                                       QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG)))
+                                       QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG |
+                                       QEMU_MIGRATION_COOKIE_CPU_HOTPLUG)))
         goto cleanup;
 
     if (STREQ_NULLABLE(protocol, "rdma") &&