diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c88b032c2b..e5e0167262 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.
- The mandatory node
subelement configures the guest NUMA
- node to attach the memory to.
+ The node
subelement configures the guest NUMA node to
+ attach the memory to. The element shall be used only if the guest has
+ NUMA nodes configured.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f1961773c8..994faceec7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4532,9 +4532,11 @@
-
-
-
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index eb0044449a..0ac7dbf249 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;
}
@@ -17711,8 +17716,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;
}
@@ -20802,7 +20807,8 @@ virDomainMemoryTargetDefFormat(virBufferPtr buf,
virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "%llu\n", def->size);
- virBufferAsprintf(buf, "%u\n", def->targetNode);
+ if (def->targetNode >= 0)
+ virBufferAsprintf(buf, "%d\n", def->targetNode);
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f10b5348b7..8d43ee65d8 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 507d44695f..52488ab08d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3597,6 +3597,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,