Blob Blame History Raw
From 6e1a906b835301aef822702b62b11969ae4d0f26 Mon Sep 17 00:00:00 2001
Message-Id: <6e1a906b835301aef822702b62b11969ae4d0f26@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 24 Aug 2016 16:11:34 -0400
Subject: [PATCH] qemu: migration: Prepare for non-contiguous vcpu
 configurations

https://bugzilla.redhat.com/show_bug.cgi?id=1097930
https://bugzilla.redhat.com/show_bug.cgi?id=1224341

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.

(cherry picked from commit 48e3d42889dcf3f7cec24c0bf4fd55c8da5f324b)
---
 src/qemu/qemu_domain.c    | 35 +++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h    |  3 +++
 src/qemu/qemu_migration.c | 16 ++++++++++++++--
 3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7a71bfb..07c42a0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5914,3 +5914,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);
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 76b6904..3a80769 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -724,4 +724,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__ */
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 463e624..ae70f2a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -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;
 
@@ -3195,6 +3201,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;
 
@@ -3690,7 +3701,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") &&
-- 
2.10.0