mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 18:05:20 +00:00
qemu: Don't duplicate suspend events and state changes
Since the STOP event handler can use the pausedReason as sent to qemuProcessStopCPUs, we no longer need to send duplicate suspended lifecycle events because we know what caused the stop along with extra details. This processing allows us to also remove the duplicated state change from qemuProcessStopCPUs. Reviewed-by: John Ferlan <jferlan@redhat.com> Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
This commit is contained in:
parent
ab2eaa1492
commit
e3389d830c
@ -1773,10 +1773,8 @@ static int qemuDomainSuspend(virDomainPtr dom)
|
|||||||
virQEMUDriverPtr driver = dom->conn->privateData;
|
virQEMUDriverPtr driver = dom->conn->privateData;
|
||||||
virDomainObjPtr vm;
|
virDomainObjPtr vm;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virObjectEventPtr event = NULL;
|
|
||||||
qemuDomainObjPrivatePtr priv;
|
qemuDomainObjPrivatePtr priv;
|
||||||
virDomainPausedReason reason;
|
virDomainPausedReason reason;
|
||||||
int eventDetail;
|
|
||||||
int state;
|
int state;
|
||||||
virQEMUDriverConfigPtr cfg = NULL;
|
virQEMUDriverConfigPtr cfg = NULL;
|
||||||
|
|
||||||
@ -1795,16 +1793,12 @@ static int qemuDomainSuspend(virDomainPtr dom)
|
|||||||
if (virDomainObjCheckActive(vm) < 0)
|
if (virDomainObjCheckActive(vm) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
|
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT)
|
||||||
reason = VIR_DOMAIN_PAUSED_MIGRATION;
|
reason = VIR_DOMAIN_PAUSED_MIGRATION;
|
||||||
eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED;
|
else if (priv->job.asyncJob == QEMU_ASYNC_JOB_SNAPSHOT)
|
||||||
} else if (priv->job.asyncJob == QEMU_ASYNC_JOB_SNAPSHOT) {
|
|
||||||
reason = VIR_DOMAIN_PAUSED_SNAPSHOT;
|
reason = VIR_DOMAIN_PAUSED_SNAPSHOT;
|
||||||
eventDetail = -1; /* don't create lifecycle events when doing snapshot */
|
else
|
||||||
} else {
|
|
||||||
reason = VIR_DOMAIN_PAUSED_USER;
|
reason = VIR_DOMAIN_PAUSED_USER;
|
||||||
eventDetail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = virDomainObjGetState(vm, NULL);
|
state = virDomainObjGetState(vm, NULL);
|
||||||
if (state == VIR_DOMAIN_PMSUSPENDED) {
|
if (state == VIR_DOMAIN_PMSUSPENDED) {
|
||||||
@ -1814,12 +1808,6 @@ static int qemuDomainSuspend(virDomainPtr dom)
|
|||||||
} else if (state != VIR_DOMAIN_PAUSED) {
|
} else if (state != VIR_DOMAIN_PAUSED) {
|
||||||
if (qemuProcessStopCPUs(driver, vm, reason, QEMU_ASYNC_JOB_NONE) < 0)
|
if (qemuProcessStopCPUs(driver, vm, reason, QEMU_ASYNC_JOB_NONE) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
|
|
||||||
if (eventDetail >= 0) {
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
||||||
eventDetail);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
|
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
@ -1831,7 +1819,6 @@ static int qemuDomainSuspend(virDomainPtr dom)
|
|||||||
cleanup:
|
cleanup:
|
||||||
virDomainObjEndAPI(&vm);
|
virDomainObjEndAPI(&vm);
|
||||||
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event);
|
|
||||||
virObjectUnref(cfg);
|
virObjectUnref(cfg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -16453,13 +16440,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
|
|||||||
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT,
|
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT,
|
||||||
QEMU_ASYNC_JOB_START) < 0)
|
QEMU_ASYNC_JOB_START) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
/* Create an event now in case the restore fails, so
|
|
||||||
* that user will be alerted that they are now paused.
|
|
||||||
* If restore later succeeds, we might replace this. */
|
|
||||||
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
||||||
detail);
|
|
||||||
if (!virDomainObjIsActive(vm)) {
|
if (!virDomainObjIsActive(vm)) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("guest unexpectedly quit"));
|
_("guest unexpectedly quit"));
|
||||||
|
@ -1269,29 +1269,6 @@ qemuMigrationSrcIsSafe(virDomainDefPtr def,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** qemuMigrationSrcSetOffline
|
|
||||||
* Pause domain for non-live migration.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
qemuMigrationSrcSetOffline(virQEMUDriverPtr driver,
|
|
||||||
virDomainObjPtr vm)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
VIR_DEBUG("driver=%p vm=%p", driver, vm);
|
|
||||||
ret = qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION,
|
|
||||||
QEMU_ASYNC_JOB_MIGRATION_OUT);
|
|
||||||
if (ret == 0) {
|
|
||||||
virObjectEventPtr event;
|
|
||||||
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED);
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
|
qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
|
||||||
@ -1314,19 +1291,10 @@ qemuMigrationAnyPostcopyFailed(virQEMUDriverPtr driver,
|
|||||||
"leaving the domain paused", vm->def->name);
|
"leaving the domain paused", vm->def->name);
|
||||||
|
|
||||||
if (state == VIR_DOMAIN_RUNNING) {
|
if (state == VIR_DOMAIN_RUNNING) {
|
||||||
virObjectEventPtr event;
|
|
||||||
|
|
||||||
if (qemuProcessStopCPUs(driver, vm,
|
if (qemuProcessStopCPUs(driver, vm,
|
||||||
VIR_DOMAIN_PAUSED_POSTCOPY_FAILED,
|
VIR_DOMAIN_PAUSED_POSTCOPY_FAILED,
|
||||||
QEMU_ASYNC_JOB_MIGRATION_IN) < 0) {
|
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
|
||||||
VIR_WARN("Unable to pause guest CPUs for %s", vm->def->name);
|
VIR_WARN("Unable to pause guest CPUs for %s", vm->def->name);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED);
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event);
|
|
||||||
} else {
|
} else {
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
|
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
|
||||||
VIR_DOMAIN_PAUSED_POSTCOPY_FAILED);
|
VIR_DOMAIN_PAUSED_POSTCOPY_FAILED);
|
||||||
@ -3532,10 +3500,11 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before EnterMonitor, since qemuMigrationSetOffline already does that */
|
/* Before EnterMonitor, since already qemuProcessStopCPUs does that */
|
||||||
if (!(flags & VIR_MIGRATE_LIVE) &&
|
if (!(flags & VIR_MIGRATE_LIVE) &&
|
||||||
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
|
virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
|
||||||
if (qemuMigrationSrcSetOffline(driver, vm) < 0)
|
if (qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION,
|
||||||
|
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3645,7 +3614,8 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
|
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
|
||||||
qemuMigrationSrcSetOffline(driver, vm) < 0) {
|
qemuProcessStopCPUs(driver, vm, VIR_DOMAIN_PAUSED_MIGRATION,
|
||||||
|
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +102,6 @@ typedef enum {
|
|||||||
} qemuMigrationJobPhase;
|
} qemuMigrationJobPhase;
|
||||||
VIR_ENUM_DECL(qemuMigrationJobPhase);
|
VIR_ENUM_DECL(qemuMigrationJobPhase);
|
||||||
|
|
||||||
int
|
|
||||||
qemuMigrationSrcSetOffline(virQEMUDriverPtr driver,
|
|
||||||
virDomainObjPtr vm);
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
qemuMigrationSrcBegin(virConnectPtr conn,
|
qemuMigrationSrcBegin(virConnectPtr conn,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
|
@ -3255,7 +3255,11 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
|
|||||||
if (priv->job.current)
|
if (priv->job.current)
|
||||||
ignore_value(virTimeMillisNow(&priv->job.current->stopped));
|
ignore_value(virTimeMillisNow(&priv->job.current->stopped));
|
||||||
|
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
|
/* The STOP event handler will change the domain state with the reason
|
||||||
|
* saved in priv->pausedReason and it will also emit corresponding domain
|
||||||
|
* lifecycle event.
|
||||||
|
*/
|
||||||
|
|
||||||
if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
|
if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
|
||||||
VIR_WARN("Unable to release lease on %s", vm->def->name);
|
VIR_WARN("Unable to release lease on %s", vm->def->name);
|
||||||
VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
|
VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user