[libvirt] [PATCH 02/24] conf: Move NUMA cell parsing code from cpu conf to numa conf
John Ferlan
jferlan at redhat.com
Thu Feb 19 21:12:28 UTC 2015
On 02/16/2015 01:51 PM, Peter Krempa wrote:
> 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.
> ---
> src/conf/cpu_conf.c | 90 ---------------------------------------
> src/conf/domain_conf.c | 17 +++++---
> src/conf/numa_conf.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++
> src/conf/numa_conf.h | 4 ++
> 4 files changed, 126 insertions(+), 96 deletions(-)
>
> diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
> index 4a367a1..f14b37a 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 b13cae8..06ed0fd 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 <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,
> diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
> index f6a8248..e36a4be 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:
Although this is mostly a cut'n'paste, why not just change the one "goto
cleanup;" to goto error and then not have two labels?
ACK - since I'm sure you'll do the right thing...
John
> + ctxt->node = oldNode;
> + VIR_FREE(nodes);
> + return ret;
> +}
> diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
> index bcc8c8a..276d25a 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;
> @@ -111,4 +112,7 @@ int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
>
> bool virDomainNumatuneNodesetIsAvailable(virDomainNumatunePtr numatune,
> virBitmapPtr auto_nodeset);
> +
> +int virDomainNumaDefCPUParseXML(virCPUDefPtr def, xmlXPathContextPtr ctxt);
> +
> #endif /* __NUMA_CONF_H__ */
>
More information about the libvir-list
mailing list