diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c index 4a367a1f6b..f14b37ae19 100644 --- a/src/conf/cpu_conf.c +++ b/src/conf/cpu_conf.c @@ -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); diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2e352934ca..98549e1089 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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 exceeds the" - " 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 exceeds the" + " count")); + goto error; } if (virDomainNumatuneParseXML(&def->numatune, diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c index 0bbc136e59..b4f0fca13e 100644 --- a/src/conf/numa_conf.c +++ b/src/conf/numa_conf.c @@ -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; +} diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h index 4891f15694..78b24a1bc1 100644 --- a/src/conf/numa_conf.h +++ b/src/conf/numa_conf.h @@ -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__ */