diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index 2a7604d136..7493714c5c 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -67,6 +67,31 @@ pool. Since 0.4.1 +

Features

+ +

+ Some pools support optional features: +

+ +
+...
+<features>
+  <cow state='no'>
+</features>
+...
+ +

+ Valid features are: +

+ +

Source elements

diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index ff0d3c836c..f5cf6769c8 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -37,6 +37,7 @@ + @@ -49,6 +50,7 @@ + @@ -64,6 +66,7 @@ + @@ -79,6 +82,7 @@ + @@ -91,6 +95,7 @@ + @@ -103,6 +108,7 @@ + @@ -117,6 +123,7 @@ + @@ -128,6 +135,7 @@ + @@ -140,6 +148,7 @@ + @@ -154,6 +163,7 @@ + @@ -169,6 +179,7 @@ + @@ -180,6 +191,7 @@ + @@ -191,6 +203,7 @@ + @@ -205,6 +218,7 @@ + @@ -277,6 +291,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 65d9b33049..fac5ff7b86 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -839,6 +839,33 @@ virStoragePoolDefRefreshFormat(virBufferPtr buf, } +static int +virStoragePoolDefParseFeatures(virStoragePoolDefPtr def, + xmlXPathContextPtr ctxt) +{ + g_autofree char *cow = virXPathString("string(./features/cow/@state)", ctxt); + + if (cow) { + int val; + if (def->type != VIR_STORAGE_POOL_FS && + def->type != VIR_STORAGE_POOL_DIR) { + virReportError(VIR_ERR_NO_SUPPORT, "%s", + _("cow feature may only be used for 'fs' and 'dir' pools")); + return -1; + } + if ((val = virTristateBoolTypeFromString(cow)) <= 0) { + virReportError(VIR_ERR_XML_ERROR, + _("invalid storage pool cow feature state '%s'"), + cow); + return -1; + } + def->features.cow = val; + } + + return 0; +} + + virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) { @@ -910,6 +937,9 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) } } + if (virStoragePoolDefParseFeatures(def, ctxt) < 0) + return NULL; + if (options->flags & VIR_STORAGE_POOL_SOURCE_HOST) { if (!def->source.nhost) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -1131,6 +1161,23 @@ virStoragePoolSourceFormat(virBufferPtr buf, } +static void +virStoragePoolDefFormatFeatures(virBufferPtr buf, + virStoragePoolDefPtr def) +{ + if (def->features.cow == VIR_TRISTATE_BOOL_ABSENT) + return; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + if (def->features.cow != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, "\n", + virTristateBoolTypeToString(def->features.cow)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + + static int virStoragePoolDefFormatBuf(virBufferPtr buf, virStoragePoolDefPtr def) @@ -1166,6 +1213,8 @@ virStoragePoolDefFormatBuf(virBufferPtr buf, virBufferAsprintf(buf, "%llu\n", def->available); + virStoragePoolDefFormatFeatures(buf, def); + if (virStoragePoolSourceFormat(buf, options, &def->source) < 0) return -1; diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index daa21a127b..ffd406e093 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -180,6 +180,13 @@ struct _virStoragePoolSourceDevice { } geometry; }; +typedef struct _virStoragePoolFeatures virStoragePoolFeatures; +typedef virStoragePoolFeatures *virStoragePoolFeaturesPtr; +struct _virStoragePoolFeatures { + virTristateBool cow; +}; + + typedef struct _virStoragePoolSource virStoragePoolSource; typedef virStoragePoolSource *virStoragePoolSourcePtr; struct _virStoragePoolSource { @@ -256,6 +263,7 @@ struct _virStoragePoolDef { unsigned long long capacity; /* bytes */ unsigned long long available; /* bytes */ + virStoragePoolFeatures features; virStoragePoolSource source; virStoragePoolTarget target; diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 80b49bd1cf..f7c09e3375 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -2755,7 +2755,7 @@ virStorageBackendBuildLocal(virStoragePoolObjPtr pool) return -1; if (virFileSetCOW(def->target.path, - VIR_TRISTATE_BOOL_ABSENT) < 0) + def->features.cow) < 0) return -1; return 0; diff --git a/tests/storagepoolxml2xmlin/pool-dir-cow.xml b/tests/storagepoolxml2xmlin/pool-dir-cow.xml new file mode 100644 index 0000000000..2217f2b8e3 --- /dev/null +++ b/tests/storagepoolxml2xmlin/pool-dir-cow.xml @@ -0,0 +1,10 @@ + + vms + 751f8e7e-d2e9-463d-8ffe-d38f5e13a19b + + + + + /i/cant/believe/its/not/btrfs + + diff --git a/tests/storagepoolxml2xmlout/pool-dir-cow.xml b/tests/storagepoolxml2xmlout/pool-dir-cow.xml new file mode 100644 index 0000000000..2f3fe1f909 --- /dev/null +++ b/tests/storagepoolxml2xmlout/pool-dir-cow.xml @@ -0,0 +1,15 @@ + + vms + 751f8e7e-d2e9-463d-8ffe-d38f5e13a19b + 0 + 0 + 0 + + + + + + + /i/cant/believe/its/not/btrfs + + diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c index 382a7c659f..f21f20357a 100644 --- a/tests/storagepoolxml2xmltest.c +++ b/tests/storagepoolxml2xmltest.c @@ -62,6 +62,7 @@ mymain(void) DO_TEST("pool-dir"); DO_TEST("pool-dir-naming"); + DO_TEST("pool-dir-cow"); DO_TEST("pool-fs"); DO_TEST("pool-logical"); DO_TEST("pool-logical-nopath");