.type = VSH_OT_BOOL,
.help = N_("enable post-copy migration; switch to it using migrate-postcopy command")
},
+ {.name = "postcopy-after-precopy",
+ .type = VSH_OT_BOOL,
+ .help = N_("automatically switch to post-copy migration after one pass of pre-copy")
+ },
{.name = "migrateuri",
.type = VSH_OT_STRING,
.help = N_("migration URI, usually can be omitted")
}
}
+static void
+virshMigrateIteration(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int iteration,
+ void *opaque)
+{
+ vshControl *ctl = opaque;
+
+ if (iteration == 2) {
+ vshDebug(ctl, VSH_ERR_DEBUG,
+ "iteration %d finished; switching to post-copy\n",
+ iteration - 1);
+ if (virDomainMigrateStartPostCopy(dom, 0) < 0)
+ vshDebug(ctl, VSH_ERR_INFO, "switching to post-copy failed\n");
+ }
+}
+
static bool
cmdMigrate(vshControl *ctl, const vshCmd *cmd)
{
virshMigrateTimeoutAction timeoutAction = VIRSH_MIGRATE_TIMEOUT_DEFAULT;
bool live_flag = false;
virshCtrlData data = { .dconn = NULL };
+ virshControlPtr priv = ctl->privData;
+ int iterEvent = -1;
VSH_EXCLUSIVE_OPTIONS("live", "offline");
VSH_EXCLUSIVE_OPTIONS("timeout-suspend", "timeout-postcopy");
goto cleanup;
}
+ if (vshCommandOptBool(cmd, "postcopy-after-precopy")) {
+ iterEvent = virConnectDomainEventRegisterAny(
+ priv->conn, dom,
+ VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION,
+ VIR_DOMAIN_EVENT_CALLBACK(virshMigrateIteration),
+ ctl, NULL);
+ if (iterEvent < 0)
+ goto cleanup;
+ }
+
if (pipe(p) < 0)
goto cleanup;
cleanup:
if (data.dconn)
virConnectClose(data.dconn);
+ if (iterEvent != -1)
+ virConnectDomainEventDeregisterAny(priv->conn, iterEvent);
virDomainFree(dom);
VIR_FORCE_CLOSE(p[0]);
VIR_FORCE_CLOSE(p[1]);
[I<--persistent>] [I<--undefinesource>] [I<--suspend>] [I<--copy-storage-all>]
[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<--timeout-suspend> | I<--timeout-postcopy>]]
+[I<--postcopy-after-precopy>] I<domain> I<desturi> [I<migrateuri>]
+[I<graphicsuri>] [I<listen-address>] [I<dname>]
+[I<--timeout> B<seconds> [I<--timeout-suspend> | I<--timeout-postcopy>]]
[I<--xml> B<file>] [I<--migrate-disks> B<disk-list>] [I<--disks-port> B<port>]
Migrate domain to another host. Add I<--live> for live migration; <--p2p>
I<--postcopy> enables post-copy logic in migration, but does not
actually start post-copy, i.e., migration is started in pre-copy mode.
Once migration is running, the user may switch to post-copy using the
-B<migrate-postcopy> command sent from another virsh instance.
+B<migrate-postcopy> command sent from another virsh instance or use
+I<--postcopy-after-precopy> to let libvirt automatically switch to
+post-copy after the first pass of pre-copy is finished.
B<Note>: Individual hypervisors usually do not support all possible types of
migration. For example, QEMU does not support direct migration.