We send duplicate suspended lifecycle events on qemu process stop in several
places. The reason is stop event handler always send suspended event and
we addidionally send same event but with more presise reason after call
to qemuProcessStopCPUs. Domain state change is also duplicated.
Let's change domain state and send event only in handler. For this
purpuse first let's pass state change reason to event handler (event
reason is deducible from it).
Inspired by similar patch for resume: 5dab984ed
"qemu: Pass running reason to RESUME event handler".
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy(a)virtuozzo.com>
---
src/qemu/qemu_domain.h | 4 ++++
src/qemu/qemu_process.c | 15 ++++++++++++---
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 80bd4bd..380ea14 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -370,6 +370,10 @@ struct _qemuDomainObjPrivate {
/* qemuProcessStartCPUs stores the reason for starting vCPUs here for the
* RESUME event handler to use it */
virDomainRunningReason runningReason;
+
+ /* qemuProcessStopCPUs stores the reason for starting vCPUs here for the
+ * STOP event handler to use it */
+ virDomainPausedReason pausedReason;
};
# define QEMU_DOMAIN_PRIVATE(vm) \
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e9c7618..27021b9 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -641,14 +641,17 @@ qemuProcessHandleStop(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
{
virQEMUDriverPtr driver = opaque;
virObjectEventPtr event = NULL;
- virDomainPausedReason reason = VIR_DOMAIN_PAUSED_UNKNOWN;
+ virDomainPausedReason reason;
virDomainEventSuspendedDetailType detail = VIR_DOMAIN_EVENT_SUSPENDED_PAUSED;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
virObjectLock(vm);
+
+ reason = priv->pausedReason;
+ priv->pausedReason = VIR_DOMAIN_PAUSED_UNKNOWN;
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
- qemuDomainObjPrivatePtr priv = vm->privateData;
-
if (priv->gotShutdown) {
VIR_DEBUG("Ignoring STOP event after SHUTDOWN");
goto unlock;
@@ -3132,6 +3135,8 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
VIR_FREE(priv->lockState);
+ priv->pausedReason = reason;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
goto cleanup;
@@ -3154,6 +3159,9 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
VIR_DEBUG("Preserving lock state '%s'",
NULLSTR(priv->lockState));
cleanup:
+ if (ret < 0)
+ priv->pausedReason = VIR_DOMAIN_PAUSED_UNKNOWN;
+
return ret;
}
@@ -5996,6 +6004,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
priv->monStart = 0;
priv->gotShutdown = false;
priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN;
+ priv->pausedReason = VIR_DOMAIN_PAUSED_UNKNOWN;
VIR_DEBUG("Updating guest CPU definition");
if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < 0)
--
1.8.3.1