[PATCH] qemu: add hook script event "stop"

Adam Julis posted 1 patch 2 weeks, 1 day ago
docs/hooks.rst          | 14 +++++++++++---
src/qemu/qemu_process.c | 10 ++++++++++
src/util/virhook.c      |  1 +
src/util/virhook.h      |  1 +
4 files changed, 23 insertions(+), 3 deletions(-)
[PATCH] qemu: add hook script event "stop"
Posted by Adam Julis 2 weeks, 1 day ago
The "stop" hook is called when the process of stopping a guest
started and it is known that the process can be completed
(e.g. the guest is still active).

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/647
Signed-off-by: Adam Julis <ajulis@redhat.com>
---
 docs/hooks.rst          | 14 +++++++++++---
 src/qemu/qemu_process.c | 10 ++++++++++
 src/util/virhook.c      |  1 +
 src/util/virhook.h      |  1 +
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/docs/hooks.rst b/docs/hooks.rst
index 48128ba3d8..508d5afc4e 100644
--- a/docs/hooks.rst
+++ b/docs/hooks.rst
@@ -202,9 +202,17 @@ operation. There is no specific operation to indicate a "restart" is occurring.
 
       /etc/libvirt/hooks/qemu guest_name started begin -
 
--  When a QEMU guest is stopped, the qemu hook script is called in two
-   locations, to match the startup. First, :since:`since 0.8.0`, the hook is
-   called before libvirt restores any labels:
+-  Before a QEMU guest is stopped, the qemu hook script is called in three
+   locations, to match the startup. First, :since:`since 10.8.0`, the hook is
+   called after libvirt checks that guest is still active and whole stopping
+   procedure should be run:
+
+   ::
+
+      /etc/libvirt/hooks/qemu guest_name stop begin -
+
+   The second location, :since:`since 0.8.0`, the hook is called before libvirt
+   restores any labels:
 
    ::
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2e4ee9e305..f12c4a97a6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -8615,6 +8615,7 @@ qemuProcessBeginStopJob(virDomainObj *vm,
      * is supposed to call qemuProcessStop (which will reset it after
      * 'vm->def->id' is set to -1) and/or qemuProcessEndStopJob to do proper
      * cleanup. */
+
     return 0;
 
  error:
@@ -8676,6 +8677,15 @@ void qemuProcessStop(virQEMUDriver *driver,
         goto endjob;
     }
 
+    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+        g_autofree char *xml = qemuDomainDefFormatXML(driver, NULL, vm->def, 0);
+
+        /* we can't stop the operation even if the script raised an error */
+        ignore_value(virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
+                                 VIR_HOOK_QEMU_OP_STOP, VIR_HOOK_SUBOP_BEGIN,
+                                 NULL, xml, NULL));
+    }
+
     /* BEWARE: At this point 'vm->def->id' is not cleared yet. Any code that
      * requires the id (e.g. to call virDomainDefGetShortName()) must be placed
      * between here (after the VM is killed) and the statement clearing the id.
diff --git a/src/util/virhook.c b/src/util/virhook.c
index d012bb1825..01ba17e406 100644
--- a/src/util/virhook.c
+++ b/src/util/virhook.c
@@ -76,6 +76,7 @@ VIR_ENUM_IMPL(virHookSubop,
 VIR_ENUM_IMPL(virHookQemuOp,
               VIR_HOOK_QEMU_OP_LAST,
               "start",
+              "stop",
               "stopped",
               "prepare",
               "release",
diff --git a/src/util/virhook.h b/src/util/virhook.h
index d8237c837e..ea8c540c3f 100644
--- a/src/util/virhook.h
+++ b/src/util/virhook.h
@@ -52,6 +52,7 @@ typedef enum {
 
 typedef enum {
     VIR_HOOK_QEMU_OP_START,            /* domain is about to start */
+    VIR_HOOK_QEMU_OP_STOP,             /* domain is about to stop */
     VIR_HOOK_QEMU_OP_STOPPED,          /* domain has stopped */
     VIR_HOOK_QEMU_OP_PREPARE,          /* domain startup initiated */
     VIR_HOOK_QEMU_OP_RELEASE,          /* domain destruction is over */
