Virsh freecell --all was not olny getting wrong NUMA nodes count, but even the NUMA nodes ids. They doesn't have to be continuous, as I've found out during testing this. Therefore a modification of nodeGetCellsFreeMemory() error message. --- src/nodeinfo.c | 3 +- tools/virsh.c | 70 ++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 22d53e5..ba2f793 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -468,7 +468,8 @@ nodeGetCellsFreeMemory(virConnectPtr conn ATTRIBUTE_UNUSED, long long mem; if (numa_node_size64(n, &mem) < 0) { nodeReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("Failed to query NUMA free memory")); + "%s: %d", _("Failed to query NUMA free memory " + "for node"), n); goto cleanup; } freeMems[numCells++] = mem; diff --git a/tools/virsh.c b/tools/virsh.c index 50d5e33..165a791 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2283,9 +2283,15 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) int ret; int cell, cell_given; unsigned long long memory; - unsigned long long *nodes = NULL; + xmlNodePtr *nodes = NULL; + unsigned long nodes_cnt; + unsigned long *nodes_id = NULL; + unsigned long long *nodes_free = NULL; int all_given; - virNodeInfo info; + int i; + char *cap_xml = NULL; + xmlDocPtr xml = NULL; + xmlXPathContextPtr ctxt = NULL; if (!vshConnectionUsability(ctl, ctl->conn)) @@ -2301,32 +2307,60 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) } if (all_given) { - if (virNodeGetInfo(ctl->conn, &info) < 0) { - vshError(ctl, "%s", _("failed to get NUMA nodes count")); + cap_xml = virConnectGetCapabilities(ctl->conn); + if (!cap_xml) { + vshError(ctl, "%s", _("unable to get node capabilities")); goto cleanup; } - if (!info.nodes) { - vshError(ctl, "%s", _("no NUMA nodes present")); + xml = xmlReadDoc((const xmlChar *) cap_xml, "node.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + + if (!xml) { + vshError(ctl, "%s", _("unable to get node capabilities")); goto cleanup; } - if (VIR_ALLOC_N(nodes, info.nodes) < 0) { - vshError(ctl, "%s", _("could not allocate memory")); + ctxt = xmlXPathNewContext(xml); + nodes_cnt = virXPathNodeSet("/capabilities/host/topology/cells/cell", + ctxt, &nodes); + + if (nodes_cnt == -1) { + vshError(ctl, "%s", _("could not get information about " + "NUMA topology")); goto cleanup; } - ret = virNodeGetCellsFreeMemory(ctl->conn, nodes, 0, info.nodes); - if (ret != info.nodes) { - vshError(ctl, "%s", _("could not get information about " - "all NUMA nodes")); + if ((VIR_ALLOC_N(nodes_free, nodes_cnt) < 0) || + (VIR_ALLOC_N(nodes_id, nodes_cnt) < 0)){ + vshError(ctl, "%s", _("could not allocate memory")); goto cleanup; } + for (i = 0; i < nodes_cnt; i++) { + unsigned long id; + char *val = virXMLPropString(nodes[i], "id"); + char *conv = NULL; + id = strtoul(val, &conv, 10); + if (*conv !='\0') { + vshError(ctl, "%s", _("conversion from string failed")); + goto cleanup; + } + nodes_id[i]=id; + ret = virNodeGetCellsFreeMemory(ctl->conn, &(nodes_free[i]), id, 1); + if (ret != 1) { + vshError(ctl, "%s %lu", _("failed to get free memory for " + "NUMA node nuber:"), id); + goto cleanup; + } + } + memory = 0; - for (cell = 0; cell < info.nodes; cell++) { - vshPrint(ctl, "%5d: %10llu kB\n", cell, (nodes[cell]/1024)); - memory += nodes[cell]; + for (cell = 0; cell < nodes_cnt; cell++) { + vshPrint(ctl, "%5lu: %10llu kB\n", nodes_id[cell], + (nodes_free[cell]/1024)); + memory += nodes_free[cell]; } vshPrintExtra(ctl, "--------------------\n"); @@ -2351,7 +2385,13 @@ cmdFreecell(vshControl *ctl, const vshCmd *cmd) func_ret = TRUE; cleanup: + xmlXPathFreeContext(ctxt); + if (xml) + xmlFreeDoc(xml); VIR_FREE(nodes); + VIR_FREE(nodes_free); + VIR_FREE(nodes_id); + VIR_FREE(cap_xml); return func_ret; } -- 1.7.3.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list