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(a)redhat.com>
---
src/qemu/qemu_driver.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4bb4819..3e407d7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9421,6 +9421,7 @@ qemuDomainBlockResize(virDomainPtr dom,
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
int ret = -1, idx;
+ unsigned long long size_up;
char *device = NULL;
virDomainDiskDefPtr disk = NULL;
@@ -9441,6 +9442,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)))
@@ -9467,6 +9474,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;
--
1.9.0