[libvirt] [PATCH libvirt 1/2] storage: add preallocation element

Allow to specify preallocation mode for QCOW2 images. If not specified or not available, it's ignored. This change only modify the schema, doc, parsing and tests. --- docs/formatstorage.html.in | 6 ++++++ docs/schemas/storagevol.rng | 18 ++++++++++++++++++ src/conf/storage_conf.c | 26 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 1 + src/util/storage_file.c | 4 ++++ src/util/storage_file.h | 10 ++++++++++ tests/storagevolxml2xmlin/vol-qcow2.xml | 1 + tests/storagevolxml2xmlout/vol-qcow2.xml | 1 + 8 files changed, 67 insertions(+) diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..c4faadf 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -252,6 +252,12 @@ 1,152,921,504,606,846,976 bytes). <span class="since">Since 0.4.1, multi-character <code>unit</code> since 0.9.11</span></dd> + <dt><code>preallocation</code></dt> + <dd>An image with preallocated metadata is initially larger but + can improve performance when the image needs to grow. This is + supported by QCOW2 image format. + Attribe <code>mode</code> value can be 'off' or 'metadata'. + <span class="since">Since 0.9.13</span></dd> <dt><code>capacity</code></dt> <dd>Providing the logical capacity for the volume. This value is in bytes by default, but a <code>unit</code> attribute can be diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8edb877..d9a148e 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -40,6 +40,7 @@ <ref name='scaledInteger'/> </element> </optional> + <ref name='preallocation'/> </define> <define name='permissions'> @@ -171,6 +172,23 @@ </optional> </define> + <define name='preallocationmode'> + <choice> + <value>off</value> + <value>metadata</value> + </choice> + </define> + + <define name='preallocation'> + <optional> + <element name='preallocation'> + <attribute name='mode'> + <ref name='preallocationmode'/> + </attribute> + </element> + </optional> + </define> + <define name='name'> <data type='string'> <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0b34f28..95849ec 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -991,6 +991,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + char *preallocation = NULL; xmlNodePtr node; options = virStorageVolOptionsForPoolType(pool->type); @@ -1035,6 +1036,19 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->allocation = ret->capacity; } + preallocation = virXPathString("string(./preallocation/@mode)", ctxt); + if (preallocation) { + if ((ret->preallocation = virStoragePreallocationModeTypeFromString(preallocation)) < 0) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown preallocation mode %s"), preallocation); + goto cleanup; + } + + VIR_FREE(preallocation); + } else { + ret->preallocation = VIR_STORAGE_PREALLOCATION_NONE; + } + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); @@ -1244,6 +1258,18 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAsprintf(&buf," <allocation unit='bytes'>%llu</allocation>\n", def->allocation); + if (def->preallocation != VIR_STORAGE_PREALLOCATION_NONE) { + const char *preallocation; + + preallocation = virStoragePreallocationModeTypeToString(def->preallocation); + if (!preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected pool type")); + goto cleanup; + } + virBufferAsprintf(&buf," <preallocation mode='%s'/>\n", preallocation); + } + if (virStorageVolTargetDefFormat(options, &buf, &def->target, "target") < 0) goto cleanup; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9222c4a..c7c7af0 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -98,6 +98,7 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; virStorageVolTarget backingStore; + int preallocation; /* virStoragePreallocationMode enum */ }; typedef struct _virStorageVolDefList virStorageVolDefList; diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 530071e..8d78d36 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -47,6 +47,10 @@ VIR_ENUM_IMPL(virStorageFileFormat, "cloop", "cow", "dmg", "iso", "qcow", "qcow2", "qed", "vmdk", "vpc") +VIR_ENUM_IMPL(virStoragePreallocationMode, + VIR_STORAGE_PREALLOCATION_LAST, + "", "off", "metadata") + enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ diff --git a/src/util/storage_file.h b/src/util/storage_file.h index 13d0e87..dfc8719 100644 --- a/src/util/storage_file.h +++ b/src/util/storage_file.h @@ -46,6 +46,16 @@ enum virStorageFileFormat { VIR_ENUM_DECL(virStorageFileFormat); +enum virStoragePreallocationMode { + VIR_STORAGE_PREALLOCATION_NONE, + VIR_STORAGE_PREALLOCATION_OFF, + VIR_STORAGE_PREALLOCATION_METADATA, + + VIR_STORAGE_PREALLOCATION_LAST +}; + +VIR_ENUM_DECL(virStoragePreallocationMode); + typedef struct _virStorageFileMetadata { char *backingStore; int backingStoreFormat; diff --git a/tests/storagevolxml2xmlin/vol-qcow2.xml b/tests/storagevolxml2xmlin/vol-qcow2.xml index b4924de..b4c6522 100644 --- a/tests/storagevolxml2xmlin/vol-qcow2.xml +++ b/tests/storagevolxml2xmlin/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit="G">5</capacity> <allocation>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml index 4490931..311c52e 100644 --- a/tests/storagevolxml2xmlout/vol-qcow2.xml +++ b/tests/storagevolxml2xmlout/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit='bytes'>5368709120</capacity> <allocation unit='bytes'>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> -- 1.7.10

