From 05d94a43504c87b4335c32bd03fa6ca3c1ad8cae Mon Sep 17 00:00:00 2001 From: Ben Grande Date: Thu, 11 Jun 2026 03:44:57 +0200 Subject: [PATCH] Inform clients about suspend Since there is "resume", and there is a moment when resuming that domain might still be suspended, or event suspending a domain on purposed, allow clients to know the domain state. --- qubes/app.py | 9 +++++++++ qubes/vm/qubesvm.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/qubes/app.py b/qubes/app.py index 955c82caa..15bee90cc 100644 --- a/qubes/app.py +++ b/qubes/app.py @@ -1687,6 +1687,15 @@ def _domain_event_callback(self, _conn, domain, event, _detail, _opaque): if event == libvirt.VIR_DOMAIN_EVENT_STOPPED: vm.on_libvirt_domain_stopped() + elif event == libvirt.VIR_DOMAIN_EVENT_PMSUSPENDED: + try: + vm.fire_event("domain-suspended") + except Exception: # pylint: disable=broad-except + self.log.exception( + "Uncaught exception from domain-suspended handler " + "for domain %s", + vm.name, + ) elif event == libvirt.VIR_DOMAIN_EVENT_SUSPENDED: try: vm.fire_event("domain-paused") diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index 077031f01..08e229de4 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -447,6 +447,15 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.LocalVM): :param subject: Event emitter (the qube object) :param event: Event name (``'domain-unpaused'``) + .. event:: domain-suspended (subject, event) + + Fired when the domain has been suspended. + + Handler for this event may be asynchronous. + + :param subject: Event emitter (the qube object) + :param event: Event name (``'domain-suspended'``) + .. event:: domain-resumed (subject, event) Fired when the domain has been resumed from suspend.