diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 27465bb6189780ccfc96b296eefc11fdc8f3fe04..eb203670d3cce08e9f9ad14b14dddf435bc697b6 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1030,8 +1030,8 @@
<cpu>
...
<numa>
- <cell cpus='0-3' memory='512000'/>
- <cell cpus='4-7' memory='512000'/>
+ <cell id='0' cpus='0-3' memory='512000'/>
+ <cell id='1' cpus='4-7' memory='512000'/>
</numa>
...
</cpu>
@@ -1039,10 +1039,15 @@
Each cell
element specifies a NUMA cell or a NUMA node.
- cpus
specifies the CPU or range of CPUs that are part of
- the node. memory
specifies the node memory in kibibytes
- (i.e. blocks of 1024 bytes). Each cell or node is assigned cellid
- or nodeid in the increasing order starting from 0.
+ cpus
specifies the CPU or range of CPUs that are
+ part of the node. memory
specifies the node memory
+ in kibibytes (i.e. blocks of 1024 bytes).
+ Since 1.2.7 all cells should
+ have id
attribute in case referring to some cell is
+ necessary in the code, otherwise the cells are
+ assigned id
s in the increasing order starting from
+ 0. Mixing cells with and without the id
attribute
+ is not recommended as it may result in unwanted behaviour.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index cfd8629cd29985967a77e36e390ab88e7eccf627..1d3b4d8544049b7a1de91ef41195074380d660f5 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3927,6 +3927,11 @@
+
+
+
+
+
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 811893db84059a2245b2ce9a068c640320f69b57..5003cf164cb9af9140ff0ce31be3eb2302a03636 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -152,7 +152,6 @@ virCPUDefCopy(const virCPUDef *cpu)
copy->ncells_max = copy->ncells = cpu->ncells;
for (i = 0; i < cpu->ncells; i++) {
- copy->cells[i].cellid = cpu->cells[i].cellid;
copy->cells[i].mem = cpu->cells[i].mem;
copy->cells[i].cpumask = virBitmapNewCopy(cpu->cells[i].cpumask);
@@ -438,17 +437,48 @@ virCPUDefParseXML(xmlNodePtr node,
for (i = 0; i < n; i++) {
char *cpus, *memory;
int ret, ncpus = 0;
+ unsigned int cur_cell;
+ char *tmp = NULL;
+
+ tmp = virXMLPropString(nodes[i], "id");
+ if (!tmp) {
+ cur_cell = i;
+ } else {
+ ret = virStrToLong_ui(tmp, NULL, 10, &cur_cell);
+ if (ret == -1) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid 'id' attribute in NUMA cell: %s"),
+ tmp);
+ VIR_FREE(tmp);
+ goto error;
+ }
+ VIR_FREE(tmp);
+ }
+
+ if (cur_cell >= n) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Exactly one 'cell' element per guest "
+ "NUMA cell allowed, non-contiguous ranges or "
+ "ranges not starting from 0 are not allowed"));
+ goto error;
+ }
+
+ if (def->cells[cur_cell].cpustr) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Duplicate NUMA cell info for cell id '%u'"),
+ cur_cell);
+ goto error;
+ }
- def->cells[i].cellid = i;
cpus = virXMLPropString(nodes[i], "cpus");
if (!cpus) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Missing 'cpus' attribute in NUMA cell"));
goto error;
}
- def->cells[i].cpustr = cpus;
+ def->cells[cur_cell].cpustr = cpus;
- ncpus = virBitmapParse(cpus, 0, &def->cells[i].cpumask,
+ ncpus = virBitmapParse(cpus, 0, &def->cells[cur_cell].cpumask,
VIR_DOMAIN_CPUMASK_LEN);
if (ncpus <= 0)
goto error;
@@ -461,7 +491,7 @@ virCPUDefParseXML(xmlNodePtr node,
goto error;
}
- ret = virStrToLong_ui(memory, NULL, 10, &def->cells[i].mem);
+ ret = virStrToLong_ui(memory, NULL, 10, &def->cells[cur_cell].mem);
if (ret == -1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Invalid 'memory' attribute in NUMA cell"));
@@ -645,6 +675,7 @@ virCPUDefFormatBuf(virBufferPtr buf,
virBufferAdjustIndent(buf, 2);
for (i = 0; i < def->ncells; i++) {
virBufferAddLit(buf, "cells[i].cpustr);
virBufferAsprintf(buf, " memory='%d'", def->cells[i].mem);
virBufferAddLit(buf, "/>\n");
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index 8c932ceb637e8ad656479e57a4f6a4d1d87802f3..2d538db5dbb31103b3d4ec4664fd3ce135f731d1 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -1,7 +1,7 @@
/*
* cpu_conf.h: CPU XML handling
*
- * Copyright (C) 2009-2011, 2013 Red Hat, Inc.
+ * Copyright (C) 2009-2011, 2013, 2014 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -93,7 +93,6 @@ struct _virCPUFeatureDef {
typedef struct _virCellDef virCellDef;
typedef virCellDef *virCellDefPtr;
struct _virCellDef {
- int cellid;
virBitmapPtr cpumask; /* CPUs that are part of this node */
char *cpustr; /* CPUs stored in string form for dumpxml */
unsigned int mem; /* Node memory in kB */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1d23d5f241fc07ff218c15d3ec505310b7898998..63a49e305c3e4b811c774ec5423bc846a65f3cff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6400,7 +6400,7 @@ qemuBuildNumaArgStr(const virDomainDef *def, virCommandPtr cmd)
}
virCommandAddArg(cmd, "-numa");
- virBufferAsprintf(&buf, "node,nodeid=%d", def->cpu->cells[i].cellid);
+ virBufferAsprintf(&buf, "node,nodeid=%zu", i);
virBufferAddLit(&buf, ",cpus=");
/* Up through qemu 1.4, -numa does not accept a cpus
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml
index ee402c8f7446faa83d767b9613b9517953ac7678..0543f7f79178b8d37c945938c053e71a566268f4 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml
@@ -9,10 +9,10 @@
-
+
- |
- |
+ |
+ |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml
index ee402c8f7446faa83d767b9613b9517953ac7678..0a5f9fcd13fa91136e47b5c6a8b9f2eb22b53c52 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml
@@ -9,10 +9,10 @@
-
+
- |
- |
+ |
+ |
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fa3070df2c349a5bf3103f873afcad77d38c5691
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
@@ -0,0 +1,25 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 16
+
+ hvm
+
+
+
+
+
+ |
+ |
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 557c87693d06c56a3e4e6e5f58d301818179c56f..8eb982f2c6a3f3e74a3e16d211a786947f4a7f0d 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1178,6 +1178,7 @@ mymain(void)
DO_TEST("cpu-strict1", NONE);
DO_TEST("cpu-numa1", NONE);
DO_TEST("cpu-numa2", QEMU_CAPS_SMP_TOPOLOGY);
+ DO_TEST_PARSE_ERROR("cpu-numa3", NONE);
DO_TEST("cpu-host-model", NONE);
skipLegacyCPUs = true;
DO_TEST("cpu-host-model-fallback", NONE);
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
new file mode 100644
index 0000000000000000000000000000000000000000..227bf1cd01f20bef961ba68b4314a00625cb5e0d
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
@@ -0,0 +1,28 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 16
+
+ hvm
+
+
+
+
+
+ |
+ |
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
new file mode 100644
index 0000000000000000000000000000000000000000..227bf1cd01f20bef961ba68b4314a00625cb5e0d
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
@@ -0,0 +1,28 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 219100
+ 219100
+ 16
+
+ hvm
+
+
+
+
+
+ |
+ |
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 8884b22121cef3947cd8a654a223b7755cd9a2c6..172ce2bc3d59d4857ffdddb94bec88ff1420f03b 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -370,6 +370,9 @@ mymain(void)
DO_TEST("chardev-label");
+ DO_TEST_DIFFERENT("cpu-numa1");
+ DO_TEST_DIFFERENT("cpu-numa2");
+
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
|