Use preallocation mode specified in volume XML format when running qemu-img. --- src/storage/storage_backend.c | 63 ++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index caac2f8..ed3217d 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -645,6 +645,38 @@ cleanup: return ret; } +static char * +virStorageQemuImgOptionsStr(virStorageVolDefPtr vol) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + bool do_encryption = (vol->target.encryption != NULL); + const char *backingType = vol->backingStore.path ? + virStorageFileFormatTypeToString(vol->backingStore.format) : NULL; + bool comma = false; + const char *preallocation = vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE ? + virStoragePreallocationModeTypeToString(vol->preallocation) : NULL; + + if (backingType) { + virBufferAddLit(&buf, "backing_fmt="); + virBufferAdd(&buf, backingType, -1); + comma = true; + } + + if (do_encryption) { + virBufferAdd(&buf, comma ? "," : "", -1); + virBufferAddLit(&buf, "encryption=on"); + comma = true; + } + + if (preallocation) { + virBufferAdd(&buf, comma ? "," : "", -1); + virBufferAddLit(&buf, "preallocation="); + virBufferAdd(&buf, preallocation, -1); + comma = true; + } + + return virBufferContentAndReset(&buf); +} static int virStorageBackendCreateQemuImg(virConnectPtr conn, @@ -658,6 +690,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, int imgformat = -1; virCommandPtr cmd = NULL; bool do_encryption = (vol->target.encryption != NULL); + bool with_preallocation = (vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE); unsigned long long int size_arg; virCheckFlags(0, -1); @@ -689,6 +722,12 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, return -1; } + if (vol->target.format != VIR_STORAGE_FILE_QCOW2 && with_preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("Preallocation is only available with qcow2")); + return -1; + } + if (vol->backingStore.path) { int accessRetCode = -1; char *absolutePath = NULL; @@ -781,16 +820,20 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, if (imgformat < 0) goto cleanup; + if (imgformat != QEMU_IMG_BACKING_FORMAT_OPTIONS && with_preallocation) + VIR_INFO("Preallocation not supported with this version of qemu-img"); + cmd = virCommandNew(create_tool); if (inputvol) { virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, inputPath, vol->target.path, NULL); - if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); + } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } @@ -811,8 +854,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, case QEMU_IMG_BACKING_FORMAT_OPTIONS: virCommandAddArg(cmd, "-o"); - virCommandAddArgFormat(cmd, "backing_fmt=%s%s", backingType, - do_encryption ? ",encryption=on" : ""); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); virCommandAddArg(cmd, vol->target.path); virCommandAddArgFormat(cmd, "%lluK", size_arg); break; @@ -831,10 +873,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, vol->target.path, NULL); virCommandAddArgFormat(cmd, "%lluK", size_arg); - if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); + } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } -- 1.7.10

On Sat, May 05, 2012 at 02:46:32AM +0200, Marc-André Lureau wrote:
+ if (vol->target.format != VIR_STORAGE_FILE_QCOW2 && with_preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("Preallocation is only available with qcow2")); + return -1; + }
/volume/allocation says in its documentation "If set to a value smaller than the capacity, the pool has the option of deciding to sparsely allocate a volume. It does not have to honour requests for sparse allocation though.", ie when trying to use "allocation" to get a sparsely allocated volume, failures to do the sparse allocation are not fatal (if the documentation is to be trusted). I think it would be nicer to be consistent with that for preallocation and not return an error either in this case. Christophe
+ if (vol->backingStore.path) { int accessRetCode = -1; char *absolutePath = NULL; @@ -781,16 +820,20 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, if (imgformat < 0) goto cleanup;
+ if (imgformat != QEMU_IMG_BACKING_FORMAT_OPTIONS && with_preallocation) + VIR_INFO("Preallocation not supported with this version of qemu-img"); + cmd = virCommandNew(create_tool);
if (inputvol) { virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, inputPath, vol->target.path, NULL);
- if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); + } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } @@ -811,8 +854,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
case QEMU_IMG_BACKING_FORMAT_OPTIONS: virCommandAddArg(cmd, "-o"); - virCommandAddArgFormat(cmd, "backing_fmt=%s%s", backingType, - do_encryption ? ",encryption=on" : ""); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); virCommandAddArg(cmd, vol->target.path); virCommandAddArgFormat(cmd, "%lluK", size_arg); break; @@ -831,10 +873,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, vol->target.path, NULL); virCommandAddArgFormat(cmd, "%lluK", size_arg);
- if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); + } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } -- 1.7.10
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Wed, May 9, 2012 at 12:55 PM, Christophe Fergeau <cfergeau@redhat.com> wrote:
). I think it would be nicer to be consistent with that for preallocation and not return an error either in this case.
I am not convinced this is the right thing to do. Perhaps sparse allocation, or not, does not make a big difference, but prealloc does. So silently ignoring the request is going to cause more trouble. If it's specified, I think it should be respected. -- Marc-André Lureau

