]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Adjust size for qcow2/qed if not on sector boundary
authorJohn Ferlan <jferlan@redhat.com>
Tue, 8 Apr 2014 14:59:09 +0000 (10:59 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Wed, 7 May 2014 11:25:16 +0000 (07:25 -0400)
https://bugzilla.redhat.com/show_bug.cgi?id=1002813

If qemuDomainBlockResize() is passed a size not on a KiB boundary - that
is passed a size based in bytes (VIR_DOMAIN_BLOCK_RESIZE_BYTES), then
depending on the source format (qcow2 or qed), the value passed must
be on a sector (or 512 byte) boundary. Since other libvirt code quietly
adjusts the capacity values, then do so here as well - of course ensuring
that adjustment still fits.

Signed-off-by: John Ferlan <jferlan@redhat.com>
src/qemu/qemu_driver.c

index f0e82e9fbfbbba0e652621eb92895b978ce1cc7b..4ff8a2d0d70745d06cd1854a6ba7c9a16b73b286 100644 (file)
@@ -9413,6 +9413,7 @@ qemuDomainBlockResize(virDomainPtr dom,
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
     int ret = -1, idx;
+    unsigned long long size_up;
     char *device = NULL;
     virDomainDiskDefPtr disk = NULL;
 
@@ -9433,6 +9434,12 @@ qemuDomainBlockResize(virDomainPtr dom,
             return -1;
         }
         size *= 1024;
+        size_up = size;
+    } else {
+        /* For 'qcow2' and 'qed', qemu resize blocks expects values
+         * on sector boundary, so round our value up to prepare
+         */
+        size_up = VIR_ROUND_UP(size, 512);
     }
 
     if (!(vm = qemuDomObjFromDomain(dom)))
@@ -9459,6 +9466,21 @@ qemuDomainBlockResize(virDomainPtr dom,
     }
     disk = vm->def->disks[idx];
 
+    /* qcow2 and qed must be sized appropriately, so be sure our value
+     * is sized appropriately and will fit
+     */
+    if (size != size_up &&
+        (disk->src.format == VIR_STORAGE_FILE_QCOW2 ||
+         disk->src.format == VIR_STORAGE_FILE_QED)) {
+        if (size_up > ULLONG_MAX) {
+            virReportError(VIR_ERR_OVERFLOW,
+                           _("size must be less than %llu KiB"),
+                           ULLONG_MAX / 1024);
+            goto endjob;
+        }
+        size = size_up;
+    }
+
     if (virAsprintf(&device, "%s%s", QEMU_DRIVE_HOST_PREFIX,
                     disk->info.alias) < 0)
         goto endjob;