[libvirt] [PATCH v2 6/8] Implemented post-copy migration logic in qemu

Cristian Klein cristian.klein at cs.umu.se
Tue Sep 30 14:39:27 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 <cristian.klein at cs.umu.se>
---
 src/qemu/qemu_driver.c    |  8 ++++++++
 src/qemu/qemu_migration.c | 25 ++++++++++++++++++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e873d45..3fe2216 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10942,6 +10942,14 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
+    if (flags & VIR_MIGRATE_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 4a36946..436b701 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2039,6 +2039,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
         ret = 0;
         break;
 
+    case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_ACTIVE:
+        jobInfo->type = VIR_DOMAIN_JOB_PHASE1_COMPLETED;
+        ret = 0;
+        break;
+
     case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
         jobInfo->type = VIR_DOMAIN_JOB_NONE;
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -2077,6 +2082,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
     qemuDomainJobInfoPtr jobInfo = priv->job.current;
     const char *job;
     int pauseReason;
+    bool inPhase2 = (jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED);
 
     switch (priv->job.asyncJob) {
     case QEMU_ASYNC_JOB_MIGRATION_OUT:
@@ -2092,9 +2098,11 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
         job = _("job");
     }
 
-    jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
+    if (!inPhase2)
+        jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
 
-    while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
+    while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED ||
+           (inPhase2 && jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED)) {
         /* Poll every 50ms for progress & to allow cancellation */
         struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
 
@@ -2123,7 +2131,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_PHASE1_COMPLETED) {
         qemuDomainJobInfoUpdateDowntime(jobInfo);
         VIR_FREE(priv->job.completed);
         if (VIR_ALLOC(priv->job.completed) == 0)
@@ -3149,6 +3158,16 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver,
 
     virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
 
+    /* Wait for post-copy to complete */
+    if (flags & VIR_MIGRATE_POSTCOPY) {
+        bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
+        rv = qemuMigrationWaitForCompletion(driver, vm,
+                                            QEMU_ASYNC_JOB_MIGRATION_OUT,
+                                            conn, abort_on_error);
+        if (rv < 0)
+            goto cleanup;
+    }
+
     qemuMigrationJobSetPhase(driver, vm,
                              retcode == 0
                              ? QEMU_MIGRATION_PHASE_CONFIRM3
-- 
1.9.1




More information about the libvir-list mailing list