[PATCH v2 0/2] qemu: refresh state after reset

v1: https://listman.redhat.com/archives/libvir-list/2022-November/235913.html diff to v1: * calling refresh state unconditionally (suggested by Martin) * improved commit message Kristina Hanicova (2): qemu: refresh internal domain state after reset qemu: refresh state after reboot initiated from the guest src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 19 +++++++++++++++++++ src/qemu/qemu_process.c | 2 ++ 4 files changed, 23 insertions(+) -- 2.38.1

Internal domain state may change during the reset and qemu does not always send events about it. In case it happens, internal state of the domain in libvirt would be inconsistent with the internal state in qemu which could cause additional problems (e.g. cdrom tray state can change from open to closed). The solution is to refresh state after a successful reset to query qemu about the current internal domain state. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1824722 Signed-off-by: Kristina Hanicova <khanicov@redhat.com> --- src/qemu/qemu_driver.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 08ab04b468..4af8a8691c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2000,6 +2000,7 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags) int ret = -1; qemuDomainObjPrivate *priv; virDomainState state; + virQEMUDriver *driver = dom->conn->privateData; virCheckFlags(0, -1); @@ -2026,6 +2027,8 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags) if (state == VIR_DOMAIN_CRASHED) virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_CRASHED); + qemuProcessRefreshState(driver, vm, VIR_ASYNC_JOB_NONE); + endjob: virDomainObjEndJob(vm); -- 2.38.1

Internal domain state needs to be refreshed after reset from the guest side because it may be inconsistent with the internal qemu state. Signed-off-by: Kristina Hanicova <khanicov@redhat.com> --- src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 16 ++++++++++++++++ src/qemu/qemu_process.c | 2 ++ 4 files changed, 20 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 5d81dc7a45..8892f28fce 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11161,6 +11161,7 @@ qemuProcessEventFree(struct qemuProcessEvent *event) break; case QEMU_PROCESS_EVENT_PR_DISCONNECT: case QEMU_PROCESS_EVENT_UNATTENDED_MIGRATION: + case QEMU_PROCESS_EVENT_RESET: case QEMU_PROCESS_EVENT_LAST: break; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index a9af8502d2..2f027fad87 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -448,6 +448,7 @@ typedef enum { QEMU_PROCESS_EVENT_GUEST_CRASHLOADED, QEMU_PROCESS_EVENT_MEMORY_DEVICE_SIZE_CHANGE, QEMU_PROCESS_EVENT_UNATTENDED_MIGRATION, + QEMU_PROCESS_EVENT_RESET, QEMU_PROCESS_EVENT_LAST } qemuProcessEventType; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4af8a8691c..25a1f6e0fd 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3922,6 +3922,19 @@ processMemoryDeviceSizeChange(virQEMUDriver *driver, } +static void +processResetEvent(virQEMUDriver *driver, + virDomainObj *vm) +{ + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + return; + + qemuProcessRefreshState(driver, vm, VIR_ASYNC_JOB_NONE); + + virDomainObjEndJob(vm); +} + + static void qemuProcessEventHandler(void *data, void *opaque) { struct qemuProcessEvent *processEvent = data; @@ -3973,6 +3986,9 @@ static void qemuProcessEventHandler(void *data, void *opaque) processEvent->action, processEvent->status); break; + case QEMU_PROCESS_EVENT_RESET: + processResetEvent(driver, vm); + break; case QEMU_PROCESS_EVENT_LAST: break; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c542be5036..5de55435d2 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -432,6 +432,8 @@ qemuProcessHandleReset(qemuMonitor *mon G_GNUC_UNUSED, qemuDomainSetFakeReboot(vm, false); qemuDomainSaveStatus(vm); + qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_RESET, 0, 0, NULL); + unlock: virObjectUnlock(vm); virObjectEventStateQueue(driver->domainEventState, event); -- 2.38.1

On a Tuesday in 2022, Kristina Hanicova wrote:
v1: https://listman.redhat.com/archives/libvir-list/2022-November/235913.html
diff to v1: * calling refresh state unconditionally (suggested by Martin) * improved commit message
Kristina Hanicova (2): qemu: refresh internal domain state after reset qemu: refresh state after reboot initiated from the guest
src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_driver.c | 19 +++++++++++++++++++ src/qemu/qemu_process.c | 2 ++ 4 files changed, 23 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Kristina Hanicova