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 ids 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);