[libvirt] [test-API][PATCH v2] Add 2 host node memory API cases

Wayne Sun gsun at redhat.com
Thu Feb 21 11:25:12 UTC 2013


v1:
add 2 host node memory cases and update conf
- node_mem_param: tuning host node memory parameters
- node_memory: get host node memory info, including host free
memory, node free memory and node memory stats
- numa_param conf is updated with the 2 new cases

v2:
node_mem_param: polish codes with better readability
node_memory: direct fetch info in /sys/devices/system/node/node*
other than using command 'numastat'

Signed-off-by: Wayne Sun <gsun at redhat.com>
---
 cases/numa_param.conf        |   8 ++++
 repos/numa/node_mem_param.py |  81 ++++++++++++++++++++++++++++++++
 repos/numa/node_memory.py    | 107 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 repos/numa/node_mem_param.py
 create mode 100644 repos/numa/node_memory.py

diff --git a/cases/numa_param.conf b/cases/numa_param.conf
index 64268a3..515fb1f 100644
--- a/cases/numa_param.conf
+++ b/cases/numa_param.conf
@@ -1,3 +1,11 @@
+numa:node_memory
+
+numa:node_mem_param
+    shm_pages_to_scan
+        200
+    shm_sleep_millisecs
+        20
+
 domain:install_linux_cdrom
     guestname
         $defaultname
