This will iterate over all NUMA nodes, showing
free memory for each and sum at the end.
Existing default behavior is not changed.
---
 tools/virsh.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index cd54174..505ae85 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -2273,36 +2273,87 @@ static const vshCmdInfo info_freecell[] = {
 
 static const vshCmdOptDef opts_freecell[] = {
     {"cellno", VSH_OT_INT, 0, N_("NUMA cell number")},
+    {"all", VSH_OT_BOOL, 0, N_("show free memory for all NUMA cells")},
     {NULL, 0, 0, NULL}
 };
 
 static int
 cmdFreecell(vshControl *ctl, const vshCmd *cmd)
 {
+    int func_ret = FALSE;
     int ret;
     int cell, cell_given;
     unsigned long long memory;
+    unsigned long long *nodes = NULL;
+    int all_given;
+    virNodeInfo info;
+
 
     if (!vshConnectionUsability(ctl, ctl->conn))
         return FALSE;
 
     cell = vshCommandOptInt(cmd, "cellno", &cell_given);
-    if (!cell_given) {
-        memory = virNodeGetFreeMemory(ctl->conn);
-        if (memory == 0)
-            return FALSE;
+    all_given = vshCommandOptBool(cmd, "all");
+
+    if (all_given && cell_given) {
+        vshError(ctl, "%s", _("--cellno and --all are mutually exclusive. "
+                              "Please choose only one."));
+        goto cleanup;
+    }
+
+    if (all_given) {
+        if (virNodeGetInfo(ctl->conn, &info) < 0) {
+            vshError(ctl, "%s", _("failed to get NUMA nodes count"));
+            goto cleanup;
+        }
+
+        if (!info.nodes) {
+            vshError(ctl, "%s", _("no NUMA nodes present"));
+            goto cleanup;
+        }
+
+        if (VIR_ALLOC_N(nodes, info.nodes) < 0) {
+            vshError(ctl, "%s", _("could not allocate memory"));
+            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"));
+            goto cleanup;
+        }
+
+        memory = 0;
+        for (cell = 0; cell < info.nodes; cell++) {
+            vshPrint(ctl, "%5d: %10llu kB\n", cell, (nodes[cell]/1024));
+            memory += nodes[cell];
+        }
+
+        vshPrintExtra(ctl, "--------------------\n");
+        vshPrintExtra(ctl, "%5s: %10llu kB\n",_("Total"), memory/1024);
     } else {
-        ret = virNodeGetCellsFreeMemory(ctl->conn, &memory, cell, 1);
-        if (ret != 1)
-            return FALSE;
+        if (!cell_given) {
+            memory = virNodeGetFreeMemory(ctl->conn);
+            if (memory == 0)
+                goto cleanup;
+        } else {
+            ret = virNodeGetCellsFreeMemory(ctl->conn, &memory, cell, 1);
+            if (ret != 1)
+                goto cleanup;
+        }
+
+        if (cell == -1)
+            vshPrint(ctl, "%s: %llu kB\n", _("Total"), (memory/1024));
+        else
+            vshPrint(ctl, "%d: %llu kB\n", cell, (memory/1024));
     }
 
-    if (cell == -1)
-        vshPrint(ctl, "%s: %llu kB\n", _("Total"), (memory/1024));
-    else
-        vshPrint(ctl, "%d: %llu kB\n", cell, (memory/1024));
+    func_ret = TRUE;
 
-    return TRUE;
+cleanup:
+    VIR_FREE(nodes);
+    return func_ret;
 }
 
 /*
-- 
1.7.3.5

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to