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@xxxxxxxxxx> > --- > 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"); > +}