d89b3e
From 61fbb57d74cc44594b5bcb184c350ab18b963291 Mon Sep 17 00:00:00 2001
d89b3e
Message-Id: <61fbb57d74cc44594b5bcb184c350ab18b963291@dist-git>
d89b3e
From: Eric Blake <eblake@redhat.com>
d89b3e
Date: Tue, 24 Feb 2015 11:59:51 +0100
d89b3e
Subject: [PATCH] blockjob: shuffle block rebase code
d89b3e
d89b3e
https://bugzilla.redhat.com/show_bug.cgi?id=1196066
d89b3e
d89b3e
The existing virDomainBlockRebase code rejected the combination of
d89b3e
_RELATIVE and _COPY flags, but only by accident.  It makes sense
d89b3e
to add support for the combination someday, at least for the case
d89b3e
of _SHALLOW and not _REUSE_EXT; but to implement it, libvirt would
d89b3e
have to pre-create the file with a relative backing name, and I'm
d89b3e
not ready to code that in yet.
d89b3e
d89b3e
Meanwhile, the code to forward on to the block copy code is getting
d89b3e
longer, and reorganizing the function to have the block pull done
d89b3e
early makes it easier to add even more block copy prep code.
d89b3e
d89b3e
This patch should have no semantic difference other than the quality
d89b3e
of the error message on the unsupported flag combination.  Pre-patch:
d89b3e
d89b3e
error: unsupported flags (0x10) in function qemuDomainBlockCopy
d89b3e
d89b3e
Post-patch:
d89b3e
d89b3e
error: argument unsupported: Relative backing during copy not supported yet
d89b3e
d89b3e
* src/qemu/qemu_driver.c (qemuDomainBlockRebase): Reorder code,
d89b3e
and improve error message of relative copy.
d89b3e
d89b3e
Signed-off-by: Eric Blake <eblake@redhat.com>
d89b3e
(cherry picked from commit 02d2bd7d91c200d1ea1a5b3f78c8b41720cea832)
d89b3e
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
d89b3e
---
d89b3e
 src/qemu/qemu_driver.c | 47 ++++++++++++++++++++++++++++++++---------------
d89b3e
 1 file changed, 32 insertions(+), 15 deletions(-)
d89b3e
d89b3e
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
d89b3e
index f3b909f..162e039 100644
d89b3e
--- a/src/qemu/qemu_driver.c
d89b3e
+++ b/src/qemu/qemu_driver.c
d89b3e
@@ -15947,6 +15947,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
d89b3e
                       unsigned long bandwidth, unsigned int flags)
d89b3e
 {
d89b3e
     virDomainObjPtr vm;
d89b3e
+    const char *format = NULL;
d89b3e
+    int ret = -1;
d89b3e
 
d89b3e
     virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
d89b3e
                   VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
d89b3e
@@ -15957,22 +15959,37 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
d89b3e
     if (!(vm = qemuDomObjFromDomain(dom)))
d89b3e
         return -1;
d89b3e
 
d89b3e
-    if (virDomainBlockRebaseEnsureACL(dom->conn, vm->def) < 0) {
d89b3e
+    if (virDomainBlockRebaseEnsureACL(dom->conn, vm->def) < 0)
d89b3e
+        goto cleanup;
d89b3e
+
d89b3e
+    /* For normal rebase (enhanced blockpull), the common code handles
d89b3e
+     * everything, including vm cleanup. */
d89b3e
+    if (!(flags & VIR_DOMAIN_BLOCK_REBASE_COPY))
d89b3e
+        return qemuDomainBlockJobImpl(vm, dom->conn, path, base, bandwidth,
d89b3e
+                                      NULL, BLOCK_JOB_PULL, flags);
d89b3e
+
d89b3e
+    /* If we got here, we are doing a block copy rebase. */
d89b3e
+    if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
d89b3e
+        format = "raw";
d89b3e
+
d89b3e
+    /* XXX: If we are doing a shallow copy but not reusing an external
d89b3e
+     * file, we should attempt to pre-create the destination with a
d89b3e
+     * relative backing chain instead of qemu's default of absolute */
d89b3e
+    if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE) {
d89b3e
+        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
d89b3e
+                       _("Relative backing during copy not supported yet"));
d89b3e
+        goto cleanup;
d89b3e
+    }
d89b3e
+
d89b3e
+    flags &= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
d89b3e
+              VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT);
d89b3e
+    ret = qemuDomainBlockCopy(vm, dom->conn, path, base, format,
d89b3e
+                              bandwidth, flags);
d89b3e
+    vm = NULL;
d89b3e
+ cleanup:
d89b3e
+    if (vm)
d89b3e
         virObjectUnlock(vm);
d89b3e
-        return -1;
d89b3e
-    }
d89b3e
-
d89b3e
-    if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY) {
d89b3e
-        const char *format = NULL;
d89b3e
-        if (flags & VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
d89b3e
-            format = "raw";
d89b3e
-        flags &= ~(VIR_DOMAIN_BLOCK_REBASE_COPY |
d89b3e
-                   VIR_DOMAIN_BLOCK_REBASE_COPY_RAW);
d89b3e
-        return qemuDomainBlockCopy(vm, dom->conn, path, base, format, bandwidth, flags);
d89b3e
-    }
d89b3e
-
d89b3e
-    return qemuDomainBlockJobImpl(vm, dom->conn, path, base, bandwidth, NULL,
d89b3e
-                                  BLOCK_JOB_PULL, flags);
d89b3e
+    return ret;
d89b3e
 }
d89b3e
 
d89b3e
 static int
d89b3e
-- 
d89b3e
2.3.0
d89b3e