On 12/14/2012 03:50 PM, Wayne Sun wrote:
* cover live and config flags. * config case use numaParameters API to check and confirm with check domain config xml. * live update numa parameters is with problem now, setNumaParameters API is with bug 857312 on live domain. Also use numaParameters API to check after set, then check domain pid status with allowed memory list to confirm the nodeset. * The mode check in live case is marked as TODO for later. Signed-off-by: Wayne Sun <gsun@xxxxxxxxxx> --- cases/numa_param.conf | 51 +++++++++++++++++ repos/numa/numa_param_config.py | 119 +++++++++++++++++++++++++++++++++++++++ repos/numa/numa_param_live.py | 104 ++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+), 0 deletions(-) create mode 100644 cases/numa_param.conf create mode 100644 repos/numa/__init__.py create mode 100644 repos/numa/numa_param_config.py create mode 100644 repos/numa/numa_param_live.py diff --git a/cases/numa_param.conf b/cases/numa_param.conf new file mode 100644 index 0000000..64268a3 --- /dev/null +++ b/cases/numa_param.conf @@ -0,0 +1,51 @@ +domain:install_linux_cdrom + guestname + $defaultname + guestos + $defaultos + guestarch + $defaultarch + vcpu + 4 + memory + $defaultmem + hddriver + $defaulthd + nicdriver + $defaultnic + imageformat + qcow2 + +numa:numa_param_live + guestname + $defaultname + nodeset + 0 + mode + 0 + +domain:destroy + guestname + $defaultname + +numa:numa_param_config + guestname + $defaultname + nodeset + 0-1 + mode + 2 + +domain:start + guestname + $defaultname + +domain:destroy + guestname + $defaultname + +domain:undefine + guestname + $defaultname + +options cleanup=enable diff --git a/repos/numa/__init__.py b/repos/numa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/repos/numa/numa_param_config.py b/repos/numa/numa_param_config.py new file mode 100644 index 0000000..52b21dd --- /dev/null +++ b/repos/numa/numa_param_config.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# Test set domain numa parameters with flag +# VIR_DOMAIN_AFFECT_CONFIG and check + +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', 'nodeset', 'mode') +optional_params = {} + +def check_numa_params(domobj, mode, node_tuple): + """dump domain config xml description to check numa params + """ + guestxml = domobj.XMLDesc(2) + logger.debug("domain %s xml is :\n%s" %(domobj.name(), guestxml)) + xml = minidom.parseString(guestxml) + numatune = xml.getElementsByTagName('numatune')[0] + mem_element = numatune.getElementsByTagName('memory')[0] + + if mem_element.hasAttribute('mode') and \ + mem_element.hasAttribute('nodeset'): + attr = mem_element.getAttributeNode('mode') + mode_val = attr.nodeValue + logger.info("memory mode in config xml is: %s" % mode_val) + if mode_val == 'strict': + mode_num = 0 + elif mode_val == 'preferred': + mode_num = 1 + elif mode_val == 'interleave': + mode_num = 2 + else: + logger.error("mode value is invalid") + return 1 + + attr = mem_element.getAttributeNode('nodeset') + nodeset_val = attr.nodeValue + logger.info("nodeset in config xml is: %s" % nodeset_val) + else: + logger.error("no 'mode' and 'nodeset' atrribute for element memory") + return 1 + + ret = utils.param_to_tuple(nodeset_val, node_num) + logger.debug("nudeset in config xml to tuple is:") + logger.debug(ret) + if not ret: + logger.error("fail to parse nodeset to tuple") + return 1 + + if mode_num == mode and ret == node_tuple: + return 0 + else: + return 1 + +def numa_param_config(params): + """set domain numa parameters with config flag and check + """ + global logger + logger = params['logger'] + params.pop('logger') + guestname = params['guestname'] + nodeset = params['nodeset'] + mode = int(params['mode']) + + logger.info("the name of virtual machine is %s" % guestname) + logger.info("the given node number is: %s" % nodeset) + logger.info("the given mode is: %s" % mode) + + global node_num + cmd = "lscpu|grep 'NUMA node(s)'" + ret, output = utils.exec_cmd(cmd, shell=True) + node_num = int(output[0].split(' ')[-1]) + node_tuple = utils.param_to_tuple(nodeset, node_num) + logger.debug("nodeset to tuple is:") + logger.debug(node_tuple) + + param = {'numa_nodeset': nodeset, 'numa_mode': mode} + logger.info("numa param dict for set is: %s" % param) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + logger.info("set domain numa parameters with flag: %s" % + libvirt.VIR_DOMAIN_AFFECT_CONFIG) + domobj.setNumaParameters(param, libvirt.VIR_DOMAIN_AFFECT_CONFIG) + logger.info("set domain numa parameters succeed") + + logger.info("check numa parameters") + ret = domobj.numaParameters(libvirt.VIR_DOMAIN_AFFECT_CONFIG) + logger.info("numa parameters after set is: %s" % ret) + + new_tuple = utils.param_to_tuple(ret['numa_nodeset'], node_num) + if not new_tuple: + logger.error("fail to parse nodeset to tuple") + return 1 + + if new_tuple == node_tuple and ret['numa_mode'] == mode: + logger.info("numa parameters is as expected") + else: + logger.error("numa parameters is not as expected") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + logger.info("check domain config xml of numa params") + ret = check_numa_params(domobj, mode, node_tuple) + if ret: + logger.error("numa params in domain config xml are not expected") + return 1 + else: + logger.info("numa params in domain config xml are expected") + return 0 diff --git a/repos/numa/numa_param_live.py b/repos/numa/numa_param_live.py new file mode 100644 index 0000000..8bec4f9 --- /dev/null +++ b/repos/numa/numa_param_live.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# Test set domain numa parameters with flag VIR_DOMAIN_AFFECT_LIVE +# and check + +from xml.dom import minidom + +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', 'nodeset', 'mode') +optional_params = {} + +def check_numa_params(guestname, mode, node_tuple): + """dump domain live xml description to check numa params and + check memory allowed list of domain pid + """ + cmd = "cat /var/run/libvirt/qemu/%s.pid" % guestname + status, pid = utils.exec_cmd(cmd, shell=True) + if status: + logger.error("failed to get the pid of domain %s" % guestname) + return 1 + + cmd = "grep Mems_allowed_list /proc/%s/status" % pid[0] + status, output = utils.exec_cmd(cmd, shell=True) + nodeval = output[0].split('\t')[1] + ret = utils.param_to_tuple(nodeset_val, node_num) + logger.info("Mems_allowed_list in domain pid status is: %s" % nodeval) + logger.debug("parse nodeset to tuple is:") + logger.debug(ret) + if not ret: + logger.error("fail to parse nodeset to tuple") + return 1 + + # TODO: add check for mode + + if ret == node_tuple: + return 0 + else: + return 1 + +def numa_param_live(params): + """set domain numa parameters with live flag and check + """ + global logger + logger = params['logger'] + params.pop('logger') + guestname = params['guestname'] + nodeset = params['nodeset'] + mode = int(params['mode']) + + logger.info("the name of virtual machine is %s" % guestname) + logger.info("the given node number is: %s" % nodeset) + logger.info("the given mode is: %s" % mode) + + global node_num + cmd = "lscpu|grep 'NUMA node(s)'" + ret, output = utils.exec_cmd(cmd, shell=True) + node_num = int(output[0].split(' ')[-1]) + node_tuple = utils.param_to_tuple(nodeset, node_num) + logger.debug("nodeset to tuple is:") + logger.debug(node_tuple) + + param = {'numa_nodeset': nodeset, 'numa_mode': mode} + logger.info("numa param dict for set is: %s" % param) + + conn = sharedmod.libvirtobj['conn'] + + try: + domobj = conn.lookupByName(guestname) + logger.info("set domain numa parameters with flag: %s" % + libvirt.VIR_DOMAIN_AFFECT_LIVE) + domobj.setNumaParameters(param, libvirt.VIR_DOMAIN_AFFECT_LIVE) + logger.info("set domain numa parameters succeed") + + logger.info("check numa parameters") + ret = domobj.numaParameters(libvirt.VIR_DOMAIN_AFFECT_LIVE) + logger.info("numa parameters after set is: %s" % ret) + + new_tuple = utils.param_to_tuple(ret['numa_nodeset'], node_num) + if not new_tuple: + logger.error("fail to parse nodeset to tuple") + return 1 + + if new_tuple == node_tuple and ret['numa_mode'] == mode: + logger.info("numa parameters is as expected") + else: + logger.error("numa parameters is not as expected") + return 1 + + except libvirtError, e: + logger.error("libvirt call failed: " + str(e)) + return 1 + + logger.info("check whether numa params is working") + ret = check_numa_params(guestname, mode, node_tuple) + if ret: + logger.error("numa params working as expected") + return 1 + else: + logger.info("numa params working as expected") + return 0
ACK and pushed Thanks Guannan -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list