]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Fix peer2peer migration with transient VMs
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 19 May 2011 11:48:15 +0000 (07:48 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 24 May 2011 09:41:23 +0000 (05:41 -0400)
The qemuMigrationConfirm method shouldn't deal with final VM
cleanup, since it can be called from the peer2peer migration,
which expects to still use the 'vm' object afterwards.

Push the cleanup code out of qemuMigrationConfirm, into its
caller, qemuDomainMigrateConfirm3

* src/qemu/qemu_driver.c: Add VM cleanup code to
  qemuDomainMigrateConfirm3
* src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Remove
  job handling cleanup from qemuMigrationConfirm

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

index 691965d1984972ed50c3b9f99d608713efbd43fc..db299a2b773c84ae046b5a970a79be0807d35cd1 100644 (file)
@@ -6284,6 +6284,7 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
     struct qemud_driver *driver = domain->conn->privateData;
     virDomainObjPtr vm;
     int ret = -1;
+    virErrorPtr orig_err;
 
     virCheckFlags(VIR_MIGRATE_LIVE |
                   VIR_MIGRATE_PEER2PEER |
@@ -6304,11 +6305,33 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
         goto cleanup;
     }
 
+    if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
+        goto cleanup;
+
     ret = qemuMigrationConfirm(driver, domain->conn, vm,
                                cookiein, cookieinlen,
-                               flags, cancelled, false);
+                               flags, cancelled);
+
+    orig_err = virSaveLastError();
+
+    if (qemuDomainObjEndJob(vm) == 0) {
+        vm = NULL;
+    } else if (!virDomainObjIsActive(vm) &&
+               (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
+        if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
+            virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
+        virDomainRemoveInactive(&driver->domains, vm);
+        vm = NULL;
+    }
+
+    if (orig_err) {
+        virSetError(orig_err);
+        virFreeError(orig_err);
+    }
 
 cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
     qemuDriverUnlock(driver);
     return ret;
 }
index cc9f6fb4a422eb82e15d8757eaa968a3ada2cceb..97138b5665cb7327a5f9ce91c86e205b5ba1e161 100644 (file)
@@ -1911,7 +1911,7 @@ finish:
     cookieoutlen = 0;
     ret = qemuMigrationConfirm(driver, sconn, vm,
                                cookiein, cookieinlen,
-                               flags, cancelled, true);
+                               flags, cancelled);
     /* If Confirm3 returns -1, there's nothing more we can
      * do, but fortunately worst case is that there is a
      * domain left in 'paused' state on source.
@@ -2067,12 +2067,6 @@ int qemuMigrationPerform(struct qemud_driver *driver,
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_STOPPED,
                                          VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
-        if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
-            virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
-            if (qemuDomainObjEndJob(vm) > 0)
-                virDomainRemoveInactive(&driver->domains, vm);
-            vm = NULL;
-        }
     }
 
     ret = 0;
@@ -2094,9 +2088,17 @@ endjob:
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
     }
-    if (vm &&
-        qemuDomainObjEndJob(vm) == 0)
-        vm = NULL;
+    if (vm) {
+        if (qemuDomainObjEndJob(vm) == 0) {
+            vm = NULL;
+        } else if (!virDomainObjIsActive(vm) &&
+                   (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE))) {
+            if (flags & VIR_MIGRATE_UNDEFINE_SOURCE)
+                virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
+            virDomainRemoveInactive(&driver->domains, vm);
+            vm = NULL;
+        }
+    }
 
 cleanup:
     if (vm)
@@ -2287,9 +2289,8 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
                          virDomainObjPtr vm,
                          const char *cookiein,
                          int cookieinlen,
-                         unsigned int flags,
-                         int retcode,
-                         bool skipJob)
+                         unsigned int flags ATTRIBUTE_UNUSED,
+                         int retcode)
 {
     qemuMigrationCookiePtr mig;
     virDomainEventPtr event = NULL;
@@ -2298,14 +2299,10 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
     if (!(mig = qemuMigrationEatCookie(vm, cookiein, cookieinlen, 0)))
         return -1;
 
-    if (!skipJob &&
-        qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
-        goto cleanup;
-
     if (!virDomainObjIsActive(vm)) {
         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                         _("guest unexpectedly quit"));
-        goto endjob;
+        goto cleanup;
     }
 
     /* Did the migration go as planned?  If yes, kill off the
@@ -2318,12 +2315,6 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_STOPPED,
                                          VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
-        if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
-            virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm);
-            if (qemuDomainObjEndJob(vm) > 0)
-                virDomainRemoveInactive(&driver->domains, vm);
-            vm = NULL;
-        }
     } else {
 
         /* run 'cont' on the destination, which allows migration on qemu
@@ -2335,7 +2326,7 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
             if (virGetLastError() == NULL)
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
                                 "%s", _("resume operation failed"));
-            goto endjob;
+            goto cleanup;
         }
 
         event = virDomainEventNewFromObj(vm,
@@ -2343,22 +2334,14 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
                                          VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
         if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
             VIR_WARN("Failed to save status on vm %s", vm->def->name);
-            goto endjob;
+            goto cleanup;
         }
     }
 
     qemuMigrationCookieFree(mig);
     rv = 0;
 
-endjob:
-    if (vm &&
-        !skipJob &&
-        qemuDomainObjEndJob(vm) == 0)
-        vm = NULL;
-
 cleanup:
-    if (vm)
-        virDomainObjUnlock(vm);
     if (event)
         qemuDomainEventQueue(driver, event);
     return rv;
index f96a0b8849354d0f68dd67ea06f6b4a33ca89711..781e58cefff00ed57e1d195d3e3dbaf108762959 100644 (file)
@@ -87,8 +87,7 @@ int qemuMigrationConfirm(struct qemud_driver *driver,
                          const char *cookiein,
                          int cookieinlen,
                          unsigned int flags,
-                         int retcode,
-                         bool skipJob);
+                         int retcode);
 
 
 int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,