[libvirt] [PATCH 04/11] qemu: implemented post-copy migration logic

Cristian Klein cristiklein at gmail.com
Mon Dec 1 15:59:56 UTC 2014


Perform phase stops once migration switched to post-copy.
Confirm phase waits for post-copy to finish before killing the VM.

Signed-off-by: Cristian Klein <cristiklein at gmail.com>
---
 src/qemu/qemu_driver.c    |  8 ++++++++
 src/qemu/qemu_migration.c | 46 +++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 07da3e3..06803b4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11348,6 +11348,14 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
+    if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) {
+        /* post-copy migration does not work with Sequence v2 */
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Post-copy migration requested but not "
+                         "supported by v2 protocol"));
+        goto cleanup;
+    }
+
     if (flags & VIR_MIGRATE_TUNNELLED) {
         /* this is a logical error; we never should have gotten here with
          * VIR_MIGRATE_TUNNELLED set
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index ede938b..137ddfa 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2074,6 +2074,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
         ret = 0;
         break;
 
+    case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_ACTIVE:
+        jobInfo->type = VIR_DOMAIN_JOB_BOUNDED;
+        ret = 0;
+        break;
+
     case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
         jobInfo->type = VIR_DOMAIN_JOB_NONE;
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -2106,7 +2111,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
                                qemuDomainAsyncJob asyncJob,
                                virConnectPtr dconn,
-                               bool abort_on_error)
+                               bool abort_on_error,
+                               bool exit_on_postcopy_active)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuDomainJobInfoPtr jobInfo = priv->job.current;
@@ -2129,7 +2135,9 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
 
     jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
 
-    while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
+    while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED ||
+           (!exit_on_postcopy_active &&
+            jobInfo->type == VIR_DOMAIN_JOB_BOUNDED)) {
         /* Poll every 50ms for progress & to allow cancellation */
         struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
 
@@ -2158,7 +2166,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
         virObjectLock(vm);
     }
 
-    if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED) {
+    if (jobInfo->type == VIR_DOMAIN_JOB_COMPLETED ||
+        jobInfo->type == VIR_DOMAIN_JOB_BOUNDED) {
         qemuDomainJobInfoUpdateDowntime(jobInfo);
         VIR_FREE(priv->job.completed);
         if (VIR_ALLOC(priv->job.completed) == 0)
@@ -3190,6 +3199,18 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver,
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
+    /* Wait for post-copy to complete */
+    if (flags & VIR_MIGRATE_ENABLE_POSTCOPY) {
+        bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
+        bool exit_on_postcopy_active = false;
+        rv = qemuMigrationWaitForCompletion(driver, vm,
+                                            QEMU_ASYNC_JOB_MIGRATION_OUT,
+                                            conn, abort_on_error,
+                                            exit_on_postcopy_active);
+        if (rv < 0)
+            goto cleanup;
+    }
+
     qemuMigrationJobSetPhase(driver, vm,
                              retcode == 0
                              ? QEMU_MIGRATION_PHASE_CONFIRM3
@@ -3786,9 +3807,14 @@ qemuMigrationRun(virQEMUDriverPtr driver,
         !(iothread = qemuMigrationStartTunnel(spec->fwd.stream, fd)))
         goto cancel;
 
-    rc = qemuMigrationWaitForCompletion(driver, vm,
-                                        QEMU_ASYNC_JOB_MIGRATION_OUT,
-                                        dconn, abort_on_error);
+    {
+        bool exit_on_postcopy_active = true;
+        rc = qemuMigrationWaitForCompletion(driver, vm,
+                                            QEMU_ASYNC_JOB_MIGRATION_OUT,
+                                            dconn, abort_on_error,
+                                            exit_on_postcopy_active);
+    }
+
     if (rc == -2)
         goto cancel;
     else if (rc == -1)
@@ -5251,7 +5277,13 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
     if (rc < 0)
         goto cleanup;
 
-    rc = qemuMigrationWaitForCompletion(driver, vm, asyncJob, NULL, false);
+    {
+        bool abort_on_error = false;
+        bool exit_on_postcopy_active = true;
+        rc = qemuMigrationWaitForCompletion(driver, vm, asyncJob, NULL,
+                                            abort_on_error,
+                                            exit_on_postcopy_active);
+    }
 
     if (rc < 0) {
         if (rc == -2) {
-- 
1.9.1




More information about the libvir-list mailing list