def run(test, params, env): """ Test if VM paused when image NFS shutdown, the drive option 'werror' should be stop, the drive option 'cache' should be none. 1) Setup NFS service on host 2) Boot up a VM using another disk on NFS server and write the disk by dd 3) Check if VM status is 'running' 4) Reject NFS connection on host 5) Check if VM status is 'paused' 6) Accept NFS connection on host and continue VM by monitor command 7) Check if VM status is 'running' :param test: kvm test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_nfs_devname(params, session): """ Get the possbile name of nfs storage dev name in guest. :param params: Test params dictionary. :param session: An SSH session object. """ image1_type = params.object_params("image1").get("drive_format") stg_type = params.object_params("stg").get("drive_format") cmd = "" # Seems we can get correct 'stg' devname even if the 'stg' image # has a different type from main image (we call it 'image1' in # config file) with these 'if' sentences. if image1_type == stg_type: cmd = "ls /dev/[hsv]d[a-z]" elif stg_type == "virtio": cmd = "ls /dev/vd[a-z]" else: cmd = "ls /dev/[sh]d[a-z]" cmd += " | tail -n 1" return session.cmd_output(cmd).rstrip() def check_vm_status(vm, status): """ Check if VM has the given status or not. :param vm: VM object. :param status: String with desired status. :return: True if VM status matches our desired status. :return: False if VM status does not match our desired status. """ try: vm.verify_status(status) except (virt_vm.VMStatusError, qemu_monitor.MonitorLockError): return False else: return True error_context.context("Setup NFS Server on local host", logging.info) host_ip = utils_net.get_host_ip_address(params) try: config = NFSCorruptConfig(test, params, host_ip) config.setup() except NFSCorruptError as e: test.error(str(e)) image_stg_dir = config.mnt_dir stg_params = params.object_params("stg") stg_img = QemuImg(stg_params, image_stg_dir, "stg") stg_img.create(stg_params) error_context.context("Boot vm with image on NFS server", logging.info) image_name = os.path.join(image_stg_dir, "nfs_corrupt") params["image_name_stg"] = image_name vm = env.get_vm(params["main_vm"]) try: vm.create(params=params) except Exception: stg_img.remove() config.cleanup() test.error("failed to create VM") session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) nfs_devname = get_nfs_devname(params, session) # Write disk on NFS server error_context.context("Write disk that image on NFS", logging.info) write_disk_cmd = "dd if=/dev/zero of=%s oflag=direct" % nfs_devname logging.info("dd with command: %s", write_disk_cmd) session.sendline(write_disk_cmd) try: # Read some command output, it will timeout session.read_up_to_prompt(timeout=30) except Exception: pass try: error_context.context("Make sure guest is running before test", logging.info) vm.resume() vm.verify_status("running") try: error_context.context("Reject NFS connection on host", logging.info) process.system(config.iptables_rule_gen('A')) error_context.context("Check if VM status is 'paused'", logging.info) if not utils_misc.wait_for( lambda: check_vm_status(vm, "paused"), int(params.get('wait_paused_timeout', 240))): test.error("Guest is not paused after stop NFS") finally: error_context.context("Accept NFS connection on host", logging.info) process.system(config.iptables_rule_gen('D')) error_context.context("Ensure nfs is resumed", logging.info) nfs_resume_timeout = int(params.get('nfs_resume_timeout', 240)) if not utils_misc.wait_for(config.is_mounted_dir_acessible, nfs_resume_timeout): test.error("NFS connection does not resume") error_context.context("Continue guest", logging.info) vm.resume() error_context.context("Check if VM status is 'running'", logging.info) if not utils_misc.wait_for(lambda: check_vm_status(vm, "running"), 20): test.error("Guest does not restore to 'running' status") finally: session.close() vm.destroy(gracefully=True) stg_img.check_image(params, image_stg_dir) stg_img.remove() config.cleanup()