mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 06:35:24 +00:00
qemu: Don't explicitly stop CPUs after migration
With a very old QEMU which doesn't support events we need to explicitly call qemuMigrationSetOffline at the end of migration to update our internal state. On the other hand, if we talk to QEMU using QMP, we should just wait for the STOP event and let the event handler update the state and trigger a libvirt event. Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
5d01e8666b
commit
315808e99e
@ -205,6 +205,8 @@ struct _qemuDomainObjPrivate {
|
|||||||
|
|
||||||
bool signalIOError; /* true if the domain condition should be signalled on
|
bool signalIOError; /* true if the domain condition should be signalled on
|
||||||
I/O error */
|
I/O error */
|
||||||
|
bool signalStop; /* true if the domain condition should be signalled on
|
||||||
|
QMP STOP event */
|
||||||
char *machineName;
|
char *machineName;
|
||||||
char *libDir; /* base path for per-domain files */
|
char *libDir; /* base path for per-domain files */
|
||||||
char *channelTargetDir; /* base path for per-domain channel targets */
|
char *channelTargetDir; /* base path for per-domain channel targets */
|
||||||
|
@ -4491,19 +4491,24 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|||||||
else if (rc == -1)
|
else if (rc == -1)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* When migration completed, QEMU will have paused the
|
/* When migration completed, QEMU will have paused the CPUs for us.
|
||||||
* CPUs for us, but unless we're using the JSON monitor
|
* Wait for the STOP event to be processed or explicitly stop CPUs
|
||||||
* we won't have been notified of this, so might still
|
* (for old QEMU which does not send events) to release the lock state.
|
||||||
* think we're running. For v2 protocol this doesn't
|
|
||||||
* matter because we'll kill the VM soon, but for v3
|
|
||||||
* this is important because we stay paused until the
|
|
||||||
* confirm3 step, but need to release the lock state
|
|
||||||
*/
|
*/
|
||||||
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
|
if (priv->monJSON) {
|
||||||
if (qemuMigrationSetOffline(driver, vm) < 0) {
|
while (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
|
||||||
priv->job.current->type = VIR_DOMAIN_JOB_FAILED;
|
priv->signalStop = true;
|
||||||
goto cleanup;
|
rc = virDomainObjWait(vm);
|
||||||
|
priv->signalStop = false;
|
||||||
|
if (rc < 0) {
|
||||||
|
priv->job.current->type = VIR_DOMAIN_JOB_FAILED;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING &&
|
||||||
|
qemuMigrationSetOffline(driver, vm) < 0) {
|
||||||
|
priv->job.current->type = VIR_DOMAIN_JOB_FAILED;
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -697,6 +697,8 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
{
|
{
|
||||||
virQEMUDriverPtr driver = opaque;
|
virQEMUDriverPtr driver = opaque;
|
||||||
virObjectEventPtr event = NULL;
|
virObjectEventPtr event = NULL;
|
||||||
|
virDomainPausedReason reason = VIR_DOMAIN_PAUSED_UNKNOWN;
|
||||||
|
virDomainEventSuspendedDetailType detail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
|
||||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
virObjectLock(vm);
|
virObjectLock(vm);
|
||||||
@ -708,16 +710,24 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_DEBUG("Transitioned guest %s to paused state",
|
if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT) {
|
||||||
vm->def->name);
|
reason = VIR_DOMAIN_PAUSED_MIGRATION;
|
||||||
|
detail = VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("Transitioned guest %s to paused state, reason %s",
|
||||||
|
vm->def->name, virDomainPausedReasonTypeToString(reason));
|
||||||
|
|
||||||
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, VIR_DOMAIN_PAUSED_UNKNOWN);
|
if (priv->signalStop)
|
||||||
|
virDomainObjBroadcast(vm);
|
||||||
|
|
||||||
|
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, reason);
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
VIR_DOMAIN_EVENT_SUSPENDED,
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
|
detail);
|
||||||
|
|
||||||
VIR_FREE(priv->lockState);
|
VIR_FREE(priv->lockState);
|
||||||
if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
|
if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user