2 # Print some host NUMA node statistics
5 # Michal Privoznik <mprivozn@redhat.com>
9 from xml
.dom
import minidom
12 def xpath_eval(ctxt
, path
):
13 res
= ctxt
.xpathEval(path
)
14 if res
is None or len(res
) == 0:
17 value
= res
[0].content
21 conn
= libvirt
.openReadOnly(None)
22 except libvirt
.libvirtError
:
23 print("Failed to connect to the hypervisor")
27 capsXML
= conn
.getCapabilities()
28 except libvirt
.libvirtError
:
29 print("Failed to request capabilities")
32 caps
= minidom
.parseString(capsXML
)
33 cells
= caps
.getElementsByTagName("cells")[0]
35 nodesIDs
= [ int(proc
.getAttribute("id"))
36 for proc
in cells
.getElementsByTagName("cell") ]
38 nodesMem
= [ conn
.getMemoryStats(int(proc
))
41 doms
= conn
.listAllDomains(libvirt
.VIR_CONNECT_LIST_DOMAINS_ACTIVE
)
45 if proc
.numaParameters()["numa_mode"] == libvirt
.VIR_DOMAIN_NUMATUNE_MEM_STRICT
]
48 for dom
in domsStrict
:
49 xmlStr
= dom
.XMLDesc()
50 doc
= libxml2
.parseDoc(xmlStr
)
51 ctxt
= doc
.xpathNewContext()
53 domsStrictCfg
[dom
] = {}
55 pin
= ctxt
.xpathEval("string(/domain/numatune/memory/@nodeset)")
56 memsize
= ctxt
.xpathEval("string(/domain/memory)")
57 domsStrictCfg
[dom
]["memory"] = {"size": int(memsize
), "pin": pin
}
59 for memnode
in ctxt
.xpathEval("/domain/numatune/memnode"):
60 ctxt
.setContextNode(memnode
)
61 cellid
= xpath_eval(ctxt
, "@cellid")
62 nodeset
= xpath_eval(ctxt
, "@nodeset")
64 nodesize
= xpath_eval(ctxt
, "/domain/cpu/numa/cell[@id='%s']/@memory" % cellid
)
65 domsStrictCfg
[dom
][cellid
] = {"size": int(nodesize
), "pin": nodeset
}
69 print("NUMA nodes:\t" + "\t".join(str(node
) for node
in nodesIDs
))
70 print("MemTotal:\t" + "\t".join(str(i
.get("total") // 1024) for i
in nodesMem
))
71 print("MemFree:\t" + "\t".join(str(i
.get("free") // 1024) for i
in nodesMem
))
73 for dom
, v
in domsStrictCfg
.items():
74 print("Domain '%s':\t" % dom
.name())
76 toPrint
= "\tOverall memory: %d MiB" % (v
["memory"]["size"] // 1024)
77 if v
["memory"]["pin"] is not None and v
["memory"]["pin"] is not "":
78 toPrint
= toPrint
+ " nodes %s" % v
["memory"]["pin"]
81 for k
, node
in sorted(v
.items()):
84 toPrint
= "\tNode %s:\t%d MiB" % (k
, node
["size"] // 1024)
85 if node
["pin"] is not None and node
["pin"] is not "":
86 toPrint
= toPrint
+ " nodes %s" % node
["pin"]