[libvirt] [PATCH 4/7] qemu: Unite error handling in qemuMigrationRun

Jiri Denemark jdenemar at redhat.com
Thu Oct 19 13:56:29 UTC 2017


Merge cancel and cancelPostCopy sections with the generic error section,
where we can easily decide whether canceling the ongoing migration is
required.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/qemu/qemu_migration.c | 61 ++++++++++++++++++++++-------------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 6956901be..cbf255704 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3616,7 +3616,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
     unsigned int cookieFlags = 0;
     bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
     bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
-    bool inPostCopy = false;
+    bool cancel = false;
     unsigned int waitFlags;
     virDomainDefPtr persistDef = NULL;
     char *timestamp;
@@ -3822,10 +3822,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
 
     /* From this point onwards we *must* call cancel to abort the
      * migration on source if anything goes wrong */
+    cancel = true;
 
     if (spec->fwdType != MIGRATION_FWD_DIRECT) {
         if (!(iothread = qemuMigrationStartTunnel(spec->fwd.stream, fd)))
-            goto cancel;
+            goto error;
         /* If we've created a tunnel, then the 'fd' will be closed in the
          * qemuMigrationIOFunc as data->sock.
          */
@@ -3843,13 +3844,18 @@ qemuMigrationRun(virQEMUDriverPtr driver,
     rc = qemuMigrationWaitForCompletion(driver, vm,
                                         QEMU_ASYNC_JOB_MIGRATION_OUT,
                                         dconn, waitFlags);
-    if (rc == -2)
-        goto cancel;
-    else if (rc == -1)
+    if (rc == -2) {
         goto error;
+    } else if (rc == -1) {
+        /* QEMU reported failed migration, nothing to cancel anymore */
+        cancel = false;
+        goto error;
+    }
 
-    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
-        inPostCopy = true;
+    if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED) {
+        /* QEMU finished migration, nothing to cancel anymore */
+        cancel = false;
+    }
 
     /* When migration completed, QEMU will have paused the CPUs for us.
      * Wait for the STOP event to be processed or explicitly stop CPUs
@@ -3861,25 +3867,25 @@ qemuMigrationRun(virQEMUDriverPtr driver,
             rc = virDomainObjWait(vm);
             priv->signalStop = false;
             if (rc < 0)
-                goto cancelPostCopy;
+                goto error;
         }
     } else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
                qemuMigrationSetOffline(driver, vm) < 0) {
-        goto cancelPostCopy;
+        goto error;
     }
 
     if (mig && mig->nbd &&
         qemuMigrationCancelDriveMirror(driver, vm, true,
                                        QEMU_ASYNC_JOB_MIGRATION_OUT,
                                        dconn) < 0)
-        goto cancelPostCopy;
+        goto error;
 
     if (iothread) {
         qemuMigrationIOThreadPtr io;
 
         VIR_STEAL_PTR(io, iothread);
         if (qemuMigrationStopTunnel(io, false) < 0)
-            goto cancelPostCopy;
+            goto error;
     }
 
     if (priv->job.completed) {
@@ -3919,8 +3925,15 @@ qemuMigrationRun(virQEMUDriverPtr driver,
     return ret;
 
  error:
-    if (!orig_err)
-        orig_err = virSaveLastError();
+    orig_err = virSaveLastError();
+
+    if (cancel &&
+        virDomainObjIsActive(vm) &&
+        qemuDomainObjEnterMonitorAsync(driver, vm,
+                                       QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
+        qemuMonitorMigrateCancel(priv->mon);
+        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    }
 
     /* cancel any outstanding NBD jobs */
     if (mig && mig->nbd)
@@ -3932,7 +3945,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
         qemuMigrationStopTunnel(iothread, true);
 
     if (priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_ACTIVE ||
-        priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING)
+        priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_MIGRATING ||
+        priv->job.current->status == QEMU_DOMAIN_JOB_STATUS_POSTCOPY)
         priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
 
     goto cleanup;
@@ -3940,25 +3954,6 @@ qemuMigrationRun(virQEMUDriverPtr driver,
  exit_monitor:
     ignore_value(qemuDomainObjExitMonitor(driver, vm));
     goto error;
-
- cancel:
-    orig_err = virSaveLastError();
-
-    if (virDomainObjIsActive(vm)) {
-        if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                           QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
-            qemuMonitorMigrateCancel(priv->mon);
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
-        }
-    }
-    goto error;
-
- cancelPostCopy:
-    priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_FAILED;
-    if (inPostCopy)
-        goto cancel;
-    else
-        goto error;
 }
 
 /* Perform migration using QEMU's native migrate support,
-- 
2.14.2




More information about the libvir-list mailing list