mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 11:52:20 +00:00
qemu: Implement VIR_MIGRATE_POSTCOPY_RESUME for Begin phase
Mostly we just need to check whether the domain is in a failed post-copy migration that can be resumed. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
a5e603c808
commit
37a67122dd
@ -2685,6 +2685,139 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
|
|||||||
flags);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
qemuMigrationAnyCanResume(virDomainObj *vm,
|
||||||
|
virDomainAsyncJob job,
|
||||||
|
unsigned long flags,
|
||||||
|
qemuMigrationJobPhase expectedPhase)
|
||||||
|
{
|
||||||
|
qemuDomainObjPrivate *priv = vm->privateData;
|
||||||
|
|
||||||
|
VIR_DEBUG("vm=%p, job=%s, flags=0x%lx, expectedPhase=%s",
|
||||||
|
vm, virDomainAsyncJobTypeToString(job), flags,
|
||||||
|
qemuDomainAsyncJobPhaseToString(VIR_ASYNC_JOB_MIGRATION_OUT,
|
||||||
|
expectedPhase));
|
||||||
|
|
||||||
|
if (!(flags & VIR_MIGRATE_POSTCOPY)) {
|
||||||
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||||
|
_("resuming failed post-copy migration requires post-copy to be enabled"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should never happen since POSTCOPY_RESUME is newer than
|
||||||
|
* CHANGE_PROTECTION, but let's check it anyway in case we're talking to
|
||||||
|
* a weired client.
|
||||||
|
*/
|
||||||
|
if (job == VIR_ASYNC_JOB_MIGRATION_OUT &&
|
||||||
|
expectedPhase < QEMU_MIGRATION_PHASE_PERFORM_RESUME &&
|
||||||
|
!(flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
|
||||||
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||||
|
_("resuming failed post-copy migration requires change protection"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qemuMigrationJobIsActive(vm, job))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (priv->job.asyncOwner != 0 &&
|
||||||
|
priv->job.asyncOwner != virThreadSelfID()) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("migration of domain %s is being actively monitored by another thread"),
|
||||||
|
vm->def->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virDomainObjIsPostcopy(vm, priv->job.current->operation)) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("migration of domain %s is not in post-copy phase"),
|
||||||
|
vm->def->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->job.phase < QEMU_MIGRATION_PHASE_POSTCOPY_FAILED &&
|
||||||
|
!virDomainObjIsFailedPostcopy(vm)) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("post-copy migration of domain %s has not failed"),
|
||||||
|
vm->def->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->job.phase > expectedPhase) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("resuming failed post-copy migration of domain %s already in progress"),
|
||||||
|
vm->def->name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
qemuMigrationSrcBeginResume(virQEMUDriver *driver,
|
||||||
|
virDomainObj *vm,
|
||||||
|
const char *xmlin,
|
||||||
|
char **cookieout,
|
||||||
|
int *cookieoutlen,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
virDomainJobStatus status;
|
||||||
|
|
||||||
|
if (qemuMigrationAnyRefreshStatus(driver, vm, VIR_ASYNC_JOB_MIGRATION_OUT,
|
||||||
|
&status) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (status != VIR_DOMAIN_JOB_STATUS_POSTCOPY_PAUSED) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
|
_("QEMU reports migration is still running"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qemuMigrationSrcBeginXML(vm, xmlin,
|
||||||
|
cookieout, cookieoutlen, 0, NULL, 0, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
qemuMigrationSrcBeginResumePhase(virConnectPtr conn,
|
||||||
|
virQEMUDriver *driver,
|
||||||
|
virDomainObj *vm,
|
||||||
|
const char *xmlin,
|
||||||
|
char **cookieout,
|
||||||
|
int *cookieoutlen,
|
||||||
|
unsigned long flags)
|
||||||
|
{
|
||||||
|
g_autofree char *xml = NULL;
|
||||||
|
|
||||||
|
VIR_DEBUG("vm=%p", vm);
|
||||||
|
|
||||||
|
if (!qemuMigrationAnyCanResume(vm, VIR_ASYNC_JOB_MIGRATION_OUT, flags,
|
||||||
|
QEMU_MIGRATION_PHASE_POSTCOPY_FAILED))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (qemuMigrationJobStartPhase(vm, QEMU_MIGRATION_PHASE_BEGIN_RESUME) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
virCloseCallbacksUnset(driver->closeCallbacks, vm,
|
||||||
|
qemuMigrationSrcCleanup);
|
||||||
|
qemuDomainCleanupRemove(vm, qemuProcessCleanupMigrationJob);
|
||||||
|
|
||||||
|
xml = qemuMigrationSrcBeginResume(driver, vm, xmlin, cookieout, cookieoutlen, flags);
|
||||||
|
|
||||||
|
if (virCloseCallbacksSet(driver->closeCallbacks, vm, conn,
|
||||||
|
qemuMigrationSrcCleanup) < 0)
|
||||||
|
g_clear_pointer(&xml, g_free);
|
||||||
|
|
||||||
|
if (!xml)
|
||||||
|
ignore_value(qemuMigrationJobSetPhase(vm, QEMU_MIGRATION_PHASE_POSTCOPY_FAILED));
|
||||||
|
|
||||||
|
qemuDomainCleanupAdd(vm, qemuProcessCleanupMigrationJob);
|
||||||
|
qemuMigrationJobContinue(vm);
|
||||||
|
return g_steal_pointer(&xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
qemuMigrationSrcBegin(virConnectPtr conn,
|
qemuMigrationSrcBegin(virConnectPtr conn,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
@ -2710,6 +2843,12 @@ qemuMigrationSrcBegin(virConnectPtr conn,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & VIR_MIGRATE_POSTCOPY_RESUME) {
|
||||||
|
ret = qemuMigrationSrcBeginResumePhase(conn, driver, vm, xmlin,
|
||||||
|
cookieout, cookieoutlen, flags);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
|
if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
|
||||||
if (qemuMigrationJobStart(driver, vm, VIR_ASYNC_JOB_MIGRATION_OUT,
|
if (qemuMigrationJobStart(driver, vm, VIR_ASYNC_JOB_MIGRATION_OUT,
|
||||||
flags) < 0)
|
flags) < 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user