On Wed, May 09, 2012 at 01:25:20PM +0200, Marc-André Lureau wrote:
On Wed, May 9, 2012 at 12:55 PM, Christophe Fergeau <cfergeau@redhat.com> wrote:
). I think it would be nicer to be consistent with that for preallocation and not return an error either in this case.
I am not convinced this is the right thing to do. Perhaps sparse allocation, or not, does not make a big difference, but prealloc does.
Big speed difference during win7 installations? or are you thinking of another big difference? sparse/non-sparse allocation can make a big difference on disk usage, which is a big diference as well imo. I agree with you that erroring out is better, but I tend to prefer consistency in cases like this. Christophe

Hi On Wed, May 9, 2012 at 1:33 PM, Christophe Fergeau <cfergeau@redhat.com> wrote:
Big speed difference during win7 installations? or are you thinking of another big difference? sparse/non-sparse allocation can make a big
I guess it's mostly speed up in any appending write IO (20G for win7..). Which occurs rather often, especially on new systems. Overall, the VM feels much faster, but that's my pov.
difference on disk usage, which is a big diference as well imo.
Indeed, but in case of sparse, the disk space failure is enough to guarantee that the image is created, whether it is sparse or not. So, from an image creation operation, it is equal, assuming there is no other difference than disk usage
I agree with you that erroring out is better, but I tend to prefer consistency in cases like this.
I don't think it's the same, in one case we are talking about resource usage, in the other case we are talking about VM tweak / io speed-up. -- Marc-André Lureau

