xml example:
<disk ...>
<cachetune writeback='on' direct='off' no_flush='on'/>
</disk>
Parameters semantics match corresponding qemu 'cache.*' parameters.
--
I wonder should we use flush or sync name instead of qemu no_flush?
---
docs/schemas/domaincommon.rng | 22 +++++++++++
src/conf/domain_conf.c | 90 +++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 7 ++++
3 files changed, 119 insertions(+)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 95c7882..17e4ac9 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1208,6 +1208,9 @@
<ref name="geometry"/>
</optional>
<optional>
+ <ref name="cachetune"/>
+ </optional>
+ <optional>
<ref name="diskBlockIo"/>
</optional>
<optional>
@@ -1597,6 +1600,25 @@
</optional>
</element>
</define>
+ <define name="cachetune">
+ <element name="cachetune">
+ <optional>
+ <attribute name="writeback">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="direct">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="no_flush">
+ <ref name="virOnOff"/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
<define name="geometry">
<element name="geometry">
<attribute name="cyls">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index dd34cec..092696c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7405,6 +7405,52 @@ virDomainDiskDefParseValidate(const virDomainDiskDef *def)
return 0;
}
+static int
+virDomainDiskCachetuneDefFormat(virBufferPtr buf,
+ virDomainDiskDefPtr def)
+{
+ const char *writeback = virTristateSwitchTypeToString(def->cachetune.writeback);
+ const char *direct = virTristateSwitchTypeToString(def->cachetune.direct);
+ const char *no_flush = virTristateSwitchTypeToString(def->cachetune.no_flush);
+
+ if (!writeback) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected disk cachetune writeback mode %d"),
+ def->cachetune.writeback);
+ return -1;
+ }
+
+ if (!direct) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected disk cachetune direct mode %d"),
+ def->cachetune.direct);
+ return -1;
+ }
+
+ if (!no_flush) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected disk cachetune no_flush mode %d"),
+ def->cachetune.no_flush);
+ return -1;
+ }
+
+ if (def->cachetune.writeback ||
+ def->cachetune.direct ||
+ def->cachetune.no_flush) {
+ virBufferAddLit(buf, "<cachetune");
+
+ if (def->cachetune.writeback)
+ virBufferAsprintf(buf, " writeback='%s'", writeback);
+ if (def->cachetune.direct)
+ virBufferAsprintf(buf, " direct='%s'", direct);
+ if (def->cachetune.no_flush)
+ virBufferAsprintf(buf, " no_flush='%s'", no_flush);
+
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ return 0;
+}
static int
virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
@@ -7521,6 +7567,45 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
return ret;
}
+static int
+virDomainDiskDefCachetuneParse(virDomainDiskDefPtr def,
+ xmlNodePtr cur,
+ xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED)
+{
+ char *tmp = NULL;
+ int ret = -1;
+
+ if ((tmp = virXMLPropString(cur, "writeback")) &&
+ (def->cachetune.writeback = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk cache writeback setting '%s'"),
tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ if ((tmp = virXMLPropString(cur, "direct")) &&
+ (def->cachetune.direct = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk cache direct setting '%s'"),
tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ if ((tmp = virXMLPropString(cur, "no_flush")) &&
+ (def->cachetune.no_flush = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk cache no_flush setting '%s'"),
tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(tmp);
+
+ return ret;
+}
#define VENDOR_LEN 8
#define PRODUCT_LEN 16
@@ -7738,6 +7823,9 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
}
} else if (xmlStrEqual(cur->name, BAD_CAST "boot")) {
/* boot is parsed as part of virDomainDeviceInfoParseXML */
+ } else if (xmlStrEqual(cur->name, BAD_CAST "cachetune")) {
+ if (virDomainDiskDefCachetuneParse(def, cur, ctxt) < 0)
+ goto error;
}
}
@@ -20182,6 +20270,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virDomainDiskGeometryDefFormat(buf, def);
virDomainDiskBlockIoDefFormat(buf, def);
+ if (virDomainDiskCachetuneDefFormat(buf, def) < 0)
+ return -1;
/* For now, mirroring is currently output-only: we only output it
* for live domains, therefore we ignore it on input except for
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ce90c27..2cc85e6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -597,6 +597,13 @@ struct _virDomainDiskDef {
char *vendor;
char *product;
int cachemode; /* enum virDomainDiskCache */
+
+ struct {
+ int writeback; /* enum virTristateSwitch */
+ int direct; /* enum virTristateSwitch */
+ int no_flush; /* enum virTristateSwitch */
+ } cachetune;
+
int error_policy; /* enum virDomainDiskErrorPolicy */
int rerror_policy; /* enum virDomainDiskErrorPolicy */
int iomode; /* enum virDomainDiskIo */
--
1.8.3.1