[libvirt] [PATCH] Finer grained migration control

Chris Lalancette clalance at redhat.com
Mon Oct 12 11:32:26 UTC 2009


Normally, when you migrate a domain from host A to host B,
the domain on host A remains defined but shutoff and the domain
on host B remains running but is a "transient".  Add a new
flag to virDomainMigrate() to allow the original domain to be
undefined on source host A, and a new flag to virDomainMigrate() to
allow the new domain to be persisted on the destination host B.

Signed-off-by: Chris Lalancette <clalance at redhat.com>
---
 include/libvirt/libvirt.h.in |    2 ++
 src/libvirt.c                |    4 ++++
 src/qemu/qemu_driver.c       |   34 ++++++++++++++++++++++++++++++++--
 tools/virsh.c                |    8 ++++++++
 4 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index f51a565..6186d4e 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -339,6 +339,8 @@ typedef enum {
     VIR_MIGRATE_LIVE              = (1 << 0), /* live migration */
     VIR_MIGRATE_PEER2PEER         = (1 << 1), /* direct source -> dest host control channel */
     VIR_MIGRATE_TUNNELLED         = (1 << 2), /* tunnel migration data over libvirtd connection */
+    VIR_MIGRATE_PERSIST_DEST      = (1 << 3), /* persist the VM on the destination */
+    VIR_MIGRATE_UNDEFINE_SOURCE   = (1 << 4), /* undefine the VM on the source */
 } virDomainMigrateFlags;
 
 /* Domain migration. */
diff --git a/src/libvirt.c b/src/libvirt.c
index b14942d..92a1eaa 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3128,6 +3128,10 @@ virDomainMigrateDirect (virDomainPtr domain,
  *   VIR_MIGRATE_LIVE      Do not pause the VM during migration
  *   VIR_MIGRATE_PEER2PEER Direct connection between source & destination hosts
  *   VIR_MIGRATE_TUNNELLED Tunnel migration data over the libvirt RPC channel
+ *   VIR_MIGRATE_PERSIST_DEST If the migration is successful, persist the domain
+ *                            on the destination host.
+ *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
+ *                               domain on the source host.
  *
  * VIR_MIGRATE_TUNNELLED requires that VIR_MIGRATE_PEER2PEER be set.
  * Applications using the VIR_MIGRATE_PEER2PEER flag will probably
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3812f91..ba5694e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6848,7 +6848,8 @@ qemudDomainMigratePerform (virDomainPtr dom,
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_STOPPED,
                                      VIR_DOMAIN_EVENT_STOPPED_MIGRATED);
-    if (!vm->persistent) {
+    if (!vm->persistent || (flags & VIR_MIGRATE_UNDEFINE_SOURCE)) {
+        virDomainDeleteConfig(dom->conn, driver->configDir, driver->autostartDir, vm);
         virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
@@ -6886,13 +6887,14 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
                            const char *cookie ATTRIBUTE_UNUSED,
                            int cookielen ATTRIBUTE_UNUSED,
                            const char *uri ATTRIBUTE_UNUSED,
-                           unsigned long flags ATTRIBUTE_UNUSED,
+                           unsigned long flags,
                            int retcode)
 {
     struct qemud_driver *driver = dconn->privateData;
     virDomainObjPtr vm;
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
+    int newVM = 1;
 
     qemuDriverLock(driver);
     vm = virDomainFindByName(&driver->domains, dname);
@@ -6906,6 +6908,34 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
      * object, but if no, clean up the empty qemu process.
      */
     if (retcode == 0) {
+        if (flags & VIR_MIGRATE_PERSIST_DEST) {
+            if (vm->persistent)
+                newVM = 0;
+            vm->persistent = 1;
+
+            if (virDomainSaveConfig(dconn, driver->configDir, vm->def) < 0) {
+                /* Hmpf.  Migration was successful, but making it persistent
+                 * was not.  If we report successful, then when this domain
+                 * shuts down, management tools are in for a surprise.  On the
+                 * other hand, if we report failure, then the management tools
+                 * might try to restart the domain on the source side, even
+                 * though the domain is actually running on the destination.
+                 * Return a NULL dom pointer, and hope that this is a rare
+                 * situation and management tools are smart.
+                 */
+                vm = NULL;
+                goto cleanup;
+            }
+
+            event = virDomainEventNewFromObj(vm,
+                                             VIR_DOMAIN_EVENT_DEFINED,
+                                             newVM ?
+                                             VIR_DOMAIN_EVENT_DEFINED_ADDED :
+                                             VIR_DOMAIN_EVENT_DEFINED_UPDATED);
+            if (event)
+                qemuDomainEventQueue(driver, event);
+
+        }
         dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
 
         /* run 'cont' on the destination, which allows migration on qemu
diff --git a/tools/virsh.c b/tools/virsh.c
index 46c5454..47122d5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2465,6 +2465,8 @@ static const vshCmdOptDef opts_migrate[] = {
     {"p2p", VSH_OT_BOOL, 0, gettext_noop("peer-2-peer migration")},
     {"direct", VSH_OT_BOOL, 0, gettext_noop("direct migration")},
     {"tunnelled", VSH_OT_BOOL, 0, gettext_noop("tunnelled migration")},
+    {"persistent", VSH_OT_BOOL, 0, gettext_noop("persist VM on destination")},
+    {"undefinesource", VSH_OT_BOOL, 0, gettext_noop("undefine VM on source")},
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")},
     {"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("connection URI of the destination host")},
     {"migrateuri", VSH_OT_DATA, 0, gettext_noop("migration URI, usually can be omitted")},
@@ -2504,6 +2506,12 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     if (vshCommandOptBool (cmd, "tunnelled"))
         flags |= VIR_MIGRATE_TUNNELLED;
 
+    if (vshCommandOptBool (cmd, "persistent"))
+        flags |= VIR_MIGRATE_PERSIST_DEST;
+
+    if (vshCommandOptBool (cmd, "undefinesource"))
+        flags |= VIR_MIGRATE_UNDEFINE_SOURCE;
+
     if ((flags & VIR_MIGRATE_PEER2PEER) ||
         vshCommandOptBool (cmd, "direct")) {
         /* For peer2peer migration or direct migration we only expect one URI
-- 
1.6.0.6




More information about the libvir-list mailing list