[libvirt] [PATCH v2] virsh: freecell --all getting wrong NUMA nodes count

Michal Privoznik mprivozn at redhat.com
Thu Feb 17 16:19:21 UTC 2011


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




More information about the libvir-list mailing list