]> xenbits.xensource.com Git - people/dariof/libvirt.git/commitdiff
qemu: Allow migration to be cancelled at prepare phase
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 8 Nov 2012 13:49:55 +0000 (14:49 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 12 Nov 2012 09:39:39 +0000 (10:39 +0100)
Currently, if user calls virDomainAbortJob we just issue
'migrate_cancel' and hope for the best. However, if user calls
the API in wrong phase when migration hasn't been started yet
(perform phase) the cancel request is just ignored. With this
patch, the request is remembered and as soon as perform phase
starts, migration is cancelled.

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

index a5592b92c8d27338d234448f4e350176829f4f7e..e0d6951e86baaea0c2425e435a889d0dc8f4ead8 100644 (file)
@@ -160,6 +160,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
     job->mask = DEFAULT_JOB_MASK;
     job->start = 0;
     job->dump_memory_only = false;
+    job->asyncAbort = false;
     memset(&job->info, 0, sizeof(job->info));
 }
 
@@ -959,6 +960,17 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj)
     return virObjectUnref(obj);
 }
 
+void
+qemuDomainObjAbortAsyncJob(virDomainObjPtr obj)
+{
+    qemuDomainObjPrivatePtr priv = obj->privateData;
+
+    VIR_DEBUG("Requesting abort of async job: %s",
+              qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
+
+    priv->job.asyncAbort = true;
+}
+
 static int
 qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver,
                                   bool driver_locked,
index 9c2f67c7a758a3d7df5afce57d886832365d1f8f..a2acc0ad1868c62d2c2b2c4c8f4b1ec34126983d 100644 (file)
@@ -111,6 +111,7 @@ struct qemuDomainJobObj {
     unsigned long long start;           /* When the async job started */
     bool dump_memory_only;              /* use dump-guest-memory to do dump */
     virDomainJobInfo info;              /* Async job progress data */
+    bool asyncAbort;                    /* abort of async job requested */
 };
 
 typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
@@ -204,6 +205,7 @@ bool qemuDomainObjEndJob(struct qemud_driver *driver,
 bool qemuDomainObjEndAsyncJob(struct qemud_driver *driver,
                               virDomainObjPtr obj)
     ATTRIBUTE_RETURN_CHECK;
+void qemuDomainObjAbortAsyncJob(virDomainObjPtr obj);
 void qemuDomainObjSetJobPhase(struct qemud_driver *driver,
                               virDomainObjPtr obj,
                               int phase);
index 3279a99f4b01e023a50e2e62f91b0208176a2c09..5556f1e5953fa25697eee325065888c27e0bc3ec 100644 (file)
@@ -10397,6 +10397,7 @@ static int qemuDomainAbortJob(virDomainPtr dom) {
     }
 
     VIR_DEBUG("Cancelling job at client request");
+    qemuDomainObjAbortAsyncJob(vm);
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorMigrateCancel(priv->mon);
     qemuDomainObjExitMonitor(driver, vm);
index 5f8a9c587f068cbf02cb25716e9291745db7032b..0a52486437f306b5a9e4489ae56f4167a63ab9a8 100644 (file)
@@ -2168,6 +2168,17 @@ qemuMigrationRun(struct qemud_driver *driver,
                                        QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
         goto cleanup;
 
+    if (priv->job.asyncAbort) {
+        /* explicitly do this *after* we entered the monitor,
+         * as this is a critical section so we are guaranteed
+         * priv->job.asyncAbort will not change */
+        qemuDomainObjExitMonitorWithDriver(driver, vm);
+        virReportError(VIR_ERR_OPERATION_ABORTED, _("%s: %s"),
+                       qemuDomainAsyncJobTypeToString(priv->job.asyncJob),
+                       _("canceled by client"));
+        goto cleanup;
+    }
+
     if (qemuMonitorSetMigrationSpeed(priv->mon, migrate_speed) < 0) {
         qemuDomainObjExitMonitorWithDriver(driver, vm);
         goto cleanup;