[libvirt] [PATCH v2 8/8] virsh: add postcopy-after option to migrate command

Cristian Klein cristian.klein at cs.umu.se
Tue Sep 30 14:39:29 UTC 2014


Signed-off-by: Cristian Klein <cristian.klein at cs.umu.se>
---
 tools/virsh-domain.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 tools/virsh.pod      |  5 ++++
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 36a6d52..395c73c 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9251,6 +9251,10 @@ static const vshCmdOptDef opts_migrate[] = {
      .type = VSH_OT_INT,
      .help = N_("force guest to suspend if live migration exceeds timeout (in seconds)")
     },
+    {.name = "postcopy-after",
+     .type = VSH_OT_INT,
+     .help = N_("switch to post-copy migration if live migration exceeds timeout (in seconds)")
+    },
     {.name = "xml",
      .type = VSH_OT_STRING,
      .help = N_("filename containing updated XML for the target")
@@ -9332,6 +9336,8 @@ doMigrate(void *opaque)
         VIR_FREE(xml);
     }
 
+    if (vshCommandOptBool(cmd, "postcopy-after")) /* actually an int */
+        flags |= VIR_MIGRATE_POSTCOPY;
     if (vshCommandOptBool(cmd, "live"))
         flags |= VIR_MIGRATE_LIVE;
     if (vshCommandOptBool(cmd, "p2p"))
@@ -9423,6 +9429,50 @@ vshMigrationTimeout(vshControl *ctl,
     virDomainSuspend(dom);
 }
 
+static void
+vshMigrationPostCopyAfter(vshControl *ctl,
+                    virDomainPtr dom,
+                    void *opaque ATTRIBUTE_UNUSED)
+{
+    vshDebug(ctl, VSH_ERR_DEBUG, "starting post-copy\n");
+    int rv = virDomainMigrateStartPostCopy(dom, 0);
+    if (rv < 0) {
+        vshError(ctl, "%s", _("start post-copy command failed"));
+    } else {
+        vshDebug(ctl, VSH_ERR_INFO, "switched to post-copy\n");
+    }
+}
+
+/* Parse the --postcopy-after parameter in seconds, but store its
+ * value in milliseconds. Return -1 on error, 0 if
+ * no timeout was requested, and 1 if timeout was set.
+ * Copy-paste-adapted from vshCommandOptTimeoutToMs.
+ */
+static int
+vshCommandOptPostCopyAfterToMs(vshControl *ctl, const vshCmd *cmd, int *postCopyAfter)
+{
+    int rv = vshCommandOptInt(cmd, "postcopy-after", postCopyAfter);
+
+    if (rv < 0 || (rv > 0 && *postCopyAfter < 0)) {
+        vshError(ctl, "%s", _("invalid postcopy-after parameter"));
+        return -1;
+    }
+    if (rv > 0) {
+        /* Ensure that we can multiply by 1000 without overflowing. */
+        if (*postCopyAfter > INT_MAX / 1000) {
+            vshError(ctl, "%s", _("post-copy after parameter is too big"));
+            return -1;
+        }
+        *postCopyAfter *= 1000;
+        /* 0 is a special value inside virsh, which means no timeout, so
+         * use 1ms instead for "start post-copy immediately"
+         */
+        if (*postCopyAfter == 0)
+            *postCopyAfter = 1;
+    }
+    return rv;
+}
+
 static bool
 cmdMigrate(vshControl *ctl, const vshCmd *cmd)
 {
@@ -9432,6 +9482,7 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
     bool verbose = false;
     bool functionReturn = false;
     int timeout = 0;
+    int postCopyAfter = 0;
     bool live_flag = false;
     vshCtrlData data = { .dconn = NULL };
 
@@ -9451,6 +9502,18 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
     }
 
+    if (vshCommandOptPostCopyAfterToMs(ctl, cmd, &postCopyAfter) < 0) {
+        goto cleanup;
+    } else if (postCopyAfter > 0 && !live_flag) {
+        vshError(ctl, "%s",
+                 _("migrate: Unexpected postcopy-after for offline migration"));
+        goto cleanup;
+    } else if (postCopyAfter > 0 && timeout > 0) {
+        vshError(ctl, "%s",
+                 _("migrate: --postcopy-after is incompatible with --timeout"));
+        goto cleanup;
+    }
+
     if (pipe(p) < 0)
         goto cleanup;
 
@@ -9480,8 +9543,13 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
                         doMigrate,
                         &data) < 0)
         goto cleanup;
-    functionReturn = vshWatchJob(ctl, dom, verbose, p[0], timeout,
-                                 vshMigrationTimeout, NULL, _("Migration"));
+    if (postCopyAfter != 0) {
+        functionReturn = vshWatchJob(ctl, dom, verbose, p[0], postCopyAfter,
+                                     vshMigrationPostCopyAfter, NULL, _("Migration"));
+    } else {
+        functionReturn = vshWatchJob(ctl, dom, verbose, p[0], timeout,
+                                     vshMigrationTimeout, NULL, _("Migration"));
+    }
 
     virThreadJoin(&workerThread);
 
diff --git a/tools/virsh.pod b/tools/virsh.pod
index eae9195..2ae7afa 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1404,6 +1404,7 @@ to the I<uri> namespace is displayed instead of being modified.
 [I<--compressed>] [I<--abort-on-error>] [I<--auto-converge>]
 I<domain> I<desturi> [I<migrateuri>] [I<graphicsuri>] [I<listen-address>]
 [I<dname>] [I<--timeout> B<seconds>] [I<--xml> B<file>]
+[I<--postcopy-after> B<seconds>]
 
 Migrate domain to another host.  Add I<--live> for live migration; <--p2p>
 for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
@@ -1451,6 +1452,10 @@ I<--timeout> B<seconds> forces guest to suspend when live migration exceeds
 that many seconds, and
 then the migration will complete offline. It can only be used with I<--live>.
 
+I<--postcopy-after> switches to post-copy migration when pre-copy migration
+exceeds that many seconds. Zero means start post-copy as soon as possible.
+It can only be used with I<--live>.
+
 Running migration can be canceled by interrupting virsh (usually using
 C<Ctrl-C>) or by B<domjobabort> command sent from another virsh instance.
 
-- 
1.9.1




More information about the libvir-list mailing list