diff --git a/generic/tests/cfg/block_hotplug.cfg b/generic/tests/cfg/block_hotplug.cfg index d3d4e76fda196db651a6db7eadc82a9eb4912e6e..a93ea527db8d627397fc8a5a3789c02f01c67ebc 100644 --- a/generic/tests/cfg/block_hotplug.cfg +++ b/generic/tests/cfg/block_hotplug.cfg @@ -2,47 +2,84 @@ no RHEL.3.9 no ide virt_test_type = qemu libvirt - type = pci_hotplug - pci_type = block - reference_cmd = lspci - find_pci_cmd = lspci + type = block_hotplug images += " stg0" boot_drive_stg0 = no image_name_stg0 = images/storage0 image_size_stg0 = 1G remove_image_stg0 = yes force_create_image_stg0 = yes - pci_test_cmd = "echo %s; yes | mke2fs `fdisk -l 2>&1 | awk '/\/dev\/[sv]d[a-z]* doesn/ {print $2}'` | sort | tail -1" - wait_secs_for_hook_up = 3 + get_disk_cmd = "ls /dev/[hsv]d[a-z]* | sort" + pci_test_cmd = "dd if=%s of=/dev/null bs=1k count=1000 iflag=direct &&" + pci_test_cmd += " dd if=/dev/zero of=%s bs=1k count=1000 oflag=direct" kill_vm_on_error = yes - variants: - - fmt_qcow2: - image_extra_params = "" - image_format_stg = qcow2 - image_format_stg0 = qcow2 - image_format_stg1 = qcow2 - - fmt_raw: - image_extra_params = "" - image_format_stg = raw - image_format_stg0 = raw - image_format_stg1 = raw + variants: - one_pci: - pci_num = 1 + blk_num = 1 repeat_times = 300 - multi_pci: - pci_num = 2 - repeat_times = 2 + blk_num = 2 + repeat_times = 3 images += " stg1" boot_drive_stg1 = no image_name_stg1 = images/storage1 image_size_stg1 = 1G remove_image_stg1 = yes force_create_image_stg1 = yes + + variants: + - @default: + - with_reboot: + sub_type_after_unplug = boot + reboot_method = shell + - with_shutdown: + sub_type_after_unplug = shutdown + shutdown_method = shell + check_img = yes + repeat_times = 1 + - with_stop_continue: + sub_type_after_plug = stop_continue + sub_type_after_unplug = stop_continue + - with_system_reset: + sub_type_after_plug = boot + sub_type_after_unplug = boot + reboot_method = system_reset + + variants: + - with_plug: + need_plug = yes + - without_plug: + repeat_times = 1 + boot_drive_stg0 = yes + boot_drive_stg1 = yes + need_plug = no + + variants: + - fmt_qcow2: + image_extra_params = "" + img_format_type = qcow2 + image_format_stg0 = qcow2 + image_format_stg1 = qcow2 + - fmt_raw: + image_extra_params = "" + img_format_type = raw + image_format_stg0 = raw + image_format_stg1 = raw + variants: - block_virtio: - pci_model = virtio - match_string = "Virtio block device" + pci_type = virtio-blk-pci + drive_format_stg0 = virtio + drive_format_stg1 = virtio + get_disk_pattern = "^/dev/vd[a-z]*$" + virtio_blk: + no ppc64 ppc64le - block_scsi: - pci_model = scsi - match_string = "LSI Logic" + pci_type = scsi-hd + drive_format_stg0 = scsi-hd + drive_format_stg1 = scsi-hd + get_disk_pattern = "^/dev/sd[a-z]*$" + virtio_blk: + need_controller = yes + controller_model = virtio-scsi-pci diff --git a/qemu/tests/block_hotplug.py b/qemu/tests/block_hotplug.py new file mode 100644 index 0000000000000000000000000000000000000000..c89ece55931f6a59ce1b396d42a497c4f6181776 --- /dev/null +++ b/qemu/tests/block_hotplug.py @@ -0,0 +1,167 @@ +import logging +import re +import time + +from virttest import data_dir +from virttest import storage +from virttest import error_context +from virttest import utils_test +from virttest.qemu_devices import qdevices + +from avocado.core import exceptions + + +@error_context.context_aware +def run(test, params, env): + """ + Test hotplug of block devices. + + 1) Boot up guest with/without block device(s). + 2) Hoplug block device and verify + 3) Do read/write data on hotplug block. + 4) Unplug block device and verify + + :param test: QEMU test object. + :param params: Dictionary with the test parameters. + :param env: Dictionary with test environment. + """ + def find_image(image_name): + """ + Find the path of the iamge. + """ + image_params = params.object_params(image_name) + o = storage.get_image_filename(image_params, data_dir.get_data_dir()) + return o + + def find_disk(session, cmd): + """ + Find all disks in guest. + """ + if params.get("os_type") == "linux": + pattern = params.get("get_disk_pattern", "^/dev/vd[a-z]*$") + else: + pattern = "^\d+" + cmd = params.get("get_disk_index", "wmic diskdrive get index") + + output = session.cmd_output_safe(cmd) + disks = re.findall(pattern, output, re.M) + return disks + + def get_new_disk(disk1, disk2): + """ + Get the different disk between disk1 and disk2. + """ + disk = list(set(disk2).difference(set(disk1))) + return disk + + img_list = params.get("images").split() + img_format_type = params.get("img_format_type", "qcow2") + pci_type = params.get("pci_type", "virtio-blk-pci") + pause = float(params.get("virtio_block_pause", 5.0)) + blk_num = int(params.get("blk_num", 1)) + repeat_times = int(params.get("repeat_times", 3)) + timeout = int(params.get("login_timeout", 360)) + disk_op_timeout = int(params.get("disk_op_timeout", 360)) + get_disk_cmd = params.get("get_disk_cmd") + context_msg = "Running sub test '%s' %s" + device_list = [] + + vm = env.get_vm(params["main_vm"]) + vm.verify_alive() + + for i in xrange(repeat_times): + error_context.context("Hotplug block device (iteration %d)" % i, + logging.info) + + session = vm.wait_for_login(timeout=timeout) + + sub_type = params.get("sub_type_before_plug") + if sub_type: + error_context.context(context_msg % (sub_type, "before hotplug"), + logging.info) + utils_test.run_virt_sub_test(test, params, env, sub_type) + + for num in xrange(blk_num): + device = qdevices.QDevice(pci_type) + if params.get("need_plug") == "yes": + if params.get("need_controller", "no") == "yes": + controller_model = params.get("controller_model") + controller = qdevices.QDevice(controller_model) + controller.hotplug(vm.monitor) + ver_out = controller.verify_hotplug("", vm.monitor) + if not ver_out: + err = "%s is not in qtree after hotplug" % controller_model + raise exceptions.TestFail(err) + + disks_before_plug = find_disk(session, get_disk_cmd) + + drive = qdevices.QRHDrive("block%d" % num) + drive.set_param("file", find_image(img_list[num + 1])) + drive.set_param("format", img_format_type) + drive_id = drive.get_param("id") + drive.hotplug(vm.monitor) + + device.set_param("drive", drive_id) + device.set_param("id", "block%d" % num) + device.hotplug(vm.monitor) + ver_out = device.verify_hotplug("", vm.monitor) + if not ver_out: + err = "%s is not in qtree after hotplug" % pci_type + raise exceptions.TestFail(err) + time.sleep(pause) + + disks_after_plug = find_disk(session, get_disk_cmd) + new_disks = get_new_disk(disks_before_plug, disks_after_plug) + else: + if params.get("drive_format") in pci_type: + get_disk_cmd += " | egrep -v '^/dev/[hsv]da[0-9]*$'" + + device.set_param("id", img_list[num + 1]) + new_disks = find_disk(session, get_disk_cmd) + + device_list.append(device) + if not new_disks: + raise exceptions.TestFail("Cannot find new disk after hotplug.") + + if params.get("need_plug") == "yes": + disk = new_disks[0] + else: + disk = new_disks[num] + + error_context.context("Check block device after hotplug.", + logging.info) + if params.get("pci_test_cmd"): + if params.get("os_type") == "linux": + test_cmd = params.get("pci_test_cmd") % (disk, disk) + else: + test_cmd = re.sub("PCI_NUM", "%s" % (num + 1), + params.get("pci_test_cmd")) + s, o = session.cmd_status_output(test_cmd, timeout=disk_op_timeout) + if s: + raise exceptions.TestFail("Check for block device failed " + "after hotplug, Output: %r" % o) + + sub_type = params.get("sub_type_after_plug") + if sub_type: + error_context.context(context_msg % (sub_type, "after hotplug"), + logging.info) + utils_test.run_virt_sub_test(test, params, env, sub_type) + + sub_type = params.get("sub_type_before_unplug") + if sub_type: + error_context.context(context_msg % (sub_type, "before unplug"), + logging.info) + utils_test.run_virt_sub_test(test, params, env, sub_type) + + for num in xrange(blk_num): + error_context.context("Unplug block device (iteration %d)" % i, + logging.info) + device_list[num].unplug(vm.monitor) + device_list[num].verify_unplug("", vm.monitor) + time.sleep(pause) + + sub_type = params.get("sub_type_after_unplug") + if sub_type: + error_context.context(context_msg % (sub_type, "after unplug"), + logging.info) + utils_test.run_virt_sub_test(test, params, env, sub_type)