{"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host as seen from the client(normal migration) or source(p2p migration)")},
{"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
{"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
+ {"timeout", VSH_OT_INT, 0, N_("force guest to suspend if live migration exceeds timeout (in seconds)")},
{NULL, 0, 0, NULL}
};
int ret = -1;
virThread workerThread;
struct pollfd pollfd;
+ int found;
char retchar;
struct sigaction sig_action;
struct sigaction old_sig_action;
virDomainJobInfo jobinfo;
bool verbose = false;
sigset_t sigmask, oldsigmask;
+ int timeout;
+ struct timeval start, curr;
+ bool live_flag = false;
vshCtrlData data;
if (vshCommandOptBool (cmd, "verbose"))
verbose = true;
+ if (vshCommandOptBool (cmd, "live"))
+ live_flag = TRUE;
+ timeout = vshCommandOptInt(cmd, "timeout", &found);
+ if (found) {
+ if (! live_flag) {
+ vshError(ctl, "%s", _("migrate: Unexpected timeout for offline migration"));
+ goto cleanup;
+ }
+
+ if (timeout < 1) {
+ vshError(ctl, "%s", _("migrate: Invalid timeout"));
+ goto cleanup;
+ }
+
+ /* Ensure that we can multiply by 1000 without overflowing. */
+ if (timeout > INT_MAX / 1000) {
+ vshError(ctl, "%s", _("migrate: Timeout is too big"));
+ goto cleanup;
+ }
+ } else {
+ timeout = 0;
+ }
+
if (pipe(p) < 0)
goto cleanup;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGINT);
+ GETTIMEOFDAY(&start);
while (1) {
repoll:
ret = poll(&pollfd, 1, 500);
break;
}
+ GETTIMEOFDAY(&curr);
+ if ( timeout && ((int)(curr.tv_sec - start.tv_sec) * 1000 + \
+ (int)(curr.tv_usec - start.tv_usec) / 1000) > timeout * 1000 ) {
+ /* suspend the domain when migration timeouts. */
+ vshDebug(ctl, 5, "suspend the domain when migration timeouts\n");
+ virDomainSuspend(dom);
+ timeout = 0;
+ }
+
if (verbose) {
pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
ret = virDomainGetJobInfo(dom, &jobinfo);
=item B<migrate> optional I<--live> I<--p2p> I<--direct> I<--tunnelled>
I<--persistent> I<--undefinesource> I<--suspend> I<--copy-storage-all>
I<--copy-storage-inc> I<--verbose> I<domain-id> I<desturi> I<migrateuri>
-I<dname>
+I<dname> I<--timeout>
Migrate domain to another host. Add I<--live> for live migration; I<--p2p>
for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
I<dname> is used for renaming the domain to new name during migration, which
also usually can be omitted.
+I<--timeout> forces guest to suspend when live migration exceeds timeout, and
+then the migration will complete offline. It can only be used with I<--live>.
+
B<Note>: The I<desturi> parameter for normal migration and peer2peer migration
has different semantics: