This patch adds a new xml element <hypervisorpin cpuset='1'>,
and also the parser functions, docs, and tests.
hypervisorpin means pinning hypervisor threads, and cpuset = '1'
means pinning all hypervisor threads to cpu 1.
Signed-off-by: Tang Chen <tangchen(a)cn.fujitsu.com>
---
docs/schemas/domaincommon.rng | 7 ++
src/conf/domain_conf.c | 97 ++++++++++++++++++++++-
src/conf/domain_conf.h | 1 +
tests/qemuxml2argvdata/qemuxml2argv-cputune.xml | 1 +
4 files changed, 103 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 3d205b0..f5cedeb 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -556,6 +556,13 @@
</attribute>
</element>
</zeroOrMore>
+ <optional>
+ <element name="hypervisorpin">
+ <attribute name="cpuset">
+ <ref name="cpuset"/>
+ </attribute>
+ </element>
+ </optional>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3fb90db..376c1b5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7819,6 +7819,51 @@ error:
goto cleanup;
}
+/* Parse the XML definition for hypervisorpin */
+static virDomainVcpuPinDefPtr
+virDomainHypervisorPinDefParseXML(const xmlNodePtr node)
+{
+ virDomainVcpuPinDefPtr def = NULL;
+ char *tmp = NULL;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ def->vcpuid = -1;
+
+ tmp = virXMLPropString(node, "cpuset");
+
+ if (tmp) {
+ char *set = tmp;
+ int cpumasklen = VIR_DOMAIN_CPUMASK_LEN;
+
+ if (VIR_ALLOC_N(def->cpumask, cpumasklen) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (virDomainCpuSetParse(set, 0, def->cpumask,
+ cpumasklen) < 0)
+ goto error;
+
+ VIR_FREE(tmp);
+ } else {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("missing cpuset for hypervisor
pin"));
+ goto error;
+ }
+
+cleanup:
+ return def;
+
+error:
+ VIR_FREE(tmp);
+ VIR_FREE(def);
+ goto cleanup;
+}
+
static int virDomainDefMaybeAddController(virDomainDefPtr def,
int type,
int idx)
@@ -8212,6 +8257,34 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
VIR_FREE(nodes);
+ if ((n = virXPathNodeSet("./cputune/hypervisorpin", ctxt, &nodes)) <
0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot extract hypervisorpin nodes"));
+ goto error;
+ }
+
+ if (n > 1) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one hypervisorpin is supported"));
+ VIR_FREE(nodes);
+ goto error;
+ }
+
+ if (n && VIR_ALLOC(def->cputune.hypervisorpin) < 0) {
+ goto no_memory;
+ }
+
+ if (n) {
+ virDomainVcpuPinDefPtr hypervisorpin = NULL;
+ hypervisorpin = virDomainHypervisorPinDefParseXML(nodes[0]);
+
+ if (!hypervisorpin)
+ goto error;
+
+ def->cputune.hypervisorpin = hypervisorpin;
+ }
+ VIR_FREE(nodes);
+
/* Extract numatune if exists. */
if ((n = virXPathNodeSet("./numatune", ctxt, &nodes)) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -9216,7 +9289,7 @@ no_memory:
virReportOOMError();
/* fallthrough */
- error:
+error:
VIR_FREE(tmp);
VIR_FREE(nodes);
virBitmapFree(bootMap);
@@ -12784,7 +12857,8 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAsprintf(buf, ">%u</vcpu>\n", def->maxvcpus);
if (def->cputune.shares || def->cputune.vcpupin ||
- def->cputune.period || def->cputune.quota)
+ def->cputune.period || def->cputune.quota ||
+ def->cputune.hypervisorpin)
virBufferAddLit(buf, " <cputune>\n");
if (def->cputune.shares)
@@ -12816,8 +12890,25 @@ virDomainDefFormatInternal(virDomainDefPtr def,
}
}
+ if (def->cputune.hypervisorpin) {
+ virBufferAsprintf(buf, " <hypervisorpin ");
+
+ char *cpumask = NULL;
+ cpumask = virDomainCpuSetFormat(def->cputune.hypervisorpin->cpumask,
+ VIR_DOMAIN_CPUMASK_LEN);
+ if (cpumask == NULL) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("failed to format cpuset for
hypervisor"));
+ goto cleanup;
+ }
+
+ virBufferAsprintf(buf, "cpuset='%s'/>\n", cpumask);
+ VIR_FREE(cpumask);
+ }
+
if (def->cputune.shares || def->cputune.vcpupin ||
- def->cputune.period || def->cputune.quota)
+ def->cputune.period || def->cputune.quota ||
+ def->cputune.hypervisorpin)
virBufferAddLit(buf, " </cputune>\n");
if (def->numatune.memory.nodemask ||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7d5d60b..3768b82 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1606,6 +1606,7 @@ struct _virDomainDef {
long long quota;
int nvcpupin;
virDomainVcpuPinDefPtr *vcpupin;
+ virDomainVcpuPinDefPtr hypervisorpin;
} cputune;
virDomainNumatuneDef numatune;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune.xml
b/tests/qemuxml2argvdata/qemuxml2argv-cputune.xml
index df3101d..b72af1b 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-cputune.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune.xml
@@ -10,6 +10,7 @@
<quota>-1</quota>
<vcpupin vcpu='0' cpuset='0'/>
<vcpupin vcpu='1' cpuset='1'/>
+ <hypervisorpin cpuset='1'/>
</cputune>
<os>
<type arch='i686' machine='pc'>hvm</type>
--
1.7.10.2