From b1b037fa5b4444243d72eadf0e31aa0f3e9389cb Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Tue, 28 Feb 2023 16:53:29 +0100 Subject: [PATCH] Introduce VIR_DOMAIN_PAUSED_API_ERROR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some APIs (migration, save/restore, snapshot, ...) require a domain to be suspended temporarily. In case resuming the domain fails, the domain will be unexpectedly left paused when the API finishes. This situation is reported via VIR_DOMAIN_EVENT_SUSPENDED event with VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR detail. But we do not have a corresponding reason for VIR_DOMAIN_PAUSED state and the reason would remain set to the value used when the domain was paused. So the state reason would suggest the operation is still running. This patch changes the state reason to a new VIR_DOMAIN_PAUSED_API_ERROR to make it clear the API that paused the domain already finished, but failed to resume the domain. Signed-off-by: Jiri Denemark Reviewed-by: Ján Tomko --- include/libvirt/libvirt-domain.h | 1 + src/conf/domain_conf.c | 1 + src/qemu/qemu_domain.c | 3 +++ src/qemu/qemu_driver.c | 8 ++++++++ src/qemu/qemu_snapshot.c | 8 ++++++++ tools/virsh-domain-monitor.c | 1 + 6 files changed, 22 insertions(+) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 53cab6bd4c..3ebb2c6642 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -148,6 +148,7 @@ typedef enum { VIR_DOMAIN_PAUSED_STARTING_UP = 11, /* the domain is being started (Since: 1.2.14) */ VIR_DOMAIN_PAUSED_POSTCOPY = 12, /* paused for post-copy migration (Since: 1.3.3) */ VIR_DOMAIN_PAUSED_POSTCOPY_FAILED = 13, /* paused after failed post-copy (Since: 1.3.3) */ + VIR_DOMAIN_PAUSED_API_ERROR = 14, /* Some APIs (e.g., migration, snapshot) internally need to suspend a domain. This paused state reason is used when resume operation at the end of such API fails. (Since: 9.2.0) */ # ifdef VIR_ENUM_SENTINELS VIR_DOMAIN_PAUSED_LAST /* (Since: 0.9.10) */ diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 783d3a5fff..9ef50c818b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1163,6 +1163,7 @@ VIR_ENUM_IMPL(virDomainPausedReason, "starting up", "post-copy", "post-copy failed", + "api error", ); VIR_ENUM_IMPL(virDomainShutdownReason, diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0feab09bee..72940efefb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11376,6 +11376,9 @@ qemuDomainPausedReasonToSuspendedEvent(virDomainPausedReason reason) case VIR_DOMAIN_PAUSED_POSTCOPY: return VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY; + case VIR_DOMAIN_PAUSED_API_ERROR: + return VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR; + case VIR_DOMAIN_PAUSED_UNKNOWN: case VIR_DOMAIN_PAUSED_USER: case VIR_DOMAIN_PAUSED_SAVE: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fd8136be37..b900015dcf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2727,6 +2727,10 @@ qemuDomainSaveInternal(virQEMUDriver *driver, virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR)); + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, + VIR_DOMAIN_PAUSED_API_ERROR); + } } virErrorRestore(&save_err); } @@ -3254,6 +3258,10 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom, event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, + VIR_DOMAIN_PAUSED_API_ERROR); + } if (virGetLastErrorCode() == VIR_ERR_OK) virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after dump failed")); diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 7aa4195f04..14353c6f0d 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -326,6 +326,10 @@ qemuSnapshotCreateActiveInternal(virQEMUDriver *driver, event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, + VIR_DOMAIN_PAUSED_API_ERROR); + } if (virGetLastErrorCode() == VIR_ERR_OK) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after snapshot failed")); @@ -1398,6 +1402,10 @@ qemuSnapshotCreateActiveExternal(virQEMUDriver *driver, VIR_DOMAIN_EVENT_SUSPENDED, VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR); virObjectEventStateQueue(driver->domainEventState, event); + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, + VIR_DOMAIN_PAUSED_API_ERROR); + } if (virGetLastErrorCode() == VIR_ERR_OK) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("resuming after snapshot failed")); diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index c2134faba1..bdade8f251 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -192,6 +192,7 @@ VIR_ENUM_IMPL(virshDomainPausedReason, N_("starting up"), N_("post-copy"), N_("post-copy failed"), + N_("api error"), ); VIR_ENUM_DECL(virshDomainShutdownReason);