9119d9
From daa6ee36e4fc3e17119231f110b4de770ffd2b6c Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <daa6ee36e4fc3e17119231f110b4de770ffd2b6c@dist-git>
9119d9
From: Peter Krempa <pkrempa@redhat.com>
9119d9
Date: Mon, 22 Sep 2014 17:52:40 +0200
9119d9
Subject: [PATCH] qemu: hook: Provide hook when restoring a domain save image
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1142693
9119d9
9119d9
(cherry picked from commit 4f3c2e39e5c898c533ddf58b62b452a674df794d)
9119d9
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 docs/hooks.html.in     | 11 ++++++++
9119d9
 src/qemu/qemu_driver.c | 70 +++++++++++++++++++++++++++++++++++++++++++++-----
9119d9
 src/util/virhook.c     |  3 ++-
9119d9
 src/util/virhook.h     |  1 +
9119d9
 4 files changed, 78 insertions(+), 7 deletions(-)
9119d9
9119d9
diff --git a/docs/hooks.html.in b/docs/hooks.html.in
9119d9
index 07b9d49..1aae00c 100644
9119d9
--- a/docs/hooks.html.in
9119d9
+++ b/docs/hooks.html.in
9119d9
@@ -177,6 +177,17 @@
9119d9
         script returns failure or the output XML is not valid, incoming
9119d9
         migration will be canceled. This hook may be used, e.g., to change
9119d9
         location of disk images for incoming domains.
