[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/3] add virsh --suspend



This adds a new flag, VIR_MIGRATE_PAUSED, that mandates pausing
the migrated VM before starting it.

* include/libvirt/libvirt.h.in (virDomainMigrateFlags): Add
VIR_MIGRATE_PAUSED.
* src/qemu/qemu_driver.c (qemudDomainMigrateFinish2): Handle
VIR_MIGRATE_PAUSED.
* tools/virsh.c (opts_migrate): Add --suspend.
(cmdMigrate): Handle it.
* tools/virsh.pod (migrate): Document it.
---
	The complicated part of the patch is simply this with diff -b:

	@@ -7320,6 +7320,7 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
	         qemuDomainObjPrivatePtr priv = vm->privateData;
	         dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
	 
	+        if (!(flags & VIR_MIGRATE_PAUSED)) {
	         /* run 'cont' on the destination, which allows migration on qemu
	          * >= 0.10.6 to work properly.  This isn't strictly necessary on
	          * older qemu's, but it also doesn't hurt anything there
	@@ -7335,9 +7336,17 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
	         qemuDomainObjExitMonitorWithDriver(driver, vm);
	 
	         vm->state = VIR_DOMAIN_RUNNING;
	+        }

 include/libvirt/libvirt.h.in |    1 +
 src/libvirt.c                |    1 +
 src/qemu/qemu_driver.c       |   33 +++++++++++++++++++++------------
 tools/virsh.c                |    5 ++++-
 tools/virsh.pod              |    7 ++++---
 5 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5bc7694..0488cbf 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -341,6 +341,7 @@ typedef enum {
     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 */
+    VIR_MIGRATE_PAUSED            = (1 << 5), /* pause on remote side */
 } virDomainMigrateFlags;
 
 /* Domain migration. */
diff --git a/src/libvirt.c b/src/libvirt.c
index 05e45f3..2ced604 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3179,6 +3179,7 @@ virDomainMigrateDirect (virDomainPtr domain,
  *                            on the destination host.
  *   VIR_MIGRATE_UNDEFINE_SOURCE If the migration is successful, undefine the
  *                               domain on the source host.
+ *   VIR_MIGRATE_PAUSED    Leave the domain suspended on the remote side.
  *
  * 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 44cec6c..4d20fb7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7320,24 +7320,33 @@ qemudDomainMigrateFinish2 (virConnectPtr dconn,
         qemuDomainObjPrivatePtr priv = vm->privateData;
         dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
 
-        /* run 'cont' on the destination, which allows migration on qemu
-         * >= 0.10.6 to work properly.  This isn't strictly necessary on
-         * older qemu's, but it also doesn't hurt anything there
-         */
-        qemuDomainObjEnterMonitorWithDriver(driver, vm);
-        if (qemuMonitorStartCPUs(priv->mon, dconn) < 0) {
-            if (virGetLastError() == NULL)
-                qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                                 "%s", _("resume operation failed"));
+        if (!(flags & VIR_MIGRATE_PAUSED)) {
+            /* run 'cont' on the destination, which allows migration on qemu
+             * >= 0.10.6 to work properly.  This isn't strictly necessary on
+             * older qemu's, but it also doesn't hurt anything there
+             */
+            qemuDomainObjEnterMonitorWithDriver(driver, vm);
+            if (qemuMonitorStartCPUs(priv->mon, dconn) < 0) {
+                if (virGetLastError() == NULL)
+                    qemudReportError(dconn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                     "%s", _("resume operation failed"));
+                qemuDomainObjExitMonitorWithDriver(driver, vm);
+                goto endjob;
+            }
             qemuDomainObjExitMonitorWithDriver(driver, vm);
-            goto endjob;
+
+            vm->state = VIR_DOMAIN_RUNNING;
         }
-        qemuDomainObjExitMonitorWithDriver(driver, vm);
 
-        vm->state = VIR_DOMAIN_RUNNING;
         event = virDomainEventNewFromObj(vm,
                                          VIR_DOMAIN_EVENT_RESUMED,
                                          VIR_DOMAIN_EVENT_RESUMED_MIGRATED);
+        if (vm->state == VIR_DOMAIN_PAUSED) {
+            qemuDomainEventQueue(driver, event);
+            event = virDomainEventNewFromObj(vm,
+                                             VIR_DOMAIN_EVENT_SUSPENDED,
+                                             VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+        }
         virDomainSaveStatus(dconn, driver->stateDir, vm);
     } else {
         qemudShutdownVMDaemon (dconn, driver, vm);
diff --git a/tools/virsh.c b/tools/virsh.c
index 9faac35..9871b4b 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2478,6 +2478,7 @@ static const vshCmdOptDef opts_migrate[] = {
     {"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")},
+    {"suspend", VSH_OT_BOOL, 0, gettext_noop("do not restart the domain on the destination host")},
     {"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")},
@@ -2519,10 +2520,12 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
 
     if (vshCommandOptBool (cmd, "persistent"))
         flags |= VIR_MIGRATE_PERSIST_DEST;
-
     if (vshCommandOptBool (cmd, "undefinesource"))
         flags |= VIR_MIGRATE_UNDEFINE_SOURCE;
 
+    if (vshCommandOptBool (cmd, "suspend"))
+        flags |= VIR_MIGRATE_PAUSED;
+
     if ((flags & VIR_MIGRATE_PEER2PEER) ||
         vshCommandOptBool (cmd, "direct")) {
         /* For peer2peer migration or direct migration we only expect one URI
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 6ff0151..3830464 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -302,10 +302,11 @@ except that it does some error checking.
 The editor used can be supplied by the C<$EDITOR> environment
 variable, or if that is not defined defaults to C<vi>.
 
-=item B<migrate> optional I<--live> I<domain-id> I<desturi> I<migrateuri>
+=item B<migrate> optional I<--live> I<--suspend> I<domain-id> I<desturi> I<migrateuri>
 
-Migrate domain to another host.  Add --live for live migration. The I<desturi>
-is the connection URI of the destination host, and I<migrateuri> is the
+Migrate domain to another host.  Add --live for live migration; --suspend
+leaves the domain paused on the destination host. The I<desturi> is the
+connection URI of the destination host, and I<migrateuri> is the
 migration URI, which usually can be omitted.
 
 =item B<reboot> I<domain-id>
-- 
1.6.5.2



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]