[libvirt] [PATCH v2 0/1] Fix qcow2 fully allocated filesystem objects.

From: Wim ten Have <wim.ten.have@oracle.com> When tools like virt-install request to create a fully allocated filesystem object storage by setting the parameter sparse=no, libvirt doesn't allow that to happen for qcow2 formatted files. Regardless of its XML instuction request libvirt always targets its filesystem object storage with preallocation=metadata if format=qcow2 is in effect. This results in sparse files which could cause problems since total image storage potentially can overrun actual filesystem available space. Changes from v1: * Fix XML target sparse setting and apply for qcow2. * Bring the test change under same PATCH. Wim ten Have (1): storage: extend preallocation flags support for qemu-img src/conf/storage_conf.c | 3 +++ src/storage/storage_util.c | 10 ++++++++-- .../qcow2-nocapacity-convert-prealloc.argv | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) -- 2.14.3

From: Wim ten Have <wim.ten.have@oracle.com> This patch adds support to qcow2 formatted filesystem object storage by instructing qemu-img to build them with preallocation=falloc whenever the XML described storage <allocation> matches its <capacity>. For all other cases the filesystem stored objects are built with preallocation=metadata. Signed-off-by: Wim ten Have <wim.ten.have@oracle.com> --- src/conf/storage_conf.c | 3 +++ src/storage/storage_util.c | 10 ++++++++-- .../qcow2-nocapacity-convert-prealloc.argv | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 5036ab9ef..2bd077237 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1184,6 +1184,9 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->target.allocation = ret->target.capacity; } + if (ret->target.allocation < ret->target.capacity) + ret->target.sparse = true; + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index b4aed0f70..c4f311ded 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -856,6 +856,7 @@ struct _virStorageBackendQemuImgInfo { const char *compat; virBitmapPtr features; bool nocow; + bool sparse; const char *backingPath; int backingFormat; @@ -884,8 +885,12 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc, virStorageFileFormatTypeToString(info.backingFormat)); if (info.encryption) virBufferAddLit(&buf, "encryption=on,"); - if (info.preallocate) - virBufferAddLit(&buf, "preallocation=metadata,"); + if (info.preallocate) { + if (info.sparse) + virBufferAddLit(&buf, "preallocation=metadata,"); + else + virBufferAddLit(&buf, "preallocation=falloc,"); + } } if (info.nocow) @@ -1187,6 +1192,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, .compat = vol->target.compat, .features = vol->target.features, .nocow = vol->target.nocow, + .sparse = vol->target.sparse, .secretPath = secretPath, .secretAlias = NULL, }; diff --git a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv index 9073b1b16..b151b9401 100644 --- a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv +++ b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv @@ -1,4 +1,4 @@ qemu-img convert -f raw -O qcow2 \ --o encryption=on,preallocation=metadata \ +-o encryption=on,preallocation=falloc \ /var/lib/libvirt/images/sparse.img \ /var/lib/libvirt/images/OtherDemo.img -- 2.14.3

On 04/09/2018 08:14 PM, Wim Ten Have wrote:
From: Wim ten Have <wim.ten.have@oracle.com>
This patch adds support to qcow2 formatted filesystem object storage by instructing qemu-img to build them with preallocation=falloc whenever the XML described storage <allocation> matches its <capacity>. For all other cases the filesystem stored objects are built with preallocation=metadata.
Signed-off-by: Wim ten Have <wim.ten.have@oracle.com> --- src/conf/storage_conf.c | 3 +++ src/storage/storage_util.c | 10 ++++++++-- .../qcow2-nocapacity-convert-prealloc.argv | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 5036ab9ef..2bd077237 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1184,6 +1184,9 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->target.allocation = ret->target.capacity; }
+ if (ret->target.allocation < ret->target.capacity) + ret->target.sparse = true;
This doesn't feel right. This sparse flag is used for different purposes. However, we don't need it. We can just introduce allocation member to _virStorageBackendQemuImgInfo, initialize it and then change ..
+ ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index b4aed0f70..c4f311ded 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -856,6 +856,7 @@ struct _virStorageBackendQemuImgInfo { const char *compat; virBitmapPtr features; bool nocow; + bool sparse;
const char *backingPath; int backingFormat; @@ -884,8 +885,12 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc, virStorageFileFormatTypeToString(info.backingFormat)); if (info.encryption) virBufferAddLit(&buf, "encryption=on,"); - if (info.preallocate) - virBufferAddLit(&buf, "preallocation=metadata,"); + if (info.preallocate) { + if (info.sparse)
.. this condition.
+ virBufferAddLit(&buf, "preallocation=metadata,"); + else + virBufferAddLit(&buf, "preallocation=falloc,"); + } }
if (info.nocow) @@ -1187,6 +1192,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, .compat = vol->target.compat, .features = vol->target.features, .nocow = vol->target.nocow, + .sparse = vol->target.sparse, .secretPath = secretPath, .secretAlias = NULL, }; diff --git a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv index 9073b1b16..b151b9401 100644 --- a/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv +++ b/tests/storagevolxml2argvdata/qcow2-nocapacity-convert-prealloc.argv @@ -1,4 +1,4 @@ qemu-img convert -f raw -O qcow2 \ --o encryption=on,preallocation=metadata \ +-o encryption=on,preallocation=falloc \ /var/lib/libvirt/images/sparse.img \ /var/lib/libvirt/images/OtherDemo.img
ACK with this squashed in: diff --git i/src/conf/storage_conf.c w/src/conf/storage_conf.c index 2bd0772370..5036ab9ef8 100644 --- i/src/conf/storage_conf.c +++ w/src/conf/storage_conf.c @@ -1184,9 +1184,6 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->target.allocation = ret->target.capacity; } - if (ret->target.allocation < ret->target.capacity) - ret->target.sparse = true; - ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); diff --git i/src/storage/storage_util.c w/src/storage/storage_util.c index c4f311ded1..897dfdaaee 100644 --- i/src/storage/storage_util.c +++ w/src/storage/storage_util.c @@ -851,12 +851,12 @@ struct _virStorageBackendQemuImgInfo { int format; const char *path; unsigned long long size_arg; + unsigned long long allocation; bool encryption; bool preallocate; const char *compat; virBitmapPtr features; bool nocow; - bool sparse; const char *backingPath; int backingFormat; @@ -886,7 +886,7 @@ storageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc, if (info.encryption) virBufferAddLit(&buf, "encryption=on,"); if (info.preallocate) { - if (info.sparse) + if (info.size_arg > info.allocation) virBufferAddLit(&buf, "preallocation=metadata,"); else virBufferAddLit(&buf, "preallocation=falloc,"); @@ -1187,12 +1187,12 @@ virStorageBackendCreateQemuImgCmdFromVol(virStoragePoolObjPtr pool, struct _virStorageBackendQemuImgInfo info = { .format = vol->target.format, .path = vol->target.path, + .allocation = vol->target.allocation, .encryption = vol->target.encryption != NULL, .preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA), .compat = vol->target.compat, .features = vol->target.features, .nocow = vol->target.nocow, - .sparse = vol->target.sparse, .secretPath = secretPath, .secretAlias = NULL, }; I'm squashing it in, and pushing. Michal
participants (2)
-
Michal Privoznik
-
Wim Ten Have