1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

conf: Move NUMA cell parsing code from cpu conf to numa conf

For weird historical reasons NUMA cells are added as a subelement of
<cpu> while the actual configuration is done in <numatune>.

This patch splits out the cell parser code from cpu config to NUMA
config. Note that the changes to the code are minimal just to make it
work and the function will be refactored in the next patch.
This commit is contained in:
Peter Krempa 2015-02-11 12:27:53 +01:00
parent fcee64e73c
commit 5bba61fd58
4 changed files with 126 additions and 96 deletions

View File

@ -426,96 +426,6 @@ virCPUDefParseXML(xmlNodePtr node,
def->features[i].policy = policy;
}
if (virXPathNode("./numa[1]", ctxt)) {
VIR_FREE(nodes);
n = virXPathNodeSet("./numa[1]/cell", ctxt, &nodes);
if (n <= 0) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("NUMA topology defined without NUMA cells"));
goto error;
}
if (VIR_RESIZE_N(def->cells, def->ncells_max,
def->ncells, n) < 0)
goto error;
def->ncells = n;
for (i = 0; i < n; i++) {
char *cpus, *memAccessStr;
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;
}
cpus = virXMLPropString(nodes[i], "cpus");
if (!cpus) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Missing 'cpus' attribute in NUMA cell"));
goto error;
}
def->cells[cur_cell].cpustr = cpus;
ncpus = virBitmapParse(cpus, 0, &def->cells[cur_cell].cpumask,
VIR_DOMAIN_CPUMASK_LEN);
if (ncpus <= 0)
goto error;
def->cells_cpus += ncpus;
ctxt->node = nodes[i];
if (virDomainParseMemory("./@memory", "./@unit", ctxt,
&def->cells[cur_cell].mem, true, false) < 0)
goto cleanup;
memAccessStr = virXMLPropString(nodes[i], "memAccess");
if (memAccessStr) {
int rc = virMemAccessTypeFromString(memAccessStr);
if (rc <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid 'memAccess' attribute "
"value '%s'"),
memAccessStr);
VIR_FREE(memAccessStr);
goto error;
}
def->cells[cur_cell].memAccess = rc;
VIR_FREE(memAccessStr);
}
}
}
cleanup:
ctxt->node = oldnode;
VIR_FREE(fallback);

View File

@ -13495,12 +13495,17 @@ virDomainDefParseXML(xmlDocPtr xml,
goto error;
}
if (def->cpu->cells_cpus > def->maxvcpus) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Number of CPUs in <numa> exceeds the"
" <vcpu> count"));
goto error;
}
}
if (virDomainNumaDefCPUParseXML(def->cpu, ctxt) < 0)
goto error;
if (def->cpu &&
def->cpu->cells_cpus > def->maxvcpus) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Number of CPUs in <numa> exceeds the"
" <vcpu> count"));
goto error;
}
if (virDomainNumatuneParseXML(&def->numatune,

View File

@ -680,3 +680,114 @@ virDomainNumatuneNodesetIsAvailable(virDomainNumatunePtr numatune,
return true;
}
int
virDomainNumaDefCPUParseXML(virCPUDefPtr def,
xmlXPathContextPtr ctxt)
{
xmlNodePtr *nodes = NULL;
xmlNodePtr oldNode = ctxt->node;
int n;
size_t i;
int ret = -1;
if (virXPathNode("/domain/cpu/numa[1]", ctxt)) {
VIR_FREE(nodes);
n = virXPathNodeSet("/domain/cpu/numa[1]/cell", ctxt, &nodes);
if (n <= 0) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("NUMA topology defined without NUMA cells"));
goto error;
}
if (VIR_RESIZE_N(def->cells, def->ncells_max,
def->ncells, n) < 0)
goto error;
def->ncells = n;
for (i = 0; i < n; i++) {
char *cpus, *memAccessStr;
int rc, ncpus = 0;
unsigned int cur_cell;
char *tmp = NULL;
tmp = virXMLPropString(nodes[i], "id");
if (!tmp) {
cur_cell = i;
} else {
rc = virStrToLong_ui(tmp, NULL, 10, &cur_cell);
if (rc == -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;
}
cpus = virXMLPropString(nodes[i], "cpus");
if (!cpus) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("Missing 'cpus' attribute in NUMA cell"));
goto error;
}
def->cells[cur_cell].cpustr = cpus;
ncpus = virBitmapParse(cpus, 0, &def->cells[cur_cell].cpumask,
VIR_DOMAIN_CPUMASK_LEN);
if (ncpus <= 0)
goto error;
def->cells_cpus += ncpus;
ctxt->node = nodes[i];
if (virDomainParseMemory("./@memory", "./@unit", ctxt,
&def->cells[cur_cell].mem, true, false) < 0)
goto cleanup;
memAccessStr = virXMLPropString(nodes[i], "memAccess");
if (memAccessStr) {
rc = virMemAccessTypeFromString(memAccessStr);
if (rc <= 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid 'memAccess' attribute "
"value '%s'"),
memAccessStr);
VIR_FREE(memAccessStr);
goto error;
}
def->cells[cur_cell].memAccess = rc;
VIR_FREE(memAccessStr);
}
}
}
ret = 0;
error:
cleanup:
ctxt->node = oldNode;
VIR_FREE(nodes);
return ret;
}

View File

@ -29,6 +29,7 @@
# include "virutil.h"
# include "virbitmap.h"
# include "virbuffer.h"
# include "cpu_conf.h"
typedef struct _virDomainNumatune virDomainNumatune;
@ -114,4 +115,7 @@ bool virDomainNumatuneNodesetIsAvailable(virDomainNumatunePtr numatune,
bool virDomainNumatuneNodeSpecified(virDomainNumatunePtr numatune,
int cellid);
int virDomainNumaDefCPUParseXML(virCPUDefPtr def, xmlXPathContextPtr ctxt);
#endif /* __NUMA_CONF_H__ */