9119d9
+      
  • Since 1.2.9, the qemu hook script is
  • 9119d9
    +        also called when restoring a saved image either via the API or
    9119d9
    +        automatically when restoring a managed save machine. It is called
    9119d9
    +        as: 
    /etc/libvirt/hooks/qemu guest_name restore begin -
    9119d9
    +        with domain XML sent to standard input of the script. In this case,
    9119d9
    +        the script acts as a filter and is supposed to modify the domain
    9119d9
    +        XML and print it out on its standard output. Empty output is
    9119d9
    +        identical to copying the input XML without changing it. In case the
    9119d9
    +        script returns failure or the output XML is not valid, restore of the
    9119d9
    +        image will be aborted. This hook may be used, e.g., to change
    9119d9
    +        location of disk images for restored domains.
    9119d9
           
  • Since 0.9.13, the qemu hook script
  • 9119d9
             is also called when the libvirtd daemon restarts and reconnects
    9119d9
             to previously running QEMU processes. If the script fails, the
    9119d9
    diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
    9119d9
    index 580ac17..8f655e5 100644
    9119d9
    --- a/src/qemu/qemu_driver.c
    9119d9
    +++ b/src/qemu/qemu_driver.c
    9119d9
    @@ -5643,20 +5643,24 @@ qemuDomainRestoreFlags(virConnectPtr conn,
    9119d9
                            unsigned int flags)
    9119d9
     {
    9119d9
         virQEMUDriverPtr driver = conn->privateData;
    9119d9
    +    qemuDomainObjPrivatePtr priv = NULL;
    9119d9
         virDomainDefPtr def = NULL;
    9119d9
    -    virDomainDefPtr newdef = NULL;
    9119d9
         virDomainObjPtr vm = NULL;
    9119d9
    +    char *xml = NULL;
    9119d9
    +    char *xmlout = NULL;
    9119d9
    +    const char *newxml = dxml;
    9119d9
         int fd = -1;
    9119d9
         int ret = -1;
    9119d9
         virQEMUSaveHeader header;
    9119d9
         virFileWrapperFdPtr wrapperFd = NULL;
    9119d9
    +    bool hook_taint = false;
    9119d9
     
    9119d9
         virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
    9119d9
                       VIR_DOMAIN_SAVE_RUNNING |
    9119d9
                       VIR_DOMAIN_SAVE_PAUSED, -1);
    9119d9
     
    9119d9
     
    9119d9
    -    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
    9119d9
    +    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
    9119d9
                                      (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
    9119d9
                                      &wrapperFd, false, false);
    9119d9
         if (fd < 0)
    9119d9
    @@ -5665,12 +5669,31 @@ qemuDomainRestoreFlags(virConnectPtr conn,
    9119d9
         if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
    9119d9
             goto cleanup;
    9119d9
     
    9119d9
    -    if (dxml) {
    9119d9
    -        if (!(newdef = qemuDomainSaveImageUpdateDef(driver, def, dxml)))
    9119d9
    +    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
    9119d9
    +        int hookret;
    9119d9
    +
    9119d9
    +        if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
    9119d9
    +                                   VIR_HOOK_QEMU_OP_RESTORE,
    9119d9
    +                                   VIR_HOOK_SUBOP_BEGIN,
    9119d9
    +                                   NULL,
    9119d9
    +                                   dxml ? dxml : xml,
    9119d9
    +                                   &xmlout)) < 0)
    9119d9
    +            goto cleanup;
    9119d9
    +
    9119d9
    +        if (hookret == 0 && xmlout) {
    9119d9
    +            VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
    9119d9
    +            hook_taint = true;
    9119d9
    +            newxml = xmlout;
    9119d9
    +        }
    9119d9
    +    }
    9119d9
    +
    9119d9
    +    if (newxml) {
    9119d9
    +        virDomainDefPtr tmp;
    9119d9
    +        if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, newxml)))
    9119d9
                 goto cleanup;
    9119d9
     
    9119d9
             virDomainDefFree(def);
    9119d9
    -        def = newdef;
    9119d9
    +        def = tmp;
    9119d9
         }
    9119d9
     
    9119d9
         if (!(vm = virDomainObjListAdd(driver->domains, def,
    9119d9
    @@ -5686,6 +5709,11 @@ qemuDomainRestoreFlags(virConnectPtr conn,
    9119d9
         else if (flags & VIR_DOMAIN_SAVE_PAUSED)
    9119d9
             header.was_running = 0;
    9119d9
     
    9119d9
    +    if (hook_taint) {
    9119d9
    +        priv = vm->privateData;
    9119d9
    +        priv->hookRun = true;
    9119d9
    +    }
    9119d9
    +
    9119d9
         if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
    9119d9
             goto cleanup;
    9119d9
     
    9119d9
    @@ -5704,6 +5732,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,
    9119d9
      cleanup:
    9119d9
         virDomainDefFree(def);
    9119d9
         VIR_FORCE_CLOSE(fd);
    9119d9
    +    VIR_FREE(xml);
    9119d9
    +    VIR_FREE(xmlout);
    9119d9
         virFileWrapperFdFree(wrapperFd);
    9119d9
         if (vm)
    9119d9
             virObjectUnlock(vm);
    9119d9
    @@ -5841,12 +5871,15 @@ qemuDomainObjRestore(virConnectPtr conn,
    9119d9
                          bool bypass_cache)
    9119d9
     {
    9119d9
         virDomainDefPtr def = NULL;
    9119d9
    +    qemuDomainObjPrivatePtr priv = vm->privateData;
    9119d9
         int fd = -1;
    9119d9
         int ret = -1;
    9119d9
    +    char *xml = NULL;
    9119d9
    +    char *xmlout = NULL;
    9119d9
         virQEMUSaveHeader header;
    9119d9
         virFileWrapperFdPtr wrapperFd = NULL;
    9119d9
     
    9119d9
    -    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
    9119d9
    +    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
    9119d9
                                      bypass_cache, &wrapperFd, false, true);
    9119d9
         if (fd < 0) {
    9119d9
             if (fd == -3)
    9119d9
    @@ -5854,6 +5887,29 @@ qemuDomainObjRestore(virConnectPtr conn,
    9119d9
             goto cleanup;
    9119d9
         }
    9119d9
     
    9119d9
    +    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
    9119d9
    +        int hookret;
    9119d9
    +
    9119d9
    +        if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
    9119d9
    +                                   VIR_HOOK_QEMU_OP_RESTORE,
    9119d9
    +                                   VIR_HOOK_SUBOP_BEGIN,
    9119d9
    +                                   NULL, xml, &xmlout)) < 0)
    9119d9
    +            goto cleanup;
    9119d9
    +
    9119d9
    +        if (hookret == 0 && xmlout) {
    9119d9
    +            virDomainDefPtr tmp;
    9119d9
    +
    9119d9
    +            VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
    9119d9
    +
    9119d9
    +            if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, xmlout)))
    9119d9
    +                goto cleanup;
    9119d9
    +
    9119d9
    +            virDomainDefFree(def);
    9119d9
    +            def = tmp;
    9119d9
    +            priv->hookRun = true;
    9119d9
    +        }
    9119d9
    +    }
    9119d9
    +
    9119d9
         if (STRNEQ(vm->def->name, def->name) ||
    9119d9
             memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
    9119d9
             char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
    9119d9
    @@ -5877,6 +5933,8 @@ qemuDomainObjRestore(virConnectPtr conn,
    9119d9
             VIR_WARN("Failed to close %s", path);
    9119d9
     
    9119d9
      cleanup:
    9119d9
    +    VIR_FREE(xml);
    9119d9
    +    VIR_FREE(xmlout);
    9119d9
         virDomainDefFree(def);
    9119d9
         VIR_FORCE_CLOSE(fd);
    9119d9
         virFileWrapperFdFree(wrapperFd);
    9119d9
    diff --git a/src/util/virhook.c b/src/util/virhook.c
    9119d9
    index ac7b40f..25d0783 100644
    9119d9
    --- a/src/util/virhook.c
    9119d9
    +++ b/src/util/virhook.c
    9119d9
    @@ -77,7 +77,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
    9119d9
                   "migrate",
    9119d9
                   "started",
    9119d9
                   "reconnect",
    9119d9
    -              "attach")
    9119d9
    +              "attach",
    9119d9
    +              "restore")
    9119d9
     
    9119d9
     VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
    9119d9
                   "start",
    9119d9
    diff --git a/src/util/virhook.h b/src/util/virhook.h
    9119d9
    index 5bc0a5f..550ef84 100644
    9119d9
    --- a/src/util/virhook.h
    9119d9
    +++ b/src/util/virhook.h
    9119d9
    @@ -60,6 +60,7 @@ typedef enum {
    9119d9
         VIR_HOOK_QEMU_OP_STARTED,          /* domain has started */
    9119d9
         VIR_HOOK_QEMU_OP_RECONNECT,        /* domain is being reconnected by libvirt */
    9119d9
         VIR_HOOK_QEMU_OP_ATTACH,           /* domain is being attached to be libvirt */
    9119d9
    +    VIR_HOOK_QEMU_OP_RESTORE,          /* domain is being restored */
    9119d9
     
    9119d9
         VIR_HOOK_QEMU_OP_LAST,
    9119d9
     } virHookQemuOpType;
    9119d9
    -- 
    9119d9
    2.1.1
    9119d9