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(a)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");
+}