On Sat, May 05, 2012 at 02:46:32AM +0200, Marc-André Lureau wrote:
Use preallocation mode specified in volume XML format when running qemu-img. --- src/storage/storage_backend.c | 63 ++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 10 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index caac2f8..ed3217d 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -645,6 +645,38 @@ cleanup: return ret; }
+static char * +virStorageQemuImgOptionsStr(virStorageVolDefPtr vol) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + bool do_encryption = (vol->target.encryption != NULL); + const char *backingType = vol->backingStore.path ? + virStorageFileFormatTypeToString(vol->backingStore.format) : NULL; + bool comma = false; + const char *preallocation = vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE ? + virStoragePreallocationModeTypeToString(vol->preallocation) : NULL; + + if (backingType) { + virBufferAddLit(&buf, "backing_fmt="); + virBufferAdd(&buf, backingType, -1); + comma = true; + } + + if (do_encryption) { + virBufferAdd(&buf, comma ? "," : "", -1); + virBufferAddLit(&buf, "encryption=on"); + comma = true; + } + + if (preallocation) { + virBufferAdd(&buf, comma ? "," : "", -1); + virBufferAddLit(&buf, "preallocation="); + virBufferAdd(&buf, preallocation, -1); + comma = true; + } + + return virBufferContentAndReset(&buf); +}
static int virStorageBackendCreateQemuImg(virConnectPtr conn, @@ -658,6 +690,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, int imgformat = -1; virCommandPtr cmd = NULL; bool do_encryption = (vol->target.encryption != NULL); + bool with_preallocation = (vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE); unsigned long long int size_arg;
virCheckFlags(0, -1); @@ -689,6 +722,12 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, return -1; }
+ if (vol->target.format != VIR_STORAGE_FILE_QCOW2 && with_preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR,
I'd use VIR_ERR_XML_ERROR or VIR_ERR_CONFIG_UNSUPPORTED here
+ _("Preallocation is only available with qcow2")); + return -1; + } + if (vol->backingStore.path) { int accessRetCode = -1; char *absolutePath = NULL; @@ -781,16 +820,20 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, if (imgformat < 0) goto cleanup;
+ if (imgformat != QEMU_IMG_BACKING_FORMAT_OPTIONS && with_preallocation) + VIR_INFO("Preallocation not supported with this version of qemu-img"); + cmd = virCommandNew(create_tool);
if (inputvol) { virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type, inputPath, vol->target.path, NULL);
- if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol));
The string returned by virStorageQemuImgOptionsStr is leaked here and in all subsequent uses. Patch looks good otherwise. Christophe
+ } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } @@ -811,8 +854,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
case QEMU_IMG_BACKING_FORMAT_OPTIONS: virCommandAddArg(cmd, "-o"); - virCommandAddArgFormat(cmd, "backing_fmt=%s%s", backingType, - do_encryption ? ",encryption=on" : ""); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); virCommandAddArg(cmd, vol->target.path); virCommandAddArgFormat(cmd, "%lluK", size_arg); break; @@ -831,10 +873,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, vol->target.path, NULL); virCommandAddArgFormat(cmd, "%lluK", size_arg);
- if (do_encryption) { - if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { - virCommandAddArgList(cmd, "-o", "encryption=on", NULL); - } else { + if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) { + virCommandAddArg(cmd, "-o"); + virCommandAddArg(cmd, virStorageQemuImgOptionsStr(vol)); + } else { + if (do_encryption) { virCommandAddArg(cmd, "-e"); } } -- 1.7.10
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Sat, May 05, 2012 at 02:46:31AM +0200, Marc-André Lureau wrote:
Allow to specify preallocation mode for QCOW2 images. If not specified or not available, it's ignored.
This change only modify the schema, doc, parsing and tests. --- docs/formatstorage.html.in | 6 ++++++ docs/schemas/storagevol.rng | 18 ++++++++++++++++++ src/conf/storage_conf.c | 26 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 1 + src/util/storage_file.c | 4 ++++ src/util/storage_file.h | 10 ++++++++++ tests/storagevolxml2xmlin/vol-qcow2.xml | 1 + tests/storagevolxml2xmlout/vol-qcow2.xml | 1 + 8 files changed, 67 insertions(+)
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..c4faadf 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -252,6 +252,12 @@ 1,152,921,504,606,846,976 bytes). <span class="since">Since 0.4.1, multi-character <code>unit</code> since 0.9.11</span></dd> + <dt><code>preallocation</code></dt> + <dd>An image with preallocated metadata is initially larger but + can improve performance when the image needs to grow. This is + supported by QCOW2 image format. + Attribe <code>mode</code> value can be 'off' or 'metadata'. + <span class="since">Since 0.9.13</span></dd> <dt><code>capacity</code></dt> <dd>Providing the logical capacity for the volume. This value is in bytes by default, but a <code>unit</code> attribute can be diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8edb877..d9a148e 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -40,6 +40,7 @@ <ref name='scaledInteger'/> </element> </optional> + <ref name='preallocation'/> </define>
<define name='permissions'> @@ -171,6 +172,23 @@ </optional> </define>
+ <define name='preallocationmode'> + <choice> + <value>off</value> + <value>metadata</value> + </choice> + </define> + + <define name='preallocation'> + <optional> + <element name='preallocation'> + <attribute name='mode'> + <ref name='preallocationmode'/> + </attribute> + </element> + </optional> + </define> + <define name='name'> <data type='string'> <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0b34f28..95849ec 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -991,6 +991,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + char *preallocation = NULL; xmlNodePtr node;
options = virStorageVolOptionsForPoolType(pool->type); @@ -1035,6 +1036,19 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->allocation = ret->capacity; }
+ preallocation = virXPathString("string(./preallocation/@mode)", ctxt); + if (preallocation) { + if ((ret->preallocation = virStoragePreallocationModeTypeFromString(preallocation)) < 0) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown preallocation mode %s"), preallocation); + goto cleanup; + } + + VIR_FREE(preallocation); + } else { + ret->preallocation = VIR_STORAGE_PREALLOCATION_NONE; + } + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); @@ -1244,6 +1258,18 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAsprintf(&buf," <allocation unit='bytes'>%llu</allocation>\n", def->allocation);
+ if (def->preallocation != VIR_STORAGE_PREALLOCATION_NONE) { + const char *preallocation; + + preallocation = virStoragePreallocationModeTypeToString(def->preallocation); + if (!preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected pool type"));
Shouldn't this be something like "unexpected preallocation mode"? The rest of the patch looks good to me. Christophe
+ goto cleanup; + } + virBufferAsprintf(&buf," <preallocation mode='%s'/>\n", preallocation); + } + if (virStorageVolTargetDefFormat(options, &buf, &def->target, "target") < 0) goto cleanup; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9222c4a..c7c7af0 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -98,6 +98,7 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; virStorageVolTarget backingStore; + int preallocation; /* virStoragePreallocationMode enum */ };
typedef struct _virStorageVolDefList virStorageVolDefList; diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 530071e..8d78d36 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -47,6 +47,10 @@ VIR_ENUM_IMPL(virStorageFileFormat, "cloop", "cow", "dmg", "iso", "qcow", "qcow2", "qed", "vmdk", "vpc")
+VIR_ENUM_IMPL(virStoragePreallocationMode, + VIR_STORAGE_PREALLOCATION_LAST, + "", "off", "metadata") + enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ diff --git a/src/util/storage_file.h b/src/util/storage_file.h index 13d0e87..dfc8719 100644 --- a/src/util/storage_file.h +++ b/src/util/storage_file.h @@ -46,6 +46,16 @@ enum virStorageFileFormat {
VIR_ENUM_DECL(virStorageFileFormat);
+enum virStoragePreallocationMode { + VIR_STORAGE_PREALLOCATION_NONE, + VIR_STORAGE_PREALLOCATION_OFF, + VIR_STORAGE_PREALLOCATION_METADATA, + + VIR_STORAGE_PREALLOCATION_LAST +}; + +VIR_ENUM_DECL(virStoragePreallocationMode); + typedef struct _virStorageFileMetadata { char *backingStore; int backingStoreFormat; diff --git a/tests/storagevolxml2xmlin/vol-qcow2.xml b/tests/storagevolxml2xmlin/vol-qcow2.xml index b4924de..b4c6522 100644 --- a/tests/storagevolxml2xmlin/vol-qcow2.xml +++ b/tests/storagevolxml2xmlin/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit="G">5</capacity> <allocation>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml index 4490931..311c52e 100644 --- a/tests/storagevolxml2xmlout/vol-qcow2.xml +++ b/tests/storagevolxml2xmlout/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit='bytes'>5368709120</capacity> <allocation unit='bytes'>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> -- 1.7.10
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

Allow to specify preallocation mode for QCOW2 images. If not specified or not available, it's ignored. This change only modify the schema, doc, parsing and tests. --- docs/formatstorage.html.in | 6 ++++++ docs/schemas/storagevol.rng | 18 ++++++++++++++++++ src/conf/storage_conf.c | 26 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 1 + src/util/storage_file.c | 4 ++++ src/util/storage_file.h | 10 ++++++++++ tests/storagevolxml2xmlin/vol-qcow2.xml | 1 + tests/storagevolxml2xmlout/vol-qcow2.xml | 1 + 8 files changed, 67 insertions(+) diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..c4faadf 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -252,6 +252,12 @@ 1,152,921,504,606,846,976 bytes). <span class="since">Since 0.4.1, multi-character <code>unit</code> since 0.9.11</span></dd> + <dt><code>preallocation</code></dt> + <dd>An image with preallocated metadata is initially larger but + can improve performance when the image needs to grow. This is + supported by QCOW2 image format. + Attribe <code>mode</code> value can be 'off' or 'metadata'. + <span class="since">Since 0.9.13</span></dd> <dt><code>capacity</code></dt> <dd>Providing the logical capacity for the volume. This value is in bytes by default, but a <code>unit</code> attribute can be diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8edb877..d9a148e 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -40,6 +40,7 @@ <ref name='scaledInteger'/> </element> </optional> + <ref name='preallocation'/> </define> <define name='permissions'> @@ -171,6 +172,23 @@ </optional> </define> + <define name='preallocationmode'> + <choice> + <value>off</value> + <value>metadata</value> + </choice> + </define> + + <define name='preallocation'> + <optional> + <element name='preallocation'> + <attribute name='mode'> + <ref name='preallocationmode'/> + </attribute> + </element> + </optional> + </define> + <define name='name'> <data type='string'> <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0b34f28..446cc9d 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -991,6 +991,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + char *preallocation = NULL; xmlNodePtr node; options = virStorageVolOptionsForPoolType(pool->type); @@ -1035,6 +1036,19 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->allocation = ret->capacity; } + preallocation = virXPathString("string(./preallocation/@mode)", ctxt); + if (preallocation) { + if ((ret->preallocation = virStoragePreallocationModeTypeFromString(preallocation)) < 0) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown preallocation mode %s"), preallocation); + goto cleanup; + } + + VIR_FREE(preallocation); + } else { + ret->preallocation = VIR_STORAGE_PREALLOCATION_NONE; + } + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); @@ -1244,6 +1258,18 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAsprintf(&buf," <allocation unit='bytes'>%llu</allocation>\n", def->allocation); + if (def->preallocation != VIR_STORAGE_PREALLOCATION_NONE) { + const char *preallocation; + + preallocation = virStoragePreallocationModeTypeToString(def->preallocation); + if (!preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected preallocation mode")); + goto cleanup; + } + virBufferAsprintf(&buf," <preallocation mode='%s'/>\n", preallocation); + } + if (virStorageVolTargetDefFormat(options, &buf, &def->target, "target") < 0) goto cleanup; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9222c4a..c7c7af0 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -98,6 +98,7 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; virStorageVolTarget backingStore; + int preallocation; /* virStoragePreallocationMode enum */ }; typedef struct _virStorageVolDefList virStorageVolDefList; diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 530071e..8d78d36 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -47,6 +47,10 @@ VIR_ENUM_IMPL(virStorageFileFormat, "cloop", "cow", "dmg", "iso", "qcow", "qcow2", "qed", "vmdk", "vpc") +VIR_ENUM_IMPL(virStoragePreallocationMode, + VIR_STORAGE_PREALLOCATION_LAST, + "", "off", "metadata") + enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ diff --git a/src/util/storage_file.h b/src/util/storage_file.h index 13d0e87..dfc8719 100644 --- a/src/util/storage_file.h +++ b/src/util/storage_file.h @@ -46,6 +46,16 @@ enum virStorageFileFormat { VIR_ENUM_DECL(virStorageFileFormat); +enum virStoragePreallocationMode { + VIR_STORAGE_PREALLOCATION_NONE, + VIR_STORAGE_PREALLOCATION_OFF, + VIR_STORAGE_PREALLOCATION_METADATA, + + VIR_STORAGE_PREALLOCATION_LAST +}; + +VIR_ENUM_DECL(virStoragePreallocationMode); + typedef struct _virStorageFileMetadata { char *backingStore; int backingStoreFormat; diff --git a/tests/storagevolxml2xmlin/vol-qcow2.xml b/tests/storagevolxml2xmlin/vol-qcow2.xml index b4924de..b4c6522 100644 --- a/tests/storagevolxml2xmlin/vol-qcow2.xml +++ b/tests/storagevolxml2xmlin/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit="G">5</capacity> <allocation>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml index 4490931..311c52e 100644 --- a/tests/storagevolxml2xmlout/vol-qcow2.xml +++ b/tests/storagevolxml2xmlout/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit='bytes'>5368709120</capacity> <allocation unit='bytes'>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> -- 1.7.10.1

On Wed, May 09, 2012 at 02:01:14PM +0200, Marc-André Lureau wrote:
Allow to specify preallocation mode for QCOW2 images. If not specified or not available, it's ignored.
This change only modify the schema, doc, parsing and tests. --- docs/formatstorage.html.in | 6 ++++++ docs/schemas/storagevol.rng | 18 ++++++++++++++++++ src/conf/storage_conf.c | 26 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 1 + src/util/storage_file.c | 4 ++++ src/util/storage_file.h | 10 ++++++++++ tests/storagevolxml2xmlin/vol-qcow2.xml | 1 + tests/storagevolxml2xmlout/vol-qcow2.xml | 1 + 8 files changed, 67 insertions(+)
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..c4faadf 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -252,6 +252,12 @@ 1,152,921,504,606,846,976 bytes). <span class="since">Since 0.4.1, multi-character <code>unit</code> since 0.9.11</span></dd> + <dt><code>preallocation</code></dt> + <dd>An image with preallocated metadata is initially larger but + can improve performance when the image needs to grow. This is + supported by QCOW2 image format. + Attribe <code>mode</code> value can be 'off' or 'metadata'. + <span class="since">Since 0.9.13</span></dd> <dt><code>capacity</code></dt> <dd>Providing the logical capacity for the volume. This value is in bytes by default, but a <code>unit</code> attribute can be diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8edb877..d9a148e 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -40,6 +40,7 @@ <ref name='scaledInteger'/> </element> </optional> + <ref name='preallocation'/> </define>
<define name='permissions'> @@ -171,6 +172,23 @@ </optional> </define>
+ <define name='preallocationmode'> + <choice> + <value>off</value> + <value>metadata</value> + </choice> + </define> + + <define name='preallocation'> + <optional> + <element name='preallocation'> + <attribute name='mode'> + <ref name='preallocationmode'/> + </attribute> + </element> + </optional> + </define> + <define name='name'> <data type='string'> <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0b34f28..446cc9d 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -991,6 +991,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + char *preallocation = NULL; xmlNodePtr node;
options = virStorageVolOptionsForPoolType(pool->type); @@ -1035,6 +1036,19 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->allocation = ret->capacity; }
+ preallocation = virXPathString("string(./preallocation/@mode)", ctxt); + if (preallocation) { + if ((ret->preallocation = virStoragePreallocationModeTypeFromString(preallocation)) < 0) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR,
This error should be VIR_ERR_XML_ERROR Apologies for the several mails with comments about the same patch :-/ Christophe
+ _("unknown preallocation mode %s"), preallocation); + goto cleanup; + } + + VIR_FREE(preallocation); + } else { + ret->preallocation = VIR_STORAGE_PREALLOCATION_NONE; + } + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); @@ -1244,6 +1258,18 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAsprintf(&buf," <allocation unit='bytes'>%llu</allocation>\n", def->allocation);
+ if (def->preallocation != VIR_STORAGE_PREALLOCATION_NONE) { + const char *preallocation; + + preallocation = virStoragePreallocationModeTypeToString(def->preallocation); + if (!preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected preallocation mode")); + goto cleanup; + } + virBufferAsprintf(&buf," <preallocation mode='%s'/>\n", preallocation); + } + if (virStorageVolTargetDefFormat(options, &buf, &def->target, "target") < 0) goto cleanup; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9222c4a..c7c7af0 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -98,6 +98,7 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; virStorageVolTarget backingStore; + int preallocation; /* virStoragePreallocationMode enum */ };
typedef struct _virStorageVolDefList virStorageVolDefList; diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 530071e..8d78d36 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -47,6 +47,10 @@ VIR_ENUM_IMPL(virStorageFileFormat, "cloop", "cow", "dmg", "iso", "qcow", "qcow2", "qed", "vmdk", "vpc")
+VIR_ENUM_IMPL(virStoragePreallocationMode, + VIR_STORAGE_PREALLOCATION_LAST, + "", "off", "metadata") + enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ diff --git a/src/util/storage_file.h b/src/util/storage_file.h index 13d0e87..dfc8719 100644 --- a/src/util/storage_file.h +++ b/src/util/storage_file.h @@ -46,6 +46,16 @@ enum virStorageFileFormat {
VIR_ENUM_DECL(virStorageFileFormat);
+enum virStoragePreallocationMode { + VIR_STORAGE_PREALLOCATION_NONE, + VIR_STORAGE_PREALLOCATION_OFF, + VIR_STORAGE_PREALLOCATION_METADATA, + + VIR_STORAGE_PREALLOCATION_LAST +}; + +VIR_ENUM_DECL(virStoragePreallocationMode); + typedef struct _virStorageFileMetadata { char *backingStore; int backingStoreFormat; diff --git a/tests/storagevolxml2xmlin/vol-qcow2.xml b/tests/storagevolxml2xmlin/vol-qcow2.xml index b4924de..b4c6522 100644 --- a/tests/storagevolxml2xmlin/vol-qcow2.xml +++ b/tests/storagevolxml2xmlin/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit="G">5</capacity> <allocation>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml index 4490931..311c52e 100644 --- a/tests/storagevolxml2xmlout/vol-qcow2.xml +++ b/tests/storagevolxml2xmlout/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit='bytes'>5368709120</capacity> <allocation unit='bytes'>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> -- 1.7.10.1
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Sat, May 05, 2012 at 02:46:31AM +0200, Marc-André Lureau wrote:
Allow to specify preallocation mode for QCOW2 images. If not specified or not available, it's ignored.
This change only modify the schema, doc, parsing and tests. --- docs/formatstorage.html.in | 6 ++++++ docs/schemas/storagevol.rng | 18 ++++++++++++++++++ src/conf/storage_conf.c | 26 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 1 + src/util/storage_file.c | 4 ++++ src/util/storage_file.h | 10 ++++++++++ tests/storagevolxml2xmlin/vol-qcow2.xml | 1 + tests/storagevolxml2xmlout/vol-qcow2.xml | 1 + 8 files changed, 67 insertions(+)
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index d0e4319..c4faadf 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -252,6 +252,12 @@ 1,152,921,504,606,846,976 bytes). <span class="since">Since 0.4.1, multi-character <code>unit</code> since 0.9.11</span></dd> + <dt><code>preallocation</code></dt> + <dd>An image with preallocated metadata is initially larger but + can improve performance when the image needs to grow. This is + supported by QCOW2 image format.
by _the_ QCOW2 image format? (needs confirmation from a native speaker I think)
+ Attribe <code>mode</code> value can be 'off' or 'metadata'.
Attribute
+ <span class="since">Since 0.9.13</span></dd>
I was about to say this should wait until 0.9.13, good that we agree ;)
<dt><code>capacity</code></dt> <dd>Providing the logical capacity for the volume. This value is in bytes by default, but a <code>unit</code> attribute can be diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8edb877..d9a148e 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -40,6 +40,7 @@ <ref name='scaledInteger'/> </element> </optional> + <ref name='preallocation'/>
This is a nit, but it seems to usually be written <optional><ref name='preallocation'/></optional> rather than having the 'optional' tag down the ref definition.
</define>
<define name='permissions'> @@ -171,6 +172,23 @@ </optional> </define>
+ <define name='preallocationmode'> + <choice> + <value>off</value> + <value>metadata</value> + </choice> + </define> + + <define name='preallocation'> + <optional> + <element name='preallocation'> + <attribute name='mode'> + <ref name='preallocationmode'/> + </attribute> + </element> + </optional> + </define> + <define name='name'> <data type='string'> <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param> diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 0b34f28..95849ec 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -991,6 +991,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + char *preallocation = NULL; xmlNodePtr node;
options = virStorageVolOptionsForPoolType(pool->type); @@ -1035,6 +1036,19 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool, ret->allocation = ret->capacity; }
+ preallocation = virXPathString("string(./preallocation/@mode)", ctxt); + if (preallocation) { + if ((ret->preallocation = virStoragePreallocationModeTypeFromString(preallocation)) < 0) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown preallocation mode %s"), preallocation);
preallocation is leaked in this codepath
+ goto cleanup; + } + + VIR_FREE(preallocation); + } else { + ret->preallocation = VIR_STORAGE_PREALLOCATION_NONE; + } + ret->target.path = virXPathString("string(./target/path)", ctxt); if (options->formatFromString) { char *format = virXPathString("string(./target/format/@type)", ctxt); @@ -1244,6 +1258,18 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAsprintf(&buf," <allocation unit='bytes'>%llu</allocation>\n", def->allocation);
+ if (def->preallocation != VIR_STORAGE_PREALLOCATION_NONE) { + const char *preallocation; + + preallocation = virStoragePreallocationModeTypeToString(def->preallocation); + if (!preallocation) { + virStorageReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected pool type")); + goto cleanup; + } + virBufferAsprintf(&buf," <preallocation mode='%s'/>\n", preallocation); + } + if (virStorageVolTargetDefFormat(options, &buf, &def->target, "target") < 0) goto cleanup; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 9222c4a..c7c7af0 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -98,6 +98,7 @@ struct _virStorageVolDef { virStorageVolSource source; virStorageVolTarget target; virStorageVolTarget backingStore; + int preallocation; /* virStoragePreallocationMode enum */ };
typedef struct _virStorageVolDefList virStorageVolDefList; diff --git a/src/util/storage_file.c b/src/util/storage_file.c index 530071e..8d78d36 100644 --- a/src/util/storage_file.c +++ b/src/util/storage_file.c @@ -47,6 +47,10 @@ VIR_ENUM_IMPL(virStorageFileFormat, "cloop", "cow", "dmg", "iso", "qcow", "qcow2", "qed", "vmdk", "vpc")
+VIR_ENUM_IMPL(virStoragePreallocationMode, + VIR_STORAGE_PREALLOCATION_LAST, + "", "off", "metadata")
first member could be "none" instead of "" "default" would be a better name for the default state the default behaviour change some day. Christophe
+ enum lv_endian { LV_LITTLE_ENDIAN = 1, /* 1234 */ LV_BIG_ENDIAN /* 4321 */ diff --git a/src/util/storage_file.h b/src/util/storage_file.h index 13d0e87..dfc8719 100644 --- a/src/util/storage_file.h +++ b/src/util/storage_file.h @@ -46,6 +46,16 @@ enum virStorageFileFormat {
VIR_ENUM_DECL(virStorageFileFormat);
+enum virStoragePreallocationMode { + VIR_STORAGE_PREALLOCATION_NONE, + VIR_STORAGE_PREALLOCATION_OFF, + VIR_STORAGE_PREALLOCATION_METADATA, + + VIR_STORAGE_PREALLOCATION_LAST +}; + +VIR_ENUM_DECL(virStoragePreallocationMode); + typedef struct _virStorageFileMetadata { char *backingStore; int backingStoreFormat; diff --git a/tests/storagevolxml2xmlin/vol-qcow2.xml b/tests/storagevolxml2xmlin/vol-qcow2.xml index b4924de..b4c6522 100644 --- a/tests/storagevolxml2xmlin/vol-qcow2.xml +++ b/tests/storagevolxml2xmlin/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit="G">5</capacity> <allocation>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml index 4490931..311c52e 100644 --- a/tests/storagevolxml2xmlout/vol-qcow2.xml +++ b/tests/storagevolxml2xmlout/vol-qcow2.xml @@ -5,6 +5,7 @@ </source> <capacity unit='bytes'>5368709120</capacity> <allocation unit='bytes'>294912</allocation> + <preallocation mode='metadata'/> <target> <path>/var/lib/libvirt/images/OtherDemo.img</path> <format type='qcow2'/> -- 1.7.10
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
participants (2)
-
Christophe Fergeau
-
Marc-André Lureau