[libvirt] [PATCHv2 11/15] blockjob: implement block copy for qemu

Eric Blake eblake at redhat.com
Fri Apr 6 16:43:49 UTC 2012


On 04/06/2012 09:36 AM, Eric Blake wrote:
> On 04/05/2012 10:36 PM, Eric Blake wrote:
>> Minimal patch to wire up all the pieces in the previous patches
>> to actually enable a block copy job.  By minimal, I mean that
>> qemu creates the file, SELinux must be disabled, a lock manager
>> is not informed, and the audit logs aren't updated.  But those
>> will be added as improvements in future patches.
>>

I'm still testing this, but this is probably what I will add as 11.5/15
in my v3 series for allowing the REUSE_EXT flag.

From 804c1b654af7f4dddbd3dd768cce7c041436b761 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake at redhat.com>
Date: Fri, 6 Apr 2012 10:32:07 -0600
Subject: [PATCH] blockjob: allow for existing files

This copies some of the checks from snapshots regarding testing
when a file already exists.

* src/qemu/qemu_driver.c (qemuDomainBlockRebase): Allow REUSE_EXT
flag.
(qemuDomainBlockCopy): Wire up flag, and add some sanity checks.
---
 src/qemu/qemu_driver.c |   51
++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1b1c921..f7b2a01 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11881,9 +11881,11 @@ qemuDomainBlockCopy(virDomainPtr dom, const
char *path,
     int ret = -1;
     int idx;
     int mode;
+    struct stat st;

     /* Preliminaries: find the disk we are editing, sanity checks */
-    virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW, -1);
+    virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
+                  VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT, -1);

     qemuDriverLock(driver);
     virUUIDFormat(dom->uuid, uuidstr);
@@ -11928,19 +11930,55 @@ qemuDomainBlockCopy(virDomainPtr dom, const
char *path,
         goto endjob;
     }

+    if ((flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) &&
+        STREQ_NULLABLE(format, "raw") &&
+        STRNEQ_NULLABLE(disk->driverType, "raw")) {
+        qemuReportError(VIR_ERR_INVALID_ARG,
+                        _("raw shallow copy of non-raw disk '%s' not
possible"),
+                        disk->dst);
+        goto endjob;
+    }
+    /* XXX this is pessimistic; we could use 'query-block' or even
+     * keep track of the backing chain ourselves, rather than assuming
+     * that all non-raw source files have a current backing image */
+    if ((flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) &&
+        !(flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) &&
+        STRNEQ_NULLABLE(disk->driverType, "raw")) {
+        qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
+                        _("non-shallow copy of non-raw disk '%s' to
existing "
+                          "destination not supported"),
+                        disk->dst);
+        goto endjob;
+    }
+
     /* Prepare the destination file.  */
+    if (stat(dest, &st) < 0) {
+        if (errno != ENOENT) {
+            virReportSystemError(errno, _("unable to stat for disk %s:
%s"),
+                                 disk->dst, dest);
+            goto endjob;
+        }
+    } else if (!(S_ISBLK(st.st_mode) || !st.st_size ||
+                 (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("external destination file for disk %s already "
+                          "exists and is not a block device: %s"),
+                        disk->dst, dest);
+        goto endjob;
+    }
+
     /* XXX We also need to add security labeling, lock manager lease,
-     * and auditing of those events, as well as to support reuse of
-     * existing images, including probing the existing format of an
-     * existing image.  */
-    if (!format)
+     * and auditing of those events.  */
+    if (!format && !(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))
         format = disk->driverType;
     if ((format && !(disk->mirrorFormat = strdup(format))) ||
         !(disk->mirror = strdup(dest))) {
         virReportOOMError();
         goto endjob;
     }
-    if (flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
+    if (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
+        mode = QEMU_MONITOR_DRIVE_MIRROR_EXISTING;
+    else if (flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
         mode = QEMU_MONITOR_DRIVE_MIRROR_ABSOLUTE;
     else
         mode = QEMU_MONITOR_DRIVE_MIRROR_NO_BACKING;
@@ -11976,6 +12014,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const
char *path, const char *base,
                       unsigned long bandwidth, unsigned int flags)
 {
     virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
+                  VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
                   VIR_DOMAIN_BLOCK_REBASE_COPY |
                   VIR_DOMAIN_BLOCK_REBASE_COPY_RAW, -1);

-- 
1.7.7.6


-- 
Eric Blake   eblake at redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 620 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120406/b7223186/attachment-0001.sig>


More information about the libvir-list mailing list