* repos/domain/blkstatsflags.py * repos/domain/block_iotune.py * repos/domain/block_peek.py * repos/domain/block_resize.py * repos/domain/domain_blkio.py * cases/basic_blockjob.conf V1->V2: Removed diskpath params for block_resize, this hard code disk device is not convenient for users. --- cases/basic_blockjob.conf | 83 +++++++++++++++++++++ repos/domain/blkstatsflags.py | 63 ++++++++++++++++ repos/domain/block_iotune.py | 118 ++++++++++++++++++++++++++++++ repos/domain/block_peek.py | 69 ++++++++++++++++++ repos/domain/block_resize.py | 94 ++++++++++++++++++++++++ repos/domain/domain_blkio.py | 163 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 590 insertions(+) create mode 100644 cases/basic_blockjob.conf create mode 100644 repos/domain/blkstatsflags.py create mode 100644 repos/domain/block_iotune.py create mode 100644 repos/domain/block_peek.py create mode 100644 repos/domain/block_resize.py create mode 100644 repos/domain/domain_blkio.py diff --git a/cases/basic_blockjob.conf b/cases/basic_blockjob.conf new file mode 100644 index 0000000..21332dc --- /dev/null +++ b/cases/basic_blockjob.conf @@ -0,0 +1,83 @@ +domain:install_linux_cdrom + guestname + $defaultname + guestos + $defaultos + guestarch + $defaultarch + vcpu + $defaultvcpu + memory + $defaultmem + hddriver + $defaulthd + nicdriver + $defaultnic + macaddr + 54:52:00:45:c3:8a + +domain:install_linux_check + guestname + $defaultname + virt_type + $defaulthv + hddriver + $defaulthd + nicdriver + $defaultnic + +domain:block_iotune + guestname + $defaultname + bytes_sec + 100000 + iops_sec + 0 + +domain:block_iotune + guestname + $defaultname + bytes_sec + 0 + iops_sec + 1000 + +domain:block_peek + guestname + $defaultname + +domain:block_peek + guestname + $defaultname + +domain:block_resize + guestname + $defaultname + disksize + 1G + +domain:blkstats + guestname + $defaultname + +domain:blkstatsflags + guestname + $defaultname + flags + 0 + +domain:domain_blkinfo + guestname + $defaultname + +domain:domain_blkio + guestname + $defaultname + weight + 500 + +domain:undefine + guestname + $defaultname + +options cleanup=enable diff --git a/repos/domain/blkstatsflags.py b/repos/domain/blkstatsflags.py new file mode 100644 index 0000000..4c84a18 --- /dev/null +++ b/repos/domain/blkstatsflags.py @@ -0,0 +1,63 @@ +#!/usr/bin/evn python +# To test domain block device statistics with flags + +import time +import libxml2 + +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', 'flags') +optional_params = {} + +def check_guest_status(domobj): + """Check guest current status""" + state = domobj.info()[0] + if state == libvirt.VIR_DOMAIN_SHUTOFF or state == libvirt.VIR_DOMAIN_SHUTDOWN: + # add check function + return False + else: + return True + +def check_blkstats(): + """Check block device statistic result""" + pass + +def blkstatsflags(params): + """Domain block device statistic""" + logger = params['logger'] + guestname = params['guestname'] + flags = int(params['flags']) + + conn = sharedmod.libvirtobj['conn'] + + domobj = conn.lookupByName(guestname) + + # Check domain block status + if check_guest_status(domobj): + pass + else: + domobj.create() + time.sleep(90) + try: + xml = domobj.XMLDesc(0) + doc = libxml2.parseDoc(xml) + cont = doc.xpathNewContext() + devs = cont.xpathEval("/domain/devices/disk/target/@dev") + + for dev in devs: + path = dev.content + blkstats = domobj.blockStatsFlags(path, flags) + # check_blkstats() + logger.debug(blkstats) + for entry in blkstats.keys(): + logger.info("%s %s %s" %(path, entry, blkstats[entry])) + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" + % (e.message, e.get_error_code())) + return 1 + + return 0 diff --git a/repos/domain/block_iotune.py b/repos/domain/block_iotune.py new file mode 100644 index 0000000..26e4823 --- /dev/null +++ b/repos/domain/block_iotune.py @@ -0,0 +1,118 @@ +#!/usr/bin/evn python +# To test domain block device iotune + +import time +import libxml2 +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname', 'bytes_sec', 'iops_sec') +optional_params = {} + +def check_guest_status(domobj): + """Check guest current status""" + state = domobj.info()[0] + if state == libvirt.VIR_DOMAIN_SHUTOFF or \ + state == libvirt.VIR_DOMAIN_SHUTDOWN: + # add check function + return False + else: + return True + +def prepare_block_iotune(param, wbs, rbs, tbs, wis, ris, tis, logger): + """prepare the block iotune parameter + """ + logger.info("write_bytes_sec : %s" % wbs) + param['write_bytes_sec'] = wbs + logger.info("read_bytes_sec : %s" % rbs) + param['read_bytes_sec'] = rbs + logger.info("total_bytes_sec : %s" % tbs) + param['total_bytes_sec'] = tbs + logger.info("write_iops_sec : %s" % wis) + param['write_iops_sec'] = wis + logger.info("read_iops_sec : %s" % ris) + param['read_iops_sec'] = ris + logger.info("total_iops_sec : %s\n" % tis) + param['total_iops_sec'] = tis + return 0 + +def check_iotune(expected_param, result_param): + """check block iotune configuration + """ + for k in expected_param.keys(): + if expected_param[k] != result_param[k]: + return 1 + return 0 + +def block_iotune(params): + """Domain block device iotune""" + logger = params['logger'] + guestname = params['guestname'] + bytes_sec = int(params['bytes_sec']) + iops_sec = int(params['iops_sec']) + flag = 0 + + conn = sharedmod.libvirtobj['conn'] + + domobj = conn.lookupByName(guestname) + + # Check domain block status + if check_guest_status(domobj): + pass + else: + domobj.create() + time.sleep(90) + + try: + xml = domobj.XMLDesc(0) + doc = libxml2.parseDoc(xml) + cont = doc.xpathNewContext() + vdevs = cont.xpathEval("/domain/devices/disk/target/@dev") + vdev = vdevs[0].content + + iotune_para = {'write_bytes_sec': 0L, + 'total_iops_sec': 0L, + 'read_iops_sec': 0L, + 'read_bytes_sec': 0L, + 'write_iops_sec': 0L, + 'total_bytes_sec': 0L + } + + logger.info("prepare block iotune:") + prepare_block_iotune(iotune_para, bytes_sec, bytes_sec, 0, + iops_sec, iops_sec, 0, logger) + + logger.info("start to set block iotune:") + domobj.setBlockIoTune(vdev, iotune_para, flag) + + res = domobj.blockIoTune(vdev, flag) + ret = check_iotune(iotune_para, res) + if not ret: + logger.info("set pass") + else: + logger.error("fails to set") + return 1 + + logger.info("prepare block iotune:") + prepare_block_iotune(iotune_para, 0, 0, bytes_sec, + 0, 0, iops_sec, logger) + + logger.info("start to set block iotune:") + domobj.setBlockIoTune(vdev, iotune_para, flag) + + res = domobj.blockIoTune(vdev, flag) + ret = check_iotune(iotune_para, res) + if not ret: + logger.info("set pass") + else: + logger.error("fails to set") + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" + % (e.message, e.get_error_code())) + return 1 + + return 0 diff --git a/repos/domain/block_peek.py b/repos/domain/block_peek.py new file mode 100644 index 0000000..b88668a --- /dev/null +++ b/repos/domain/block_peek.py @@ -0,0 +1,69 @@ +#!/usr/bin/evn python +# To test domain block device peek + +import time +import libxml2 +import libvirt +from libvirt import libvirtError + +from src import sharedmod + +required_params = ('guestname',) +optional_params = {} + +def check_guest_status(domobj): + """Check guest current status""" + state = domobj.info()[0] + if state == libvirt.VIR_DOMAIN_SHUTOFF or \ + state == libvirt.VIR_DOMAIN_SHUTDOWN: + # add check function + return False + else: + return True + +def block_peek(params): + """domain block peek test function + """ + logger = params['logger'] + guestname = params['guestname'] + flag = 0 + + conn = sharedmod.libvirtobj['conn'] + + domobj = conn.lookupByName(guestname) + + # Check domain block status + if check_guest_status(domobj): + pass + else: + domobj.create() + time.sleep(90) + + try: + xml = domobj.XMLDesc(0) + doc = libxml2.parseDoc(xml) + cont = doc.xpathNewContext() + vdevs = cont.xpathEval("/domain/devices/disk/target/@dev") + vdev = vdevs[0].content + + logger.info("start to test block_peek.") + logger.info("get the MBR's last byte of domain %s %s is:" + % (guestname, vdev)) + + last_byte = domobj.blockPeek(vdev, 511, 1, flag) + logger.info(last_byte) + + # compare with '\xaa' + if last_byte == '\xaa': + logger.info("Pass: the last byte is \\xaa") + else: + logger.error("Failed: the last byte is not \\xaa") + logger.error("please make sure the guest is bootable") + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" + % (e.message, e.get_error_code())) + return 1 + + return 0 diff --git a/repos/domain/block_resize.py b/repos/domain/block_resize.py new file mode 100644 index 0000000..6070c22 --- /dev/null +++ b/repos/domain/block_resize.py @@ -0,0 +1,94 @@ +#!/usr/bin/evn python +# To test domain block device resize + +import time +import libxml2 +import libvirt +from libvirt import libvirtError + +from src import sharedmod +from utils import utils + +required_params = ('guestname', 'disksize',) +optional_params = {} + +def check_guest_status(domobj): + """Check guest current status""" + state = domobj.info()[0] + if state == libvirt.VIR_DOMAIN_SHUTOFF or \ + state == libvirt.VIR_DOMAIN_SHUTDOWN: + # add check function + return False + else: + return True + +def block_resize(params): + """domain block resize test function + """ + logger = params['logger'] + guestname = params['guestname'] + disksize = params['disksize'] + flag = 0 + + out = utils.get_capacity_suffix_size(disksize) + if len(out) == 0: + logger.error("disksize parse error: \'%s\'" % disksize) + logger.error("disksize should be a number with capacity suffix") + return 1 + + if out['suffix'] == 'K': + flag = 0 + disksize = long(out['capacity']) + elif out['suffix'] == 'B': + flag = 1 + disksize = long(out['capacity_byte']) + elif out['suffix'] == 'M': + flag = 0 + disksize = long(out['capacity']) * 1024 + elif out['suffix'] == 'G': + flag = 0 + disksize = long(out['capacity']) * 1024 * 1024 + else: + logger.error("disksize parse error: with a unsupported suffix \'%s\'" + % out['suffix']) + logger.error("the available disksize suffix of block_resize is: ") + logger.error("B, K, M, G, T") + return 1 + + conn = sharedmod.libvirtobj['conn'] + + domobj = conn.lookupByName(guestname) + + xml = domobj.XMLDesc(0) + doc = libxml2.parseDoc(xml) + cont = doc.xpathNewContext() + vdevs = cont.xpathEval("/domain/devices/disk/source/@file") + diskpath = vdevs[0].content + logger.info("the disk is %s" % diskpath) + + # Check domain block status + if check_guest_status(domobj): + pass + else: + domobj.create() + time.sleep(90) + + try: + logger.info("resize domain disk to %s" % disksize) + domobj.blockResize(diskpath, disksize, flag) + + # Currently, the units of disksize which get from blockInfo is byte. + block_info = domobj.blockInfo(diskpath, 0) + + if block_info[0] == disksize * (1 + 1023 * (1 - flag)): + logger.info("domain disk resize success") + else: + logger.error("error: domain disk change into %s" % block_info[0]) + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" + % (e.message, e.get_error_code())) + return 1 + + return 0 diff --git a/repos/domain/domain_blkio.py b/repos/domain/domain_blkio.py new file mode 100644 index 0000000..f1c637d --- /dev/null +++ b/repos/domain/domain_blkio.py @@ -0,0 +1,163 @@ +#!/usr/bin/evn python +# To test domain blkio parameters + +import os +import time +import libxml2 +import libvirt +import commands +from libvirt import libvirtError + +from src import sharedmod + +CGROUP_PATH = "/cgroup" +BLKIO_PATH1 = "%s/blkio/libvirt/qemu/%s" +BLKIO_PATH2 = "/sys/fs%s/blkio/machine/%s.libvirt-qemu" +GET_PARTITION = "df -P %s | tail -1 | awk {'print $1'}" + +required_params = ('guestname', 'weight',) +optional_params = {} + +def get_output(command, logger): + """execute shell command + """ + status, ret = commands.getstatusoutput(command) + if status: + logger.error("executing "+ "\"" + command + "\"" + " failed") + logger.error(ret) + return status, ret + +def get_device(domobj, logger): + """get the disk device which domain image stored in + """ + xml = domobj.XMLDesc(0) + doc = libxml2.parseDoc(xml) + cont = doc.xpathNewContext() + devs = cont.xpathEval("/domain/devices/disk/source/@file") + image_file = devs[0].content + + status, output = get_output(GET_PARTITION % image_file, logger) + if not status: + return output[:-1] + else: + logger.error("get device error: ") + logger.error(GET_PARTITION % image_file) + return "" + +def check_blkio_paras(domain_blkio_path, domainname, blkio_paras, logger): + """check blkio parameters according to cgroup filesystem + """ + logger.info("checking blkio parameters from cgroup") + if 'weight' in blkio_paras: + expected_weight = blkio_paras['weight'] + status, output = get_output("cat %s/blkio.weight" + % domain_blkio_path, logger) + if not status: + logger.info("%s/blkio.weight is \"%s\"" + % (domain_blkio_path, output)) + else: + return 1 + + if int(output) == expected_weight: + logger.info("the weight matches with cgroup blkio.weight") + return 0 + else: + logger.error("the weight mismatches with cgroup blkio.weight") + return 1 + + if 'device_weight' in blkio_paras: + expected_device_weight = blkio_paras['device_weight'] + status, output = get_output("cat %s/blkio.weight_device" + % domain_blkio_path, logger) + if not status: + logger.info("%s/blkio.weight_device is \"%s\"" + % (domain_blkio_path, output)) + else: + return 1 + + if output.split(' ')[1] == expected_device_weight.split(',')[1]: + logger.info("the device_weight matches with cgroup \ + blkio.weight_device") + return 0 + else: + logger.error("the device_weight mismatches with cgroup \ + blkio.weight_device") + return 1 + + return 0 + +def check_guest_status(domobj): + """Check guest current status""" + state = domobj.info()[0] + if state == libvirt.VIR_DOMAIN_SHUTOFF or \ + state == libvirt.VIR_DOMAIN_SHUTDOWN: + # add check function + return False + else: + return True + +def domain_blkio(params): + """domain blkio parameters test function""" + logger = params['logger'] + guestname = params['guestname'] + expected_weight = params['weight'] + flag = 0 + + conn = sharedmod.libvirtobj['conn'] + + domobj = conn.lookupByName(guestname) + + # Check domain block status + if check_guest_status(domobj): + pass + else: + domobj.create() + time.sleep(90) + + if os.path.exists(CGROUP_PATH): + blkio_path = BLKIO_PATH1 % (CGROUP_PATH, guestname) + else: + blkio_path = BLKIO_PATH2 % (CGROUP_PATH, guestname) + + try: + blkio_paras = domobj.blkioParameters(flag) + + logger.info("the blkio weight of %s is: %d" + % (guestname, blkio_paras['weight'])) + + status = check_blkio_paras(blkio_path, guestname, blkio_paras, + logger) + if status != 0: + return 1 + + logger.info("start to set param weight to %s" % expected_weight) + blkio_paras = {'weight':int(expected_weight)} + status = domobj.setBlkioParameters(blkio_paras, flag) + if status != 0: + return 1 + + status = check_blkio_paras(blkio_path, guestname, blkio_paras, + logger) + if status != 0: + return 1 + + device = get_device(domobj, logger) + device_weight = "%s,%s" % (device, expected_weight) + logger.info("start to set param device_weight to %s" + % device_weight) + blkio_paras = {'device_weight':device_weight} + status = domobj.setBlkioParameters(blkio_paras, flag) + if status != 0: + return 1 + + status = check_blkio_paras(blkio_path, guestname, blkio_paras, + logger) + if status != 0: + return 1 + + except libvirtError, e: + logger.error("API error message: %s, error code is %s" + % (e.message, e.get_error_code())) + return 1 + + return 0 -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list