QEMU_MIGRATION_COMPLETED_CHECK_STORAGE = (1 << 1),
QEMU_MIGRATION_COMPLETED_POSTCOPY = (1 << 2),
QEMU_MIGRATION_COMPLETED_PRE_SWITCHOVER = (1 << 3),
+ QEMU_MIRGATION_COMPLETED_RECOVERY = (1 << 4),
};
return 1;
}
+ /* When QEMU is new enough to enter postcopy-recover-setup state during
+ * post-copy recovery, the source waits for the recovery to start
+ * before letting the destination wait for migration to complete.
+ */
+ if (flags & QEMU_MIRGATION_COMPLETED_RECOVERY &&
+ jobData->status == VIR_DOMAIN_JOB_STATUS_POSTCOPY) {
+ VIR_DEBUG("Post-copy recovery active");
+ return 1;
+ }
+
if (jobData->status == VIR_DOMAIN_JOB_STATUS_HYPERVISOR_COMPLETED)
return 1;
else
char **cookieout,
int *cookieoutlen,
qemuMigrationSpec *spec,
+ virConnectPtr dconn,
unsigned int flags)
{
qemuDomainObjPrivate *priv = vm->privateData;
if (rc < 0)
return -1;
+ /* Wait for postcopy recovery to start (or fail) if QEMU is new enough to
+ * support postcopy-recover-setup migration state. */
+ if (priv->migrationRecoverSetup) {
+ VIR_DEBUG("Waiting for post-copy recovery to start");
+ if (qemuMigrationSrcWaitForCompletion(vm, VIR_ASYNC_JOB_MIGRATION_OUT, dconn,
+ QEMU_MIRGATION_COMPLETED_RECOVERY) < 0)
+ return -1;
+ } else {
+ VIR_WARN("QEMU is too old, we may report a failure in post-copy phase even though the migration may be running just fine");
+ }
+
if (qemuMigrationCookieFormat(mig, driver, vm,
QEMU_MIGRATION_SOURCE,
cookieout, cookieoutlen,
if (flags & VIR_MIGRATE_POSTCOPY_RESUME) {
ret = qemuMigrationSrcResume(vm, migParams, cookiein, cookieinlen,
- cookieout, cookieoutlen, &spec, flags);
+ cookieout, cookieoutlen, &spec, dconn, flags);
} else {
ret = qemuMigrationSrcRun(driver, vm, xmlin, persist_xml, cookiein, cookieinlen,
cookieout, cookieoutlen, flags, resource,