Adjust the config code so that it does not enforce that target memory
node is specified. To avoid breakage, adjust the qemu memory hotplug
config checker to disallow such config for now.
---
docs/formatdomain.html.in | 5 +++--
docs/schemas/domaincommon.rng | 8 +++++---
src/conf/domain_conf.c | 16 +++++++++++-----
src/conf/domain_conf.h | 2 +-
src/qemu/qemu_domain.c | 7 +++++++
5 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c88b032..e5e0167 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -6300,8 +6300,9 @@ qemu-kvm -net nic,model=? /dev/null
added memory as a scaled integer.
</p>
<p>
- The mandatory <code>node</code> subelement configures the guest
NUMA
- node to attach the memory to.
+ The <code>node</code> subelement configures the guest NUMA node to
+ attach the memory to. The element shall be used only if the guest has
+ NUMA nodes configured.
</p>
</dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f196177..994face 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4532,9 +4532,11 @@
<element name="size">
<ref name="scaledInteger"/>
</element>
- <element name="node">
- <ref name="unsignedInt"/>
- </element>
+ <optional>
+ <element name="node">
+ <ref name="unsignedInt"/>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2edf123..52b76fb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12544,10 +12544,15 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node,
int ret = -1;
xmlNodePtr save = ctxt->node;
ctxt->node = node;
+ int rv;
- if (virXPathUInt("string(./node)", ctxt, &def->targetNode) < 0)
{
+ /* initialize to value which marks that the user didn't specify it */
+ def->targetNode = -1;
+
+ if ((rv = virXPathInt("string(./node)", ctxt, &def->targetNode)) ==
-2 ||
+ (rv == 0 && def->targetNode < 0)) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("invalid or missing value of memory device node"));
+ _("invalid value of memory device node"));
goto cleanup;
}
@@ -17700,8 +17705,8 @@ virDomainMemoryDefCheckABIStability(virDomainMemoryDefPtr src,
if (src->targetNode != dst->targetNode) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Target memory device targetNode '%u' "
- "doesn't match source targetNode '%u'"),
+ _("Target memory device targetNode '%d' "
+ "doesn't match source targetNode '%d'"),
dst->targetNode, src->targetNode);
return false;
}
@@ -20791,7 +20796,8 @@ virDomainMemoryTargetDefFormat(virBufferPtr buf,
virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "<size
unit='KiB'>%llu</size>\n", def->size);
- virBufferAsprintf(buf, "<node>%u</node>\n",
def->targetNode);
+ if (def->targetNode >= 0)
+ virBufferAsprintf(buf, "<node>%d</node>\n",
def->targetNode);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</target>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f10b534..8d43ee6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2022,7 +2022,7 @@ struct _virDomainMemoryDef {
/* target */
int model; /* virDomainMemoryModel */
- unsigned int targetNode;
+ int targetNode;
unsigned long long size; /* kibibytes */
virDomainDeviceInfo info;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e17c57d..69ddeb4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3591,6 +3591,13 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef
*mem,
return -1;
}
+ if (mem->targetNode == -1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("target NUMA node needs to be specified for "
+ "memory device"));
+ return -1;
+ }
+
if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
if (mem->info.addr.dimm.slot >= def->mem.memory_slots) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
--
2.6.2