Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
tools/virsh-domain.c | 63 +++++++++++++++++++++++++++++++++++++++++++++-------
tools/virsh.pod | 15 ++++++++-----
2 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index d1d6650..55ad342 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9645,7 +9645,16 @@ static const vshCmdOptDef opts_migrate[] = {
},
{.name = "timeout",
.type = VSH_OT_INT,
- .help = N_("force guest to suspend if live migration exceeds timeout (in
seconds)")
+ .help = N_("run action specified by --timeout-* option (suspend by "
+ "default) if live migration exceeds timeout (in seconds)")
+ },
+ {.name = "timeout-suspend",
+ .type = VSH_OT_BOOL,
+ .help = N_("suspend the guest after timeout")
+ },
+ {.name = "timeout-postcopy",
+ .type = VSH_OT_BOOL,
+ .help = N_("switch to post-copy after timeout")
},
{.name = "xml",
.type = VSH_OT_STRING,
@@ -9823,14 +9832,35 @@ doMigrate(void *opaque)
goto out;
}
+typedef enum {
+ VIRSH_MIGRATE_TIMEOUT_DEFAULT,
+ VIRSH_MIGRATE_TIMEOUT_SUSPEND,
+ VIRSH_MIGRATE_TIMEOUT_POSTCOPY,
+} virshMigrateTimeoutAction;
+
static void
-virshMigrationTimeout(vshControl *ctl,
- virDomainPtr dom,
- void *opaque ATTRIBUTE_UNUSED)
+virshMigrateTimeout(vshControl *ctl,
+ virDomainPtr dom,
+ void *opaque)
{
- vshDebug(ctl, VSH_ERR_DEBUG, "suspending the domain, "
- "since migration timed out\n");
- virDomainSuspend(dom);
+ virshMigrateTimeoutAction action = *(virshMigrateTimeoutAction *) opaque;
+
+ switch (action) {
+ case VIRSH_MIGRATE_TIMEOUT_DEFAULT: /* unreachable */
+ case VIRSH_MIGRATE_TIMEOUT_SUSPEND:
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "migration timed out; suspending domain\n");
+ if (virDomainSuspend(dom) < 0)
+ vshDebug(ctl, VSH_ERR_INFO, "suspending domain failed\n");
+ break;
+
+ case VIRSH_MIGRATE_TIMEOUT_POSTCOPY:
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "migration timed out; switching to post-copy\n");
+ if (virDomainMigrateStartPostCopy(dom, 0) < 0)
+ vshDebug(ctl, VSH_ERR_INFO, "switching to post-copy failed\n");
+ break;
+ }
}
static bool
@@ -9842,9 +9872,12 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
bool verbose = false;
bool functionReturn = false;
int timeout = 0;
+ virshMigrateTimeoutAction timeoutAction = VIRSH_MIGRATE_TIMEOUT_DEFAULT;
bool live_flag = false;
virshCtrlData data = { .dconn = NULL };
+ VSH_EXCLUSIVE_OPTIONS("timeout-suspend", "timeout-postcopy");
+
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
@@ -9861,6 +9894,19 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
+ if (vshCommandOptBool(cmd, "timeout-suspend"))
+ timeoutAction = VIRSH_MIGRATE_TIMEOUT_SUSPEND;
+ if (vshCommandOptBool(cmd, "timeout-postcopy"))
+ timeoutAction = VIRSH_MIGRATE_TIMEOUT_POSTCOPY;
+ if (timeout > 0) {
+ if (timeoutAction == VIRSH_MIGRATE_TIMEOUT_DEFAULT)
+ timeoutAction = VIRSH_MIGRATE_TIMEOUT_SUSPEND;
+ } else if (timeoutAction) {
+ vshError(ctl, "%s",
+ _("migrate: Unexpected --timeout-* option without
--timeout"));
+ goto cleanup;
+ }
+
if (pipe(p) < 0)
goto cleanup;
@@ -9891,7 +9937,8 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
&data) < 0)
goto cleanup;
functionReturn = virshWatchJob(ctl, dom, verbose, p[0], timeout,
- virshMigrationTimeout, NULL,
_("Migration"));
+ virshMigrateTimeout,
+ &timeoutAction, _("Migration"));
virThreadJoin(&workerThread);
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 109c608..64b4287 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1531,8 +1531,8 @@ to the I<uri> namespace is displayed instead of being
modified.
[I<--copy-storage-inc>] [I<--change-protection>] [I<--unsafe>]
[I<--verbose>]
[I<--compressed>] [I<--abort-on-error>] [I<--auto-converge>]
[I<--postcopy>]
I<domain> I<desturi> [I<migrateuri>] [I<graphicsuri>]
[I<listen-address>]
-[I<dname>] [I<--timeout> B<seconds>] [I<--xml> B<file>]
-[I<--migrate-disks> B<disk-list>]
+[I<dname>] [I<--timeout> B<seconds> [I<--timeout-suspend> |
I<--timeout-postcopy>]]
+[I<--xml> B<file>] [I<--migrate-disks> B<disk-list>]
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>
@@ -1582,9 +1582,14 @@ the destination to supply a larger set of changes to any
host-specific
portions of the domain XML, such as accounting for naming differences
between source and destination in accessing underlying storage.
-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<--timeout> B<seconds> tells virsh to run a specified action when live
+migration exceeds that many seconds. It can only be used with I<--live>.
+If I<--timeout-suspend> is specified, the domain will be suspended after
+the timeout and the migration will complete offline; this is the default
+if no I<--timeout-*> option is specified on the command line. When
+I<--timeout-postcopy> is used, virsh will switch migration from pre-copy
+to post-copy upon timeout; migration has to be started with I<--postcopy>
+option for this to work.
Running migration can be canceled by interrupting virsh (usually using
C<Ctrl-C>) or by B<domjobabort> command sent from another virsh instance.
--
2.7.0