Exemple #1
0
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()