
On 29.09.2016 10:56, Jaroslav Safka wrote:
This first change introduces xml parsing support for preallocated shared file descriptor based memory backing. It allows vhost-user to be used without hugepages.
New xml elements: <memoryBacking> <source type='file|anonymous' path='/path/to/qemu/' /> <access Mode='shared|private'/> <allocation mode='immediate|ondemand'/> </memoryBacking>
Okay, this is definitely interesting approach (not only because while reviewing this, I've found an old branch in my git where I've started to work on this). Frankly, I don't know if this is a good API or not. Historically, we required Dan's ACK on XML schema :-) btw: s/Mode/mode/ ;-)
--- docs/schemas/domaincommon.rng | 37 +++++ src/conf/domain_conf.c | 149 ++++++++++++++++----- src/conf/domain_conf.h | 34 +++++ .../qemuxml2argv-memorybacking-set.xml | 32 +++++ .../qemuxml2argv-memorybacking-unset.xml | 32 +++++ .../qemuxml2xmlout-memorybacking-set.xml | 40 ++++++ .../qemuxml2xmlout-memorybacking-unset.xml | 40 ++++++ tests/qemuxml2xmltest.c | 3 + 8 files changed, 334 insertions(+), 33 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-set.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-memorybacking-unset.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-set.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-memorybacking-unset.xml
You need to update the docs too. formatdomain.html.in to be more precise.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a06da46..7f73569 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c
@@ -16179,48 +16194,101 @@ virDomainDefParseXML(xmlDocPtr xml, } VIR_FREE(tmp);
- if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot extract hugepages nodes")); - goto error; + tmp = virXPathString("string(./memoryBacking/source/@type)", ctxt); + if (tmp) { + if ((def->mem.source = virDomainMemorySourceTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/source/type '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { + tmp = virXPathString("string(./memoryBacking/source/@path)", ctxt); + if (!tmp && VIR_STRDUP(tmp, VIR_DOMAIN_MEMORY_DEFAULT_PATH) < 0) + goto error; + + def->mem.mem_path = tmp; + tmp = NULL; + } }
- if (n) { - if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) + tmp = virXPathString("string(./memoryBacking/access/@mode)", ctxt); + if (tmp) { + if ((def->mem.access = virDomainMemoryAccessTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/access/mode '%s'"), tmp); goto error; + } + VIR_FREE(tmp); + }
- for (i = 0; i < n; i++) { - if (virDomainHugepagesParseXML(nodes[i], ctxt, - &def->mem.hugepages[i]) < 0) + tmp = virXPathString("string(./memoryBacking/allocation/@mode)", ctxt); + if (tmp) { + if ((def->mem.allocation = virDomainMemoryAllocationTypeFromString(tmp)) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown memoryBacking/allocation/mode '%s'"), tmp); + goto error; + } + VIR_FREE(tmp); + } + + if (virXPathNode("./memoryBacking/hugepages", ctxt)) { + /* hugepages will be used */ + + if (def->mem.allocation == VIR_DOMAIN_MEMORY_ALLOCATION_ONDEMAND) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("hugepages are not allowed with memory allocation ondemand")); + goto error; + } + + if (def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_ANONYMOUS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("hugepages are not allowed with anonymous memory source")); + goto error; + } + + if ((n = virXPathNodeSet("./memoryBacking/hugepages/page", ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract hugepages nodes")); + goto error; + }
These types of checks would normally go to post parse callback.
+ + if (n) { + if (VIR_ALLOC_N(def->mem.hugepages, n) < 0) goto error; - def->mem.nhugepages++;
- for (j = 0; j < i; j++) { - if (def->mem.hugepages[i].nodemask && - def->mem.hugepages[j].nodemask && - virBitmapOverlaps(def->mem.hugepages[i].nodemask, - def->mem.hugepages[j].nodemask)) { - virReportError(VIR_ERR_XML_DETAIL, - _("nodeset attribute of hugepages " - "of sizes %llu and %llu intersect"), - def->mem.hugepages[i].size, - def->mem.hugepages[j].size); - goto error; - } else if (!def->mem.hugepages[i].nodemask && - !def->mem.hugepages[j].nodemask) { - virReportError(VIR_ERR_XML_DETAIL, - _("two master hugepages detected: " - "%llu and %llu"), - def->mem.hugepages[i].size, - def->mem.hugepages[j].size); + for (i = 0; i < n; i++) { + if (virDomainHugepagesParseXML(nodes[i], ctxt, + &def->mem.hugepages[i]) < 0) goto error; + def->mem.nhugepages++; + + for (j = 0; j < i; j++) { + if (def->mem.hugepages[i].nodemask && + def->mem.hugepages[j].nodemask && + virBitmapOverlaps(def->mem.hugepages[i].nodemask, + def->mem.hugepages[j].nodemask)) { + virReportError(VIR_ERR_XML_DETAIL, + _("nodeset attribute of hugepages " + "of sizes %llu and %llu intersect"), + def->mem.hugepages[i].size, + def->mem.hugepages[j].size); + goto error; + } else if (!def->mem.hugepages[i].nodemask && + !def->mem.hugepages[j].nodemask) { + virReportError(VIR_ERR_XML_DETAIL, + _("two master hugepages detected: " + "%llu and %llu"), + def->mem.hugepages[i].size, + def->mem.hugepages[j].size); + goto error; + } } } - }
- VIR_FREE(nodes); - } else { - if ((node = virXPathNode("./memoryBacking/hugepages", ctxt))) { + VIR_FREE(nodes); + } else { + /* no hugepage pages */ if (VIR_ALLOC(def->mem.hugepages) < 0) goto error;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d2065cf..f1290a3 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h
@@ -3073,6 +3104,9 @@ VIR_ENUM_DECL(virDomainTPMModel) VIR_ENUM_DECL(virDomainTPMBackend) VIR_ENUM_DECL(virDomainMemoryModel) VIR_ENUM_DECL(virDomainMemoryBackingModel) +VIR_ENUM_DECL(virDomainMemorySource) +VIR_ENUM_DECL(virDomainMemoryAccess) +VIR_ENUM_DECL(virDomainMemoryAllocation)
These macros declare vir*TypeFromString() and vir*TypeToString() functions. Because they are in the header file, we should update the libvirt_private.syms too (even though these functions are not used anywere else just yet). The rest of the code looks okay (even in 2/2). Michal