diff --git a/qemu/tests/block_check_memory_leak.py b/qemu/tests/block_check_memory_leak.py index 5c48850b7a..cec674e37b 100644 --- a/qemu/tests/block_check_memory_leak.py +++ b/qemu/tests/block_check_memory_leak.py @@ -5,7 +5,7 @@ import time from avocado.utils import process -from virttest import arch, error_context +from virttest import arch, env_process, error_context from virttest import data_dir as virttest_data_dir from virttest.utils_misc import get_linux_drive_path @@ -19,7 +19,7 @@ def run(test, params, env): 2) Execute IO on multi disks 3) Wait the IO doing in minutes. 4) Destroy the VM. - 5) Check leak info in valgrind log . + 5) Check leak or overflow info in valgrind log . :param test: QEMU test object. @@ -27,12 +27,17 @@ def run(test, params, env): :param env: Dictionary with test environment. """ - def _execute_io_in_guest(): + def _execute_io_in_guest(serial=None): devs = "" - for serial in data_images: + if serial: drive = get_linux_drive_path(session, serial) if drive: devs += drive.replace("/dev/", "") + " " + else: + for serial in data_images: + drive = get_linux_drive_path(session, serial) + if drive: + devs += drive.replace("/dev/", "") + " " guest_io_cmd = params["guest_io_cmd"] % devs host_script = params["host_script"] @@ -43,40 +48,107 @@ def _execute_io_in_guest(): logger.info("Execute io:%s", guest_io_cmd) session.sendline("$SHELL " + guest_io_cmd) + def _get_scsi_debug_disk(): + output = ( + process.system_output( + "lsscsi -giss|grep scsi_debug", shell=True, ignore_status=True + ) + .decode() + .strip() + ) + test.log.info("Host cmd output '%s'", output) + disk_info = [] + if len(output) < 10: + test.log.warning("Can not find scsi_debug disk") + return + + output = output.split("\n") + for disk in output: + info = disk.split() + disk_dic = { + "path": info[5], + "wwn": info[6], + "sg": info[7], + "size": info[8], + "all": disk, + } + disk_info.append(disk_dic) + + test.log.info(disk_info) + return disk_info + if arch.ARCH in ("ppc64", "ppc64le"): - output = process.system_output("lscfg --list firmware -v", shell=True).decode() - ver = float(re.findall(r"\d\.\d", output)[0]) + out = process.system_output("lscfg --list firmware -v", shell=True).decode() + ver = float(re.findall(r"\d\.\d", out)[0]) if ver >= 6.3: # bz2235228,cancel test due to known product bug. test.cancel( "Skip test for xive kvm interrupt guest due to" " known host crash issue." ) + logger = test.log - data_images = params["data_images"].split() - error_context.context("Get the main VM", logger.info) - vm = env.get_vm(params["main_vm"]) - vm.verify_alive() - - timeout = params.get_numeric("login_timeout", 360) - session = vm.wait_for_login(timeout=timeout) - time.sleep(60) - logger.info("Start to IO in guest") - _execute_io_in_guest() - logger.info("Wait ...") - time.sleep(params.get_numeric("io_timeout", 300)) - - logger.info("Try to cancel IO.") - session = vm.wait_for_login(timeout=timeout) - session.cmd(params["guest_cancel_io_cmd"], timeout=timeout) - logger.info("Ready to destroy vm") - vm.destroy() - logger.info("Ready to check vm...") - cp_cmd = "cp %s %s" % (params["valgrind_log"], test.logdir) - process.system_output(cp_cmd, shell=True) - check_cmd = params["check_cmd"] - out = process.system_output(check_cmd, shell=True).decode() - leak_threshold = params.get_numeric("leak_threshold") - logger.info("Find leak:%s,threshold: %d", out, leak_threshold) - if len(out) and int(out) > leak_threshold: - test.fail("Find memory leak %s,Please check valgrind.log" % out) + + vm = None + disk_wwn = None + if params.get("get_scsi_device") == "yes": + scsi_debug_devs = _get_scsi_debug_disk() + if scsi_debug_devs: + dev = scsi_debug_devs[0] + disk_wwn = dev["wwn"] + if params["drive_format_stg1"] == "scsi-generic": + params["image_name_stg1"] = dev["sg"] + else: + params["image_name_stg1"] = dev["path"] + else: + test.fail("Can not find scsi_debug devices") + try: + if params.get("not_preprocess", "no") == "yes": + logger.debug("Ready boot VM : %s", params["images"]) + env_process.process( + test, + params, + env, + env_process.preprocess_image, + env_process.preprocess_vm, + ) + + data_images = params["data_images"].split() + error_context.context("Get the main VM", logger.info) + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + timeout = params.get_numeric("login_timeout", 360) + session = vm.wait_for_login(timeout=timeout) + time.sleep(params.get_numeric("vm_boot_timeout", 60)) + logger.info("Start to IO in guest") + _execute_io_in_guest(disk_wwn) + logger.info("Wait ...") + time.sleep(params.get_numeric("io_timeout", 300)) + + logger.info("Try to cancel IO.") + session = vm.wait_for_login(timeout=timeout) + session.cmd(params["guest_cancel_io_cmd"], timeout=timeout) + logger.info("Ready to destroy vm") + vm.destroy() + logger.info("Ready to check vm...") + cp_cmd = "cp %s %s" % (params["valgrind_log"], test.logdir) + process.system_output(cp_cmd, shell=True) + if params.get("leak_check", "yes") == "yes": + check_cmd = params["leak_check_cmd"] + out = process.system_output(check_cmd, shell=True).decode() + leak_threshold = params.get_numeric("leak_threshold") + logger.info("Find leak:%s,threshold: %d", out, leak_threshold) + if len(out) and int(out) > leak_threshold: + test.fail("Find memory leak %s,Please check valgrind.log" % out) + + if params.get("overflow_check", "yes") == "yes": + check_cmd = params["overflow_check_cmd"] + out = process.system_output( + check_cmd, shell=True, ignore_status=True + ).decode() + if out and len(out): + test.fail("Find overflow %s,Please check valgrind.log" % out) + finally: + if vm and vm.is_alive(): + vm.destroy(gracefully=False) diff --git a/qemu/tests/cfg/block_check_memory_leak.cfg b/qemu/tests/cfg/block_check_memory_leak.cfg index 89e7e15b39..8af4509758 100644 --- a/qemu/tests/cfg/block_check_memory_leak.cfg +++ b/qemu/tests/cfg/block_check_memory_leak.cfg @@ -3,11 +3,12 @@ type = block_check_memory_leak kill_timeout = 300 vm_create_timeout = 360 - io_timeout = 600 + vm_boot_timeout = 60 + io_timeout = 180 login_timeout = 1600 valgrind_log = /tmp/valgrind.log - pre_command = "if ! which valgrind;then yum install -y valgrind; fi;which valgrind" - qemu_command_prefix = "valgrind --trace-children=yes --track-origins=yes --leak-check=full " + pre_command = "if ! which valgrind;then yum install -y valgrind; fi;which valgrind;" + qemu_command_prefix = "valgrind -s --trace-children=yes --track-origins=yes --leak-check=full " qemu_command_prefix += " --show-leak-kinds=definite --log-file=${valgrind_log} " qemu_sandbox = mem_devs = @@ -36,20 +37,46 @@ image_format_stg3 = raw drive_format_stg4 = virtio image_format_stg4 = qcow2 - force_create_image_stg1 = yes - force_create_image_stg2 = yes - force_create_image_stg3 = yes - force_create_image_stg4 = yes - blk_extra_params_stg1 = "serial=${image_stg1}" - blk_extra_params_stg2 = "serial=${image_stg2}" - blk_extra_params_stg3 = "serial=${image_stg3}" - blk_extra_params_stg4 = "serial=${image_stg4}" guest_dir = /home name_script = guest_fio_on_disks.sh host_script = block_device/${name_script} - guest_io_cmd = "${guest_dir}/${name_script} -n 10 -s 10g -d '%s'" + leak_check = yes + overflow_check = yes guest_cancel_io_cmd = "cat /tmp/mpid|xargs kill -SIGINT;pgrep fio|xargs kill -9;sleep 2" - check_cmd = "cat ${valgrind_log}|grep -a "definitely lost:"|tail -n 1|awk '{print $4}'|tr -d ','" + leak_check_cmd = "cat ${valgrind_log}|grep -a "definitely lost:"|tail -n 1|awk '{print $4}'|tr -d ','" leak_threshold = 0 + overflow_check_cmd = "cat ${valgrind_log}|grep -E 'Invalid (write|read)'" arm64-pci, arm64-mmio: leak_threshold = 1000 + variants: + - with_normal: + guest_operation = boot_test + blk_extra_params_stg1 = "serial=${image_stg1}" + blk_extra_params_stg2 = "serial=${image_stg2}" + blk_extra_params_stg3 = "serial=${image_stg3}" + blk_extra_params_stg4 = "serial=${image_stg4}" + force_create_image_stg1 = yes + force_create_image_stg2 = yes + force_create_image_stg3 = yes + force_create_image_stg4 = yes + guest_io_cmd = "${guest_dir}/${name_script} -n 10 -s 10g -d '%s'" + - with_pass_through: + not_preprocess = yes + get_scsi_device = yes + data_images = "${image_stg1}" + images = "image1 ${data_images}" + image_format_stg1 = raw + image_raw_device_stg1 = yes + image_name_stg1 = TBD + vm_boot_timeout = 30 + io_timeout = 60 + guest_io_cmd = "${guest_dir}/${name_script} -n 10 -s 500M -d '%s'" + disk_size = 576 + pre_command += "modprobe -r scsi_debug; modprobe scsi_debug dev_size_mb=${disk_size};" + post_command += "modprobe -r scsi_debug;" + variants: + - with_block: + drive_format_stg1 = scsi-block + - with_generic: + drive_format_stg1 = scsi-generic + drive_cache_stg1 = writethrough