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..8fd2908 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 the QCOW2 image format.
+ Attribute <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..b54db13 100644
--- a/docs/schemas/storagevol.rng
+++ b/docs/schemas/storagevol.rng
@@ -40,6 +40,9 @@
<ref name='scaledInteger'/>
</element>
</optional>
+ <optional>
+ <ref name='preallocation'/>
+ </optional>
</define>
<define name='permissions'>
@@ -171,6 +174,21 @@
</optional>
</define>
+ <define name='preallocationmode'>
+ <choice>
+ <value>off</value>
+ <value>metadata</value>
+ </choice>
+ </define>
+
+ <define name='preallocation'>
+ <element name='preallocation'>
+ <attribute name='mode'>
+ <ref name='preallocationmode'/>
+ </attribute>
+ </element>
+ </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 188af6d..b775ad2 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -992,6 +992,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
char *allocation = NULL;
char *capacity = NULL;
char *unit = NULL;
+ char *preallocation = NULL;
xmlNodePtr node;
options = virStorageVolOptionsForPoolType(pool->type);
@@ -1036,6 +1037,18 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
ret->allocation = ret->capacity;
}
+ preallocation = virXPathString("string(./preallocation/@mode)", ctxt);
+ if (preallocation) {
+ if ((ret->preallocation =
virStoragePreallocationModeTypeFromString(preallocation)) < 0) {
+ virStorageReportError(VIR_ERR_XML_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);
@@ -1091,6 +1104,7 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
return ret;
cleanup:
+ VIR_FREE(preallocation);
VIR_FREE(allocation);
VIR_FREE(capacity);
VIR_FREE(unit);
@@ -1245,6 +1259,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..63abe65 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,
+ "default", "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