-- 
2.45.2
Re: [PATCH] qemu: add hook script event "stop"
Posted by Martin Kletzander 3 days, 15 hours ago
On Fri, Sep 20, 2024 at 11:34:51AM +0200, Adam Julis wrote:
>The "stop" hook is called when the process of stopping a guest
>started and it is known that the process can be completed
>(e.g. the guest is still active).
>
>Resolves: https://gitlab.com/libvirt/libvirt/-/issues/647
>Signed-off-by: Adam Julis <ajulis@redhat.com>
>---
> docs/hooks.rst          | 14 +++++++++++---
> src/qemu/qemu_process.c | 10 ++++++++++
> src/util/virhook.c      |  1 +
> src/util/virhook.h      |  1 +
> 4 files changed, 23 insertions(+), 3 deletions(-)
>
>diff --git a/docs/hooks.rst b/docs/hooks.rst
>index 48128ba3d8..508d5afc4e 100644
>--- a/docs/hooks.rst
>+++ b/docs/hooks.rst
>@@ -202,9 +202,17 @@ operation. There is no specific operation to indicate a "restart" is occurring.
>
>       /etc/libvirt/hooks/qemu guest_name started begin -
>
>--  When a QEMU guest is stopped, the qemu hook script is called in two
>-   locations, to match the startup. First, :since:`since 0.8.0`, the hook is
>-   called before libvirt restores any labels:
>+-  Before a QEMU guest is stopped, the qemu hook script is called in three
>+   locations, to match the startup. First, :since:`since 10.8.0`, the hook is
>+   called after libvirt checks that guest is still active and whole stopping
>+   procedure should be run:
>+
>+   ::
>+
>+      /etc/libvirt/hooks/qemu guest_name stop begin -
>+
>+   The second location, :since:`since 0.8.0`, the hook is called before libvirt
>+   restores any labels:
>
>    ::
>
>diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>index 2e4ee9e305..f12c4a97a6 100644
>--- a/src/qemu/qemu_process.c
>+++ b/src/qemu/qemu_process.c
>@@ -8615,6 +8615,7 @@ qemuProcessBeginStopJob(virDomainObj *vm,
>      * is supposed to call qemuProcessStop (which will reset it after
>      * 'vm->def->id' is set to -1) and/or qemuProcessEndStopJob to do proper
>      * cleanup. */
>+

This does not belong here.

>     return 0;
>
>  error:
>@@ -8676,6 +8677,15 @@ void qemuProcessStop(virQEMUDriver *driver,
>         goto endjob;
>     }
>
>+    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
>+        g_autofree char *xml = qemuDomainDefFormatXML(driver, NULL, vm->def, 0);
>+
>+        /* we can't stop the operation even if the script raised an error */

Why couldn't we?  Looks like a copy-paste error...

Rest looks fine.

>+        ignore_value(virHookCall(VIR_HOOK_DRIVER_QEMU, vm->def->name,
>+                                 VIR_HOOK_QEMU_OP_STOP, VIR_HOOK_SUBOP_BEGIN,
>+                                 NULL, xml, NULL));
>+    }
>+
>     /* BEWARE: At this point 'vm->def->id' is not cleared yet. Any code that
>      * requires the id (e.g. to call virDomainDefGetShortName()) must be placed
>      * between here (after the VM is killed) and the statement clearing the id.
>diff --git a/src/util/virhook.c b/src/util/virhook.c
>index d012bb1825..01ba17e406 100644
>--- a/src/util/virhook.c
>+++ b/src/util/virhook.c
>@@ -76,6 +76,7 @@ VIR_ENUM_IMPL(virHookSubop,
> VIR_ENUM_IMPL(virHookQemuOp,
>               VIR_HOOK_QEMU_OP_LAST,
>               "start",
>+              "stop",
>               "stopped",
>               "prepare",
>               "release",
>diff --git a/src/util/virhook.h b/src/util/virhook.h
>index d8237c837e..ea8c540c3f 100644
>--- a/src/util/virhook.h
>+++ b/src/util/virhook.h
>@@ -52,6 +52,7 @@ typedef enum {
>
> typedef enum {
>     VIR_HOOK_QEMU_OP_START,            /* domain is about to start */
>+    VIR_HOOK_QEMU_OP_STOP,             /* domain is about to stop */
>     VIR_HOOK_QEMU_OP_STOPPED,          /* domain has stopped */
>     VIR_HOOK_QEMU_OP_PREPARE,          /* domain startup initiated */
>     VIR_HOOK_QEMU_OP_RELEASE,          /* domain destruction is over */
>-- 
>2.45.2
>