Skip to content

block_check_memory_leak:add overflow test #4287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 105 additions & 33 deletions qemu/tests/block_check_memory_leak.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -19,20 +19,25 @@ 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.
:param params: Dictionary with the test parameters.
: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"]
Expand All @@ -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)
53 changes: 40 additions & 13 deletions qemu/tests/cfg/block_check_memory_leak.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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