[libvirt] [libvirt-python][PATCH] examples: Introduce nodestats example

Michal Privoznik mprivozn at redhat.com
Mon Jun 29 14:53:38 UTC 2015


So, this is an exercise to show libvirt capabilities. Firstly, for
each host NUMA nodes some statistics are printed out, i.e. total
memory and free memory. Then, for each running domain, that has memory
strictly bound to certain host nodes, a small statistics of how much
memory it takes is printed out too. For instance:

  # ./nodestats.py
  NUMA stats
  NUMA nodes:             0       1       2       3
  MemTotal:               3950    3967    3937    3943
  MemFree:                434     674     149     216
  Dom 'gentoo':           1048576 1048576 1048576 1048576

We can see 4 host NUMA nodes, all of them having roughly 4GB of RAM.
Yeah, some of them has nearly all the memory consumed. Then, there's
only one running domain, called 'gentoo', and it has 1GB per each NUMA
node configured.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 examples/nodestats.py | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100755 examples/nodestats.py

diff --git a/examples/nodestats.py b/examples/nodestats.py
new file mode 100755
index 0000000..dbf5593
--- /dev/null
+++ b/examples/nodestats.py
@@ -0,0 +1,106 @@
+#!/usr/bin/env python
+# Print some host NUMA node statistics
+#
+# Authors:
+#   Michal Privoznik <mprivozn at redhat.com
+
+import libvirt
+import sys
+from xml.dom import minidom
+import libxml2
+
+class virBitmap:
+    def __init__(self):
+        self.bitmap = 0
+
+    def setBit(self, offset):
+        mask = 1 << offset
+        self.bitmap = self.bitmap | mask
+
+    def clearBit(self, offset):
+        mask = ~(1 << offset)
+        self.bitmap = self.bitmap & mask
+
+    def isSet(self, offset):
+        mask = 1 << offset
+        return(self.bitmap & mask)
+
+    def setRange(self, start, end):
+        while (start <= end):
+            self.setBit(start)
+            start = start + 1
+
+    def parse(self, string):
+        for s in string.split(','):
+            list = s.split('-', 2)
+            start = int(list[0])
+            if len(list) == 2:
+                end = int(list[1])
+            else:
+                end = start
+            self.setRange(start, end)
+
+def xpath_eval(ctxt, path):
+    res = ctxt.xpathEval(path)
+    if res is None or len(res) == 0:
+        value = None
+    else:
+        value = res[0].content
+    return value
+
+try:
+    conn = libvirt.openReadOnly(None)
+except libvirt.libvirtError:
+    print('Failed to connect to the hypervisor')
+    sys.exit(1)
+
+try:
+    capsXML = conn.getCapabilities()
+except libvirt.libvirtError:
+    print('Failed to request capabilities')
+    sys.exit(1)
+
+caps = minidom.parseString(capsXML)
+cells = caps.getElementsByTagName('cells')[0]
+
+nodesIDs = [ int(proc.getAttribute('id'))
+             for proc in cells.getElementsByTagName('cell') ]
+
+nodesMem = [ conn.getMemoryStats(int(proc))
+             for proc in nodesIDs]
+
+doms = conn.listAllDomains(libvirt.VIR_CONNECT_LIST_DOMAINS_ACTIVE)
+domsStrict = [ proc
+               for proc in doms
+               if proc.numaParameters()['numa_mode'] == libvirt.VIR_DOMAIN_NUMATUNE_MEM_STRICT ]
+
+domsStrictCfg = {}
+
+for dom in domsStrict:
+    xmlStr = dom.XMLDesc()
+    doc = libxml2.parseDoc(xmlStr)
+    ctxt = doc.xpathNewContext()
+
+    domsStrictCfg[dom] = [ 0  for node in nodesIDs ]
+
+    for memnode in ctxt.xpathEval("/domain/numatune/memnode"):
+        ctxt.setContextNode(memnode)
+        cellid = xpath_eval(ctxt, "@cellid")
+        mode = xpath_eval(ctxt, "@mode")
+        nodeset = xpath_eval(ctxt, "@nodeset")
+
+        bitmap = virBitmap()
+        bitmap.parse(nodeset)
+        for node in nodesIDs:
+            if bitmap.isSet(int(node)):
+                mem = xpath_eval(ctxt, "/domain/cpu/numa/cell[@id='%s']/@memory" % cellid)
+                domsStrictCfg[dom][int(node)] += int(mem)
+
+print("NUMA stats")
+print("NUMA nodes:\t\t" + "\t".join(str(node) for node in nodesIDs))
+print("MemTotal:\t\t" + "\t".join(str(i.get('total') / 1024) for i in nodesMem))
+print("MemFree:\t\t" + "\t".join(str(i.get('free') / 1024) for i in nodesMem))
+
+for dom in domsStrictCfg:
+    sys.stdout.write("Dom '%s':\t\t" % dom.name())
+    print("\t".join(map(str, domsStrictCfg[dom][:])))
-- 
2.3.6




More information about the libvir-list mailing list