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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list