
On Mon, Jul 20, 2020 at 18:33:22 +0100, Daniel Berrange wrote:
The storage pool code now attempts to disable COW by default on btrfs, but management applications may wish to override this behaviour. Thus we introduce a concept of storage pool features:
<features> <cow state='yes|no'/> </features>
If the <cow> feature policy is set, it will be enforced. It will always return an hard error if COW cannot be explicitly set or unset.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- docs/formatstorage.html.in | 25 ++++++++++ docs/schemas/storagepool.rng | 30 ++++++++++++ src/conf/storage_conf.c | 49 ++++++++++++++++++++ src/conf/storage_conf.h | 8 ++++ src/storage/storage_util.c | 2 +- tests/storagepoolxml2xmlin/pool-dir-cow.xml | 10 ++++ tests/storagepoolxml2xmlout/pool-dir-cow.xml | 15 ++++++ tests/storagepoolxml2xmltest.c | 1 + 8 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 tests/storagepoolxml2xmlin/pool-dir-cow.xml create mode 100644 tests/storagepoolxml2xmlout/pool-dir-cow.xml
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 65d9b33049..4e63865b39 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) {
<= 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) + return; + + virBufferAddLit(buf, "<features>\n"); + virBufferAdjustIndent(buf, 2); + if (def->features.cow)
def->features.cow != VIR_TRISTATE_BOOL_ABSENT
+ virBufferAsprintf(buf, "<cow state='%s'/>\n", + virTristateBoolTypeToString(def->features.cow)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</features>\n"); +}