]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: hook: Provide hook when restoring a domain save image
authorPeter Krempa <pkrempa@redhat.com>
Wed, 17 Sep 2014 09:38:39 +0000 (11:38 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 22 Sep 2014 15:11:56 +0000 (17:11 +0200)
docs/hooks.html.in
src/qemu/qemu_driver.c
src/util/virhook.c
src/util/virhook.h

index 07b9d499862afcbc7942e58c51d20352b3c5bb34..1aae00c77bbfda0e2e6d1d06fc020287d5b06ce0 100644 (file)
         script returns failure or the output XML is not valid, incoming
         migration will be canceled. This hook may be used, e.g., to change
         location of disk images for incoming domains.</li>
+      <li><span class="since">Since 1.2.9</span>, the qemu hook script is
+        also called when restoring a saved image either via the API or
+        automatically when restoring a managed save machine. It is called
+        as: <pre>/etc/libvirt/hooks/qemu guest_name restore begin -</pre>
+        with domain XML sent to standard input of the script. In this case,
+        the script acts as a filter and is supposed to modify the domain
+        XML and print it out on its standard output. Empty output is
+        identical to copying the input XML without changing it. In case the
+        script returns failure or the output XML is not valid, restore of the
+        image will be aborted. This hook may be used, e.g., to change
+        location of disk images for restored domains.</li>
       <li><span class="since">Since 0.9.13</span>, the qemu hook script
         is also called when the libvirtd daemon restarts and reconnects
         to previously running QEMU processes. If the script fails, the
index ee542bf8822cbb51735b00ffa3a6b471031466f2..e73d4f91789ff050dd5db93bdd9bfee9b86f30b1 100644 (file)
@@ -5644,20 +5644,24 @@ qemuDomainRestoreFlags(virConnectPtr conn,
                        unsigned int flags)
 {
     virQEMUDriverPtr driver = conn->privateData;
+    qemuDomainObjPrivatePtr priv = NULL;
     virDomainDefPtr def = NULL;
-    virDomainDefPtr newdef = NULL;
     virDomainObjPtr vm = NULL;
+    char *xml = NULL;
+    char *xmlout = NULL;
+    const char *newxml = dxml;
     int fd = -1;
     int ret = -1;
     virQEMUSaveHeader header;
     virFileWrapperFdPtr wrapperFd = NULL;
+    bool hook_taint = false;
 
     virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
                   VIR_DOMAIN_SAVE_RUNNING |
                   VIR_DOMAIN_SAVE_PAUSED, -1);
 
 
-    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
+    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
                                  (flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
                                  &wrapperFd, false, false);
     if (fd < 0)
@@ -5666,12 +5670,31 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
         goto cleanup;
 
-    if (dxml) {
-        if (!(newdef = qemuDomainSaveImageUpdateDef(driver, def, dxml)))
+    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+        int hookret;
+
+        if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
+                                   VIR_HOOK_QEMU_OP_RESTORE,
+                                   VIR_HOOK_SUBOP_BEGIN,
+                                   NULL,
+                                   dxml ? dxml : xml,
+                                   &xmlout)) < 0)
+            goto cleanup;
+
+        if (hookret == 0 && xmlout) {
+            VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
+            hook_taint = true;
+            newxml = xmlout;
+        }
+    }
+
+    if (newxml) {
+        virDomainDefPtr tmp;
+        if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, newxml)))
             goto cleanup;
 
         virDomainDefFree(def);
-        def = newdef;
+        def = tmp;
     }
 
     if (!(vm = virDomainObjListAdd(driver->domains, def,
@@ -5687,6 +5710,11 @@ qemuDomainRestoreFlags(virConnectPtr conn,
     else if (flags & VIR_DOMAIN_SAVE_PAUSED)
         header.was_running = 0;
 
+    if (hook_taint) {
+        priv = vm->privateData;
+        priv->hookRun = true;
+    }
+
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
 
@@ -5705,6 +5733,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,
  cleanup:
     virDomainDefFree(def);
     VIR_FORCE_CLOSE(fd);
+    VIR_FREE(xml);
+    VIR_FREE(xmlout);
     virFileWrapperFdFree(wrapperFd);
     if (vm)
         virObjectUnlock(vm);
@@ -5842,12 +5872,15 @@ qemuDomainObjRestore(virConnectPtr conn,
                      bool bypass_cache)
 {
     virDomainDefPtr def = NULL;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
     int fd = -1;
     int ret = -1;
+    char *xml = NULL;
+    char *xmlout = NULL;
     virQEMUSaveHeader header;
     virFileWrapperFdPtr wrapperFd = NULL;
 
-    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
+    fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
                                  bypass_cache, &wrapperFd, false, true);
     if (fd < 0) {
         if (fd == -3)
@@ -5855,6 +5888,29 @@ qemuDomainObjRestore(virConnectPtr conn,
         goto cleanup;
     }
 
+    if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
+        int hookret;
+
+        if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
+                                   VIR_HOOK_QEMU_OP_RESTORE,
+                                   VIR_HOOK_SUBOP_BEGIN,
+                                   NULL, xml, &xmlout)) < 0)
+            goto cleanup;
+
+        if (hookret == 0 && xmlout) {
+            virDomainDefPtr tmp;
+
+            VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
+
+            if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, xmlout)))
+                goto cleanup;
+
+            virDomainDefFree(def);
+            def = tmp;
+            priv->hookRun = true;
+        }
+    }
+
     if (STRNEQ(vm->def->name, def->name) ||
         memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
         char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -5878,6 +5934,8 @@ qemuDomainObjRestore(virConnectPtr conn,
         VIR_WARN("Failed to close %s", path);
 
  cleanup:
+    VIR_FREE(xml);
+    VIR_FREE(xmlout);
     virDomainDefFree(def);
     VIR_FORCE_CLOSE(fd);
     virFileWrapperFdFree(wrapperFd);
index ac7b40f49814502856e214c1e8ef2f3e4fa7e705..25d0783bfb5e16883c0c225b07b5684b3fe03d17 100644 (file)
@@ -77,7 +77,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
               "migrate",
               "started",
               "reconnect",
-              "attach")
+              "attach",
+              "restore")
 
 VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
               "start",
index 5bc0a5f63038149e09dcd3d7a1fdff711637a631..550ef84a38ef6c9cc78fd0f65dbbf7723288f14e 100644 (file)
@@ -60,6 +60,7 @@ typedef enum {
     VIR_HOOK_QEMU_OP_STARTED,          /* domain has started */
     VIR_HOOK_QEMU_OP_RECONNECT,        /* domain is being reconnected by libvirt */
     VIR_HOOK_QEMU_OP_ATTACH,           /* domain is being attached to be libvirt */
+    VIR_HOOK_QEMU_OP_RESTORE,          /* domain is being restored */
 
     VIR_HOOK_QEMU_OP_LAST,
 } virHookQemuOpType;