* src/conf/domain_conf.h: Introduce one new struct for representing
NUMA tuning related stuffs.
* src/conf/domain_conf.c: Parse and format numatune XML.
---
src/conf/domain_conf.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 22 ++++++++++++++
src/libvirt_private.syms | 2 +
3 files changed, 96 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 02707dd..8d5e173 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -484,6 +484,11 @@ VIR_ENUM_IMPL(virDomainTimerMode, VIR_DOMAIN_TIMER_MODE_LAST,
"paravirt",
"smpsafe");
+VIR_ENUM_IMPL(virDomainNumatuneMemMode, VIR_DOMAIN_NUMATUNE_MEM_LAST,
+ "strict",
+ "preferred",
+ "interleave");
+
#define virDomainReportError(code, ...) \
virReportErrorHelper(VIR_FROM_DOMAIN, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
@@ -5875,6 +5880,51 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
VIR_FREE(nodes);
+ /* Extract numatune if exists. */
+ if ((n = virXPathNodeSet("./numatune", ctxt, NULL)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot extract numatune
nodes"));
+ goto error;
+ }
+
+ if (n) {
+ tmp = virXPathString("string(./numatune/memory/@nodeset)", ctxt);
+ if (tmp) {
+ char *set = tmp;
+ int nodemasklen = VIR_DOMAIN_CPUMASK_LEN;
+
+ if (VIR_ALLOC_N(def->numatune.memory.nodemask, nodemasklen) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ /* "nodeset" leads same syntax with "cpuset". */
+ if (virDomainCpuSetParse((const char **)&set,
+ 0, def->numatune.memory.nodemask,
+ nodemasklen) < 0)
+ goto error;
+ VIR_FREE(tmp);
+ } else {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("nodeset for NUMA memory tuning
must be set"));
+ goto error;
+ }
+
+ tmp = virXPathString("string(./numatune/memory/@mode)", ctxt);
+ if (tmp) {
+ if ((def->numatune.memory.mode =
+ virDomainNumatuneMemModeTypeFromString(tmp)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unsupported NUMA memory tuning mode
'%s'"),
+ tmp);
+ goto error;
+ }
+ VIR_FREE(tmp);
+ } else {
+ def->numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT;
+ }
+ }
+
n = virXPathNodeSet("./features/*", ctxt, &nodes);
if (n < 0)
goto error;
@@ -9457,6 +9507,28 @@ char *virDomainDefFormat(virDomainDefPtr def,
if (def->cputune.shares || def->cputune.vcpupin)
virBufferAddLit(&buf, " </cputune>\n");
+ if (def->numatune.memory.nodemask)
+ virBufferAddLit(&buf, " <numatune>\n");
+
+ if (def->numatune.memory.nodemask) {
+ char *nodemask = NULL;
+ nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
+ VIR_DOMAIN_CPUMASK_LEN);
+ if (nodemask == NULL) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("failed to format nodeset for
NUMA memory tuning"));
+ goto cleanup;
+ }
+
+ virBufferAsprintf(&buf, " <memory mode='%s'
nodeset='%s'/>\n",
+
virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode),
+ nodemask);
+ VIR_FREE(nodemask);
+ }
+
+ if (def->numatune.memory.nodemask)
+ virBufferAddLit(&buf, " </numatune>\n");
+
if (def->sysinfo)
virDomainSysinfoDefFormat(&buf, def->sysinfo);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1f4bf1d..3c54e8b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1117,6 +1117,25 @@ virDomainVcpupinDefPtr
virDomainVcpupinFindByVcpu(virDomainVcpupinDefPtr *def,
int nvcpupin,
int vcpu);
+enum virDomainNumatuneMemMode {
+ VIR_DOMAIN_NUMATUNE_MEM_STRICT,
+ VIR_DOMAIN_NUMATUNE_MEM_PREFERRED,
+ VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE,
+
+ VIR_DOMAIN_NUMATUNE_MEM_LAST
+};
+
+typedef struct _virDomainNumatuneDef virDomainNumatuneDef;
+typedef virDomainNumatuneDef *virDomainNumatuneDefPtr;
+struct _virDomainNumatuneDef {
+ struct {
+ char *nodemask;
+ int mode;
+ } memory;
+
+ /* Future NUMA tuning related stuff should go here. */
+};
+
/*
* Guest VM main configuration
*
@@ -1156,6 +1175,8 @@ struct _virDomainDef {
virDomainVcpupinDefPtr *vcpupin;
} cputune;
+ virDomainNumatuneDef numatune;
+
/* These 3 are based on virDomainLifeCycleAction enum flags */
int onReboot;
int onPoweroff;
@@ -1564,6 +1585,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceZlibCompression)
VIR_ENUM_DECL(virDomainGraphicsSpicePlaybackCompression)
VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceClipboardCopypaste)
+VIR_ENUM_DECL(virDomainNumatuneMemMode)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
VIR_ENUM_DECL(virDomainNostateReason)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5202da3..ae18c0d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -310,6 +310,8 @@ virDomainNetIndexByMac;
virDomainNetInsert;
virDomainNetRemoveByMac;
virDomainNetTypeToString;
+virDomainNumatuneMemModeTypeFromString;
+virDomainNumatuneMemModeTypeToString;
virDomainObjAssignDef;
virDomainObjCopyPersistentDef;
virDomainObjGetPersistentDef;
--
1.7.4