diff --git a/repos/numa/node_mem_param.py b/repos/numa/node_mem_param.py
new file mode 100644
index 0000000..86242b1
--- /dev/null
+++ b/repos/numa/node_mem_param.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# Test tuning host node memory parameters
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+
+required_params = ()
+optional_params = {"shm_pages_to_scan": 100,
+                   "shm_sleep_millisecs": 20,
+                   "shm_merge_across_nodes": 1
+                  }
+
+KSM_PATH = "/sys/kernel/mm/ksm/"
+
+def node_mem_param(params):
+    """test set host node memory parameters
+    """
+    logger = params['logger']
+    shm_pages_to_scan = params.get('shm_pages_to_scan')
+    shm_sleep_millisecs = params.get('shm_sleep_millisecs')
+    shm_merge_across_nodes = params.get('shm_merge_across_nodes')
+
+    if not shm_pages_to_scan \
+        and not shm_sleep_millisecs \
+        and not shm_merge_across_nodes:
+        logger.error("given param is none")
+        return 1
+
+    param_dict = {}
+    for i in optional_params.keys():
+        if eval(i):
+            param_dict[i] = int(eval(i))
+
+    logger.info("the given param dict is: %s" % param_dict)
+
+    conn = sharedmod.libvirtobj['conn']
+
+    try:
+        logger.info("get host node memory parameters")
+        mem_pre = conn.getMemoryParameters(0)
+        logger.info("host node memory parameters is: %s" % mem_pre)
+
+        logger.info("set host node memory parameters with given param %s" %
+                    param_dict)
+        conn.setMemoryParameters(param_dict, 0)
+        logger.info("set host node memory parameters done")
+
+        logger.info("get host node memory parameters")
+        mem_pos = conn.getMemoryParameters(0)
+        logger.info("host node memory parameters is: %s" % mem_pos)
+
+        for i in param_dict.keys():
+            if not mem_pos[i] == param_dict[i]:
+                logger.error("%s is not set as expected" % i)
+
+        logger.info("node memory parameters is set as expected")
+
+        logger.info("check tuning detail under %s" % KSM_PATH)
+
+        ksm_dict = {}
+        for i in param_dict.keys():
+            path = "%s%s" % (KSM_PATH, i[4:])
+            f = open(path)
+            ret = int(f.read().split('\n')[0])
+            f.close()
+            logger.info("%s value is: %s" % (path, ret))
+            ksm_dict[i] = ret
+
+        if ksm_dict == param_dict:
+            logger.info("tuning detail under %s is expected" % KSM_PATH)
+        else:
+            logger.error("check with tuning detail under %s failed"  % KSM_PATH)
+            return 1
+
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    return 0
diff --git a/repos/numa/node_memory.py b/repos/numa/node_memory.py
new file mode 100644
index 0000000..0241f3c
--- /dev/null
+++ b/repos/numa/node_memory.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# Test get host node memory info, including host free
+# memory, node free memory and node memory stats.
+
+import math
+
+import libvirt
+from libvirt import libvirtError
+
+from src import sharedmod
+from utils import utils
+
+required_params = ()
+optional_params = {}
+
+NODE_MEMINFO_PATH = "/sys/devices/system/node/node*/meminfo"
+
+def node_memory(params):
+    """test get host node memory info
+    """
+    logger = params['logger']
+
+    cmd = "lscpu|grep 'NUMA node(s)'"
+    ret, output = utils.exec_cmd(cmd, shell=True)
+    node_num = int(output[0].split(' ')[-1])
+    logger.info("host total nodes number is: %s" % node_num)
+
+    conn = sharedmod.libvirtobj['conn']
+
+    cmd = "grep 'MemFree' %s" % NODE_MEMINFO_PATH
+    node_mem = []
+    free_total = 0
+    ret, out = utils.exec_cmd(cmd, shell=True)
+    for i in range(node_num):
+        mem_free = int(out[i].split()[-2])
+        node_mem.append(mem_free)
+        free_total += mem_free
+
+    try:
+        logger.info("get host total free memory")
+        mem = conn.getFreeMemory()/1024
+        logger.info("host free memory total is: %s KiB" % mem)
+        logger.info("free memory collected in %s is: %s KiB" %
+                    (NODE_MEMINFO_PATH, free_total))
+
+        if math.fabs(mem - free_total) > 1024:
+            logger.error("free memory mismatch with info collected in %s" %
+                         NODE_MEMINFO_PATH)
+            return 1
+        else:
+            logger.info("get host free memory succeed")
+
+        logger.info("get free memory of nodes")
+        ret = conn.getCellsFreeMemory(0, node_num)
+        mem_list = [i/1024 for i in ret]
+        logger.info("node free memory list is: %s" % mem_list)
+        logger.info("node free memory list collected in %s is: %s" %
+                    (NODE_MEMINFO_PATH, node_mem))
+
+        for i in range(node_num):
+            if math.fabs(mem_list[i] - node_mem[i]) > 1024:
+                path = NODE_MEMINFO_PATH.replace('*', '%s') % i
+                logger.error("node %s free memory mismatch with collected in %s"
+                             % (i, path))
+                return 1
+
+        logger.info("get node free memory succeed")
+
+        logger.info("get node memory stats")
+        node_dict = {}
+        for i in range(node_num):
+            ret = conn.getMemoryStats(i, 0)
+            node_dict[i] = ret
+            logger.info("node %s memory stats is: %s" % (i, node_dict[i]))
+
+        node_tmp = {}
+        cmd_new = "grep 'MemTotal' %s" % NODE_MEMINFO_PATH
+        ret, out_free = utils.exec_cmd(cmd, shell=True)
+        ret, out_total = utils.exec_cmd(cmd_new, shell=True)
+        for i in range(node_num):
+            dict_tmp = {}
+            path = NODE_MEMINFO_PATH.replace('*', '%s') % i
+            dict_tmp['free'] = int(out_free[i].split()[-2])
+            dict_tmp['total'] = int(out_total[i].split()[-2])
+            node_tmp[i] = dict_tmp
+            logger.info("node %s memory stats collected in %s is: %s" %
+                        (i, path, node_tmp[i]))
+
+        for i in range(node_num):
+            path = NODE_MEMINFO_PATH.replace('*', '%s') % i
+            if math.fabs(node_tmp[i]['total'] - node_dict[i]['total']) > 1024:
+                logger.error("node %s total memory is mismatch with %s" %
+                             (i, path))
+                return 1
+
+            if math.fabs(node_tmp[i]['free'] - node_dict[i]['free']) > 1024:
+                logger.error("node %s free memory is mismatch with %s" %
+                             (i, path))
+                return 1
+
+        logger.info("get node memory stats succeed")
+
+    except libvirtError, e:
+        logger.error("libvirt call failed: " + str(e))
+        return 1
+
+    return 0
-- 
1.8.1




More information about the libvir-list mailing list