[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCHv6 7/8] blockjob: allow for existing files



This copies some of the checks from snapshots regarding testing
when a file already exists.  In the process, I noticed snapshots
had hard-to-read logic, as well as a missing sanity check:
REUSE_EXT should require the destination to already be present.

* src/qemu/qemu_driver.c (qemuDomainBlockRebase): Allow REUSE_EXT
flag.
(qemuDomainBlockCopy): Wire up flag, and add some sanity checks.
(qemuDomainSnapshotDiskPrepare): Require destination on REUSE_EXT.
---

v6: no real change from v5

 src/qemu/qemu_driver.c |   50 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cebbf46..e3d3280 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9829,8 +9829,13 @@ qemuDomainSnapshotDiskPrepare(virDomainObjPtr vm, virDomainSnapshotDefPtr def,
                                          _("unable to stat for disk %s: %s"),
                                          disk->name, disk->file);
                     goto cleanup;
+                } else if (allow_reuse) {
+                    virReportSystemError(errno,
+                                         _("missing existing file for disk %s: %s"),
+                                         disk->name, disk->file);
+                    goto cleanup;
                 }
-            } else if (!(S_ISBLK(st.st_mode) || !st.st_size || allow_reuse)) {
+            } else if (!S_ISBLK(st.st_mode) && st.st_size && !allow_reuse) {
                 qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                                 _("external snapshot file for disk %s already "
                                   "exists and is not a block device: %s"),
@@ -11962,9 +11967,11 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
     virDomainDiskDefPtr disk;
     int ret = -1;
     int idx;
+    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);
@@ -12016,12 +12023,42 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path,
         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_SHALLOW) &&
+        STREQ_NULLABLE(format, "raw") &&
+        STRNEQ_NULLABLE(disk->driverType, "raw")) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("raw shallow copy of non-raw disk '%s' not possible"),
+                        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 (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) {
+            virReportSystemError(errno,
+                                 _("missing destination file 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))) {
@@ -12060,6 +12097,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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]