def _initial_win_drives():
     size = params['stg_image_size']
     disks = utils_disk.get_windows_disks_index(session, size)
     if not utils_disk.update_windows_disk_attributes(session, disks):
         test.fail("Failed to update windows disk attributes.")
     for disk in disks[1:24]:
         yield utils_disk.configure_empty_windows_disk(session, disk, size)[0]
Example #2
0
def check_data_disks(test, params, env, vm, session):
    """
    Check guest data disks (except image1)

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    :param vm: VM object
    :param session: VM session
    """
    image_list = params.objects("images")
    del image_list[0]
    image_num = len(image_list)

    error_context.context("Check data disks in monitor!", logging.info)
    monitor_info_block = vm.monitor.info_block(False)
    blocks = ','.join(monitor_info_block.keys())
    for image in image_list:
        if image not in blocks:
            test.fail("drive_%s is missed: %s!" % (image, blocks))

    error_context.context("Read and write on data disks!", logging.info)
    os_type = params["os_type"]
    if os_type == "linux":
        sub_test_type = params.get("sub_test_type", "dd_test")
        for image in image_list:
            params["dd_if"] = "ZERO"
            params["dd_of"] = image
            utils_test.run_virt_sub_test(test, params, env, sub_test_type)

            params["dd_if"] = image
            params["dd_of"] = "NULL"
            utils_test.run_virt_sub_test(test, params, env, sub_test_type)
    elif os_type == "windows":
        iozone_cmd = params["iozone_cmd"]
        iozone_cmd = utils_misc.set_winutils_letter(session, iozone_cmd)
        data_image_size = params["data_image_size"]
        disks = utils_disk.get_windows_disks_index(session, data_image_size)
        disk_num = len(disks)
        if disk_num < image_num:
            err_msg = "set disk num: %d" % image_num
            err_msg += ", get in guest: %d" % disk_num
            test.fail("Fail to list all the volumes, %s" % err_msg)
        if not utils_disk.update_windows_disk_attributes(session, disks):
            test.fail("Failed to update windows disk attributes.")
        for disk in disks:
            drive_letter = utils_disk.configure_empty_disk(
                session, disk, data_image_size, os_type)
            if not drive_letter:
                test.fail("Fail to format disks.")
            iozone_cmd_disk = iozone_cmd % drive_letter[0]
            status, output = session.cmd_status_output(iozone_cmd_disk,
                                                       timeout=3600)
            if status:
                test.fail("Check block device '%s' failed! Output: %s" %
                          (drive_letter[0], output))
            utils_disk.clean_partition(session, disk, os_type)
    else:
        test.cancel("Unsupported OS type '%s'" % os_type)
Example #3
0
    def _format_tmpfs_disk():
        """
        Format the new tmpfs disk in guest

        return: the formatted drive letter of the disk
        """
        logging.info("Boot the guest to setup tmpfs disk")
        vm, session = _boot_guest_with_cpu_flag(cpu_model_flags)
        logging.info("Format tmpfs disk")
        disk_size = params["image_size_" + params["tmpfs_image_name"]]
        disk_id = utils_disk.get_windows_disks_index(session, disk_size)[0]
        drive_letter = utils_disk.configure_empty_windows_disk(
            session, disk_id, disk_size)[0]
        vm.graceful_shutdown(timeout=timeout)
        return drive_letter
Example #4
0
 def _get_mount_points():
     """ Get data disk mount point(s) """
     mount_points = []
     os_type = params["os_type"]
     if os_type == "linux":
         mounts = session.cmd_output_safe('cat /proc/mounts | grep /dev/')
         for img in image_list:
             size = params["image_size_%s" % img]
             img_param = params["blk_extra_params_%s" % img].split('=')[1]
             drive_path = utils_misc.get_linux_drive_path(
                 session, img_param)
             if not drive_path:
                 test.error("Failed to get drive path of '%s'" % img)
             did = drive_path[5:]
             for mp in re.finditer(r'/dev/%s\d+\s+(\S+)\s+' % did, mounts):
                 mount_points.append(mp.group(1))
             else:
                 mp = utils_disk.configure_empty_linux_disk(
                     session, did, size)
                 mount_points.extend(mp)
     elif os_type == "windows":
         size_record = []
         for img in image_list:
             size = params["image_size_%s" % img]
             if size in size_record:
                 continue
             size_record.append(size)
             disks = utils_disk.get_windows_disks_index(session, size)
             if not disks:
                 test.fail("Fail to list image %s" % img)
             if not utils_disk.update_windows_disk_attributes(
                     session, disks):
                 test.fail("Failed to update windows disk attributes")
             for disk in disks:
                 d_letter = utils_disk.configure_empty_windows_disk(
                     session, disk, size)
             if not d_letter:
                 test.fail("Fail to format disks")
             mount_points.extend(d_letter)
     else:
         test.cancel("Unsupported OS type '%s'" % os_type)
     return mount_points
Example #5
0
 def configure_data_disk(self):
     os_type = self.params["os_type"]
     disk_params = self.params.object_params(self.snapshot_tag)
     disk_size = disk_params["image_size"]
     session = self.main_vm.wait_for_login()
     try:
         if os_type != "windows":
             disk_id = self.get_linux_disk_path(session, disk_size)
             assert disk_id, "Disk not found in guest!"
             mount_point = utils_disk.configure_empty_linux_disk(
                 session, disk_id, disk_size)[0]
             self.disks_info.append([r"/dev/%s1" % disk_id, mount_point])
         else:
             disk_id = utils_disk.get_windows_disks_index(
                 session, disk_size)
             driver_letter = utils_disk.configure_empty_windows_disk(
                 session, disk_id, disk_size)[0]
             mount_point = r"%s:\\" % driver_letter
             self.disks_info.append([disk_id, mount_point])
     finally:
         session.close()
 def get_disk_op_cmd(disk_op_cmd, disk_size):
     """
     Find the disk driver letter and format the disk, and get
     disk driver letter,return disk_op_command
     """
     if os_type == "windows":
         disk_op_cmd = utils_misc.set_winutils_letter(session, disk_op_cmd)
         logging.info("Get windows disk index that to be formatted")
         disk_id = utils_disk.get_windows_disks_index(session, disk_size)
         if not utils_disk.update_windows_disk_attributes(session, disk_id):
             test.error("Failed to enable data disk %s" % disk_id)
         d_letter = utils_disk.configure_empty_windows_disk(session,
                                                            disk_id[0],
                                                            disk_size)[0]
         output_path = d_letter + ":\\test.dat"
     else:
         disks = utils_disk.get_linux_disks(session)
         for key, value in disks.items():
             if value[1] == disk_size and value[2] == "disk":
                 output_path = key
     if not output_path:
         test.fail("Can not get output file path in guest.")
     disk_op_cmd %= output_path
     return disk_op_cmd
Example #7
0
 def _get_data_disks_win():
     """ Get the data disks in windows. """
     for data_image in params['images'].split()[1:]:
         size = params.object_params(data_image)['image_size']
         yield utils_disk.get_windows_disks_index(session, size)[0], size
Example #8
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params["file_system"].split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    black_list = params["black_list"].split()
    drive_letters = int(params.get("drive_letters", "26"))
    stg_image_size = params["stg_image_size"]
    dd_test = params.get("dd_test", "no")
    pre_command = params.get("pre_command", "")
    labeltype = params.get("labeltype", "gpt")
    iozone_target_num = int(params.get('iozone_target_num', '5'))
    iozone_options = params.get('iozone_options')
    iozone_timeout = float(params.get('iozone_timeout', '7200'))

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying qtree vs."
                      " params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return
    try:
        err_msg = "Set disks num: %d" % stg_image_num
        err_msg += ", Get disks num in guest: %d"
        ostype = params["os_type"]
        if ostype == "windows":
            error_context.context(
                "Get windows disk index that to "
                "be formatted", logging.info)
            disks = utils_disk.get_windows_disks_index(session, stg_image_size)
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
            if len(disks) > drive_letters:
                black_list.extend(utils_misc.get_winutils_vol(session))
                disks = random.sample(disks, drive_letters - len(black_list))
            error_context.context(
                "Clear readonly for all disks and online "
                "them in windows guest.", logging.info)
            if not utils_disk.update_windows_disk_attributes(session, disks):
                test.fail("Failed to update windows disk attributes.")
            dd_test = "no"
        else:
            error_context.context("Get linux disk that to be "
                                  "formatted", logging.info)
            disks = sorted(utils_disk.get_linux_disks(session).keys())
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
    except Exception:
        _do_post_cmd(session)
        raise
    try:
        if iozone_options:
            iozone = generate_instance(params, session, 'iozone')
            random.shuffle(disks)
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            for n, disk in enumerate(disks):
                error_context.context("Format disk in guest: '%s'" % disk,
                                      logging.info)
                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fstype = file_system[index].strip()
                partitions = utils_disk.configure_empty_disk(
                    session,
                    disk,
                    stg_image_size,
                    ostype,
                    fstype=fstype,
                    labeltype=labeltype)
                if not partitions:
                    test.fail("Fail to format disks.")
                cmd_list = params["cmd_list"]
                for partition in partitions:
                    orig_partition = partition
                    if "/" not in partition:
                        partition += ":"
                    else:
                        partition = partition.split("/")[-1]
                    error_context.context(
                        "Copy file into / out of partition:"
                        " %s..." % partition, logging.info)
                    for cmd_l in cmd_list.split():
                        cmd = params.get(cmd_l)
                        if cmd:
                            session.cmd(cmd % partition, timeout=cmd_timeout)
                    cmd = params["compare_command"]
                    key_word = params["check_result_key_word"]
                    output = session.cmd_output(cmd)
                    if iozone_options and n < iozone_target_num:
                        iozone.run(iozone_options.format(orig_partition),
                                   iozone_timeout)
                    if key_word not in output:
                        test.fail("Files on guest os root fs and disk differ")
                    if dd_test != "no":
                        error_context.context(
                            "dd test on partition: %s..." % partition,
                            logging.info)
                        status, output = session.cmd_status_output(
                            dd_test % (partition, partition),
                            timeout=cmd_timeout)
                        if status != 0:
                            test.fail("dd test fail: %s" % output)
                    # When multiple SCSI disks are simulated by scsi_debug,
                    # they could be viewed as multiple paths to the same
                    # storage device. So need umount partition before operate
                    # next disk, in order to avoid corrupting the filesystem
                    # (xfs integrity checks error).
                    if ostype == "linux" and "scsi_debug add_host" in pre_command:
                        status, output = session.cmd_status_output(
                            "umount /dev/%s" % partition, timeout=cmd_timeout)
                        if status != 0:
                            test.fail("Failed to umount partition '%s': %s" %
                                      (partition, output))
            need_reboot = params.get("need_reboot", "no")
            need_shutdown = params.get("need_shutdown", "no")
            if need_reboot == "yes":
                error_context.context("Rebooting guest ...", logging.info)
                session = vm.reboot(session=session, timeout=login_timeout)
            if need_shutdown == "yes":
                error_context.context("Shutting down guest ...", logging.info)
                vm.graceful_shutdown(timeout=login_timeout)
                if vm.is_alive():
                    test.fail("Fail to shut down guest.")
                error_context.context("Start the guest again.", logging.info)
                vm = env.get_vm(params["main_vm"])
                vm.create(params=params)
                session = vm.wait_for_login(timeout=login_timeout)
            error_context.context("Delete partitions in guest.", logging.info)
            for disk in disks:
                utils_disk.clean_partition(session, disk, ostype)
    finally:
        if iozone_options:
            iozone.clean()
        _do_post_cmd(session)
Example #9
0
def run(test, params, env):
    """
    KVM block resize test:

    1) Start guest with data disk or system disk.
    2) Do format disk in guest if needed.
    3) Record md5 of test file on the data disk.
       Enlarge the data disk image from qemu monitor.
    4) Extend data disk partition/file-system in guest.
    5) Verify the data disk size match expected size.
    6) Reboot the guest.
    7) Do iozone test, compare the md5 of test file.
    8) Shrink data disk partition/file-system in guest.
    9) Shrink data disk image from qemu monitor.
    10) Verify the data disk size match expected size.
    11) Reboot the guest.
    12) Do iozone test, compare the md5 of test file.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def verify_disk_size(session, os_type, disk):
        """
        Verify the current block size match with the expected size.
        """
        global current_size
        current_size = utils_disk.get_disk_size(session, os_type, disk)
        accept_ratio = float(params.get("accept_ratio", 0))
        if (current_size <= block_size
                and current_size >= block_size * (1 - accept_ratio)):
            logging.info(
                "Block Resizing Finished !!! \n"
                "Current size %s is same as the expected %s", current_size,
                block_size)
            return True

    def create_md5_file(filename):
        """
        Create the file to verify md5 value.
        """
        logging.debug("create md5 file %s" % filename)
        if os_type == 'windows':
            vm.copy_files_to(params["tmp_md5_file"], filename)
        else:
            session.cmd(params["dd_cmd"] % filename)

    def get_md5_of_file(filename):
        """
        Get the md5 value of filename.
        """
        ex_args = (mpoint, filename) if os_type == 'windows' else filename
        return session.cmd(md5_cmd % ex_args).split()[0]

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    driver_name = params.get("driver_name")
    os_type = params["os_type"]
    fstype = params.get("fstype")
    labeltype = params.get("labeltype", "msdos")
    img_size = params.get("image_size_stg", "10G")
    mpoint = params.get("disk_letter", "C")
    disk = params.get("disk_index", 0)
    md5_cmd = params.get("md5_cmd", "md5sum %s")
    md5_file = params.get("md5_file", "md5.dat")
    data_image = params.get("images").split()[-1]
    data_image_params = params.object_params(data_image)
    data_image_filename = storage.get_image_filename(data_image_params,
                                                     data_dir.get_data_dir())
    data_image_dev = vm.get_block({'file': data_image_filename})
    img = QemuImg(data_image_params, data_dir.get_data_dir(), data_image)
    block_virtual_size = json.loads(img.info(force_share=True,
                                             output="json"))["virtual-size"]

    session = vm.wait_for_login(timeout=timeout)

    if os_type == 'windows' and driver_name:
        session = utils_test.qemu.windrv_check_running_verifier(
            session, vm, test, driver_name, timeout)

    if params.get("format_disk") == "yes":
        if os_type == 'linux':
            disk = sorted(utils_disk.get_linux_disks(session).keys())[0]
        else:
            disk = utils_disk.get_windows_disks_index(session, img_size)[0]
            utils_disk.update_windows_disk_attributes(session, disk)
        error_context.context("Formatting disk", logging.info)
        mpoint = utils_disk.configure_empty_disk(session,
                                                 disk,
                                                 img_size,
                                                 os_type,
                                                 fstype=fstype,
                                                 labeltype=labeltype)[0]
        partition = mpoint.replace('mnt', 'dev') if 'mnt' in mpoint else None

    for ratio in params.objects("disk_change_ratio"):
        block_size = int(int(block_virtual_size) * float(ratio))

        # Record md5
        if params.get('md5_test') == 'yes':
            junction = ":\\" if os_type == 'windows' else "/"
            md5_filename = mpoint + junction + md5_file
            create_md5_file(md5_filename)
            md5 = get_md5_of_file(md5_filename)
            logging.debug("Got md5 %s ratio:%s on %s" % (md5, ratio, disk))

        # We need shrink the disk in guest first, than in monitor
        if float(ratio) < 1.0:
            error_context.context(
                "Shrink disk size to %s in guest" % block_size, logging.info)
            if os_type == 'windows':
                shr_size = utils_numeric.normalize_data_size(
                    str(
                        utils_disk.get_disk_size(session, os_type, disk) -
                        block_size), 'M').split(".")[0]
                drive.shrink_volume(session, mpoint, shr_size)
            else:
                utils_disk.resize_filesystem_linux(session, partition,
                                                   str(block_size))
                utils_disk.resize_partition_linux(session, partition,
                                                  str(block_size))

        error_context.context("Change disk size to %s in monitor" % block_size,
                              logging.info)
        if vm.check_capability(Flags.BLOCKDEV):
            args = (None, block_size, data_image_dev)
        else:
            args = (data_image_dev, block_size)
        vm.monitor.block_resize(*args)

        if params.get("guest_prepare_cmd", ""):
            session.cmd(params.get("guest_prepare_cmd"))
        # Update GPT due to size changed
        if os_type == "linux" and labeltype == "gpt":
            session.cmd("sgdisk -e /dev/%s" % disk)
        if params.get("need_reboot") == "yes":
            session = vm.reboot(session=session)
        if params.get("need_rescan") == "yes":
            drive.rescan_disks(session)

        # We need extend disk in monitor first than extend it in guest
        if float(ratio) > 1.0:
            error_context.context("Extend disk to %s in guest" % block_size,
                                  logging.info)
            if os_type == 'windows':
                drive.extend_volume(session, mpoint)
            else:
                utils_disk.resize_partition_linux(session, partition,
                                                  str(block_size))
                utils_disk.resize_filesystem_linux(session, partition,
                                                   utils_disk.SIZE_AVAILABLE)
        global current_size
        current_size = 0
        if not wait.wait_for(lambda: verify_disk_size(session, os_type, disk),
                             20, 0, 1, "Block Resizing"):
            test.fail("Block size get from guest is not same as expected.\n"
                      "Reported: %s\nExpect: %s\n" %
                      (current_size, block_size))
        session = vm.reboot(session=session)

        if os_type == 'linux':
            if not utils_disk.is_mount(
                    partition, dst=mpoint, fstype=fstype, session=session):
                utils_disk.mount(partition,
                                 mpoint,
                                 fstype=fstype,
                                 session=session)

        if params.get('iozone_test') == 'yes':
            iozone_timeout = float(params.get("iozone_timeout", 1800))
            iozone_cmd_options = params.get("iozone_option") % mpoint
            io_test = generate_instance(params, vm, 'iozone')
            try:
                io_test.run(iozone_cmd_options, iozone_timeout)
            finally:
                io_test.clean()

        # Verify md5
        if params.get('md5_test') == 'yes':
            new_md5 = get_md5_of_file(md5_filename)
            test.assertTrue(new_md5 == md5, "Unmatched md5: %s" % new_md5)

    session.close()
Example #10
0
def run(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest with virtio data disk
    2) Format the disk and copy file to it
    3) Stop the guest and boot up it again with the data disk set to readonly
    4) Try to copy file to the data disk
    5) Try to copy file from the data disk

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    error_context.context(
        "TEST STEPS 1: Try to log into guest.", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 2: Format the disk and copy file to it", logging.info)
    os_type = params["os_type"]
    copy_cmd = params.get("copy_cmd", "copy %s %s")
    fstype = params.get("fstype", "ntfs")
    data_image_size = params.get("image_size_data", "1G")
    data_image_num = int(params.get("data_image_num",
                                    len(params.objects("images")) - 1))
    error_context.context("Get windows disk index that to "
                          "be formatted", logging.info)
    disk_index_list = utils_disk.get_windows_disks_index(session, data_image_size)
    if len(disk_index_list) < data_image_num:
        test.fail("Fail to list all data disks. "
                  "Set disk number: %d, "
                  "get disk number in guest: %d."
                  % (data_image_num, len(disk_index_list)))
    src_file = utils_misc.set_winutils_letter(
        session, params["src_file"], label="WIN_UTILS")
    error_context.context("Clear readonly for all disks and online "
                          "them in guest.", logging.info)
    if not utils_disk.update_windows_disk_attributes(session, disk_index_list):
        test.fail("Failed to update windows disk attributes.")
    error_context.context("Format disk %s in guest." % disk_index_list[0],
                          logging.info)
    drive_letter = utils_disk.configure_empty_disk(
        session, disk_index_list[0], data_image_size, os_type, fstype=fstype)
    if not drive_letter:
        test.fail("Fail to format disks.")
    dst_file = params["dst_file"] % drive_letter[0]
    session.cmd(copy_cmd % (src_file, dst_file))

    msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk"
    msg += " set to readonly"
    error_context.context(msg, logging.info)
    session.close()
    vm.destroy()

    data_img = params.get("images").split()[-1]
    params["image_readonly_%s" % data_img] = "yes"
    params["force_create_image_%s" % data_img] = "no"
    env_process.preprocess(test, params, env)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 4: Write to the readonly disk expect:"
        "The media is write protected", logging.info)
    dst_file_readonly = params["dst_file_readonly"] % drive_letter[0]
    o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly))
    if not o.find("write protect"):
        test.fail("Write in readonly disk should failed\n. {}".format(o))

    error_context.context(
        "TEST STEPS 5: Try to read from the readonly disk", logging.info)
    s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\"))
    if s != 0:
        test.fail("Read file failed\n. {}".format(o))

    session.close()
Example #11
0
def run(test, params, env):
    """
    Test multi disk suport of guest, this case will:
    1) Create disks image in configuration file.
    2) Start the guest with those disks.
    3) Checks qtree vs. test params. (Optional)
    4) Create partition on those disks.
    5) Get disk dev filenames in guest.
    6) Format those disks in guest.
    7) Copy file into / out of those disks.
    8) Compare the original file and the copied file using md5 or fc comand.
    9) Repeat steps 3-5 if needed.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _add_param(name, value):
        """ Converts name+value to stg_params string """
        if value:
            value = re.sub(' ', '\\ ', value)
            return " %s:%s " % (name, value)
        else:
            return ''

    def _do_post_cmd(session):
        cmd = params.get("post_cmd")
        if cmd:
            session.cmd_status_output(cmd)
        session.close()

    error_context.context("Parsing test configuration", logging.info)
    stg_image_num = 0
    stg_params = params.get("stg_params", "")
    # Compatibility
    stg_params += _add_param("image_size", params.get("stg_image_size"))
    stg_params += _add_param("image_format", params.get("stg_image_format"))
    stg_params += _add_param("image_boot", params.get("stg_image_boot", "no"))
    stg_params += _add_param("drive_format", params.get("stg_drive_format"))
    stg_params += _add_param("drive_cache", params.get("stg_drive_cache"))
    if params.get("stg_assign_index") != "no":
        # Assume 0 and 1 are already occupied (hd0 and cdrom)
        stg_params += _add_param("drive_index", 'range(2,n)')
    param_matrix = {}

    stg_params = stg_params.split(' ')
    i = 0
    while i < len(stg_params) - 1:
        if not stg_params[i].strip():
            i += 1
            continue
        if stg_params[i][-1] == '\\':
            stg_params[i] = '%s %s' % (stg_params[i][:-1],
                                       stg_params.pop(i + 1))
        i += 1

    rerange = []
    has_name = False
    for i in range(len(stg_params)):
        if not stg_params[i].strip():
            continue
        (cmd, parm) = stg_params[i].split(':', 1)
        if cmd == "image_name":
            has_name = True
        if _RE_RANGE1.match(parm):
            parm = _range(parm)
            if parm is False:
                test.error("Incorrect cfg: stg_params %s looks "
                           "like range(..) but doesn't contain "
                           "numbers." % cmd)
            param_matrix[cmd] = parm
            if type(parm) is str:
                # When we know the stg_image_num, substitute it.
                rerange.append(cmd)
                continue
        else:
            # ',' separated list of values
            parm = parm.split(',')
            j = 0
            while j < len(parm) - 1:
                if parm[j][-1] == '\\':
                    parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1))
                j += 1
            param_matrix[cmd] = parm
        stg_image_num = max(stg_image_num, len(parm))

    stg_image_num = int(params.get('stg_image_num', stg_image_num))
    for cmd in rerange:
        param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num)
    # param_table* are for pretty print of param_matrix
    param_table = []
    param_table_header = ['name']
    if not has_name:
        param_table_header.append('image_name')
    for _ in param_matrix:
        param_table_header.append(_)

    stg_image_name = params.get('stg_image_name', 'images/%s')
    for i in range(stg_image_num):
        name = "stg%d" % i
        params['images'] += " %s" % name
        param_table.append([])
        param_table[-1].append(name)
        if not has_name:
            params["image_name_%s" % name] = stg_image_name % name
            param_table[-1].append(params.get("image_name_%s" % name))
        for parm in param_matrix.items():
            params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])])
            param_table[-1].append(params.get('%s_%s' % (parm[0], name)))

    if params.get("multi_disk_params_only") == 'yes':
        # Only print the test param_matrix and finish
        logging.info('Newly added disks:\n%s',
                     astring.tabular_output(param_table, param_table_header))
        return

    # Always recreate VMs and disks
    error_context.context("Start the guest with new disks", logging.info)
    for vm_name in params.objects("vms"):
        vm_params = params.object_params(vm_name)
        env_process.process_images(env_process.preprocess_image, test,
                                   vm_params)

    error_context.context("Start the guest with those disks", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.create(timeout=max(10, stg_image_num), params=params)
    login_timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=login_timeout)

    n_repeat = int(params.get("n_repeat", "1"))
    file_system = [_.strip() for _ in params["file_system"].split()]
    cmd_timeout = float(params.get("cmd_timeout", 360))
    black_list = params["black_list"].split()
    drive_letters = int(params.get("drive_letters", "26"))
    stg_image_size = params["stg_image_size"]
    dd_test = params.get("dd_test", "no")
    labeltype = params.get("labeltype", "gpt")

    have_qtree = True
    out = vm.monitor.human_monitor_cmd("info qtree", debug=False)
    if "unknown command" in str(out):
        have_qtree = False

    if (params.get("check_guest_proc_scsi") == "yes") and have_qtree:
        error_context.context("Verifying qtree vs. test params")
        err = 0
        qtree = qemu_qtree.QtreeContainer()
        qtree.parse_info_qtree(vm.monitor.info('qtree'))
        disks = qemu_qtree.QtreeDisksContainer(qtree.get_nodes())
        (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info_block())
        err += tmp1 + tmp2
        err += disks.generate_params()
        err += disks.check_disk_params(params)
        (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi(
            session.cmd_output('cat /proc/scsi/scsi'))
        err += tmp1 + tmp2

        if err:
            test.fail("%s errors occurred while verifying qtree vs."
                      " params" % err)
        if params.get('multi_disk_only_qtree') == 'yes':
            return
    try:
        err_msg = "Set disks num: %d" % stg_image_num
        err_msg += ", Get disks num in guest: %d"
        ostype = params["os_type"]
        if ostype == "windows":
            error_context.context("Get windows disk index that to "
                                  "be formatted", logging.info)
            disks = utils_disk.get_windows_disks_index(session, stg_image_size)
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
            if len(disks) > drive_letters:
                black_list.extend(utils_misc.get_winutils_vol(session))
                disks = random.sample(disks, drive_letters - len(black_list))
            error_context.context("Clear readonly for all disks and online "
                                  "them in windows guest.", logging.info)
            if not utils_disk.update_windows_disk_attributes(session, disks):
                test.fail("Failed to update windows disk attributes.")
            dd_test = "no"
        else:
            error_context.context("Get linux disk that to be "
                                  "formatted", logging.info)
            disks = sorted(utils_disk.get_linux_disks(session).keys())
            if len(disks) < stg_image_num:
                test.fail("Fail to list all the volumes"
                          ", %s" % err_msg % len(disks))
    except Exception:
        _do_post_cmd(session)
        raise
    try:
        for i in range(n_repeat):
            logging.info("iterations: %s", (i + 1))
            for disk in disks:
                error_context.context("Format disk in guest: '%s'" % disk,
                                      logging.info)
                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fstype = file_system[index].strip()
                partitions = utils_disk.configure_empty_disk(
                    session, disk, stg_image_size, ostype,
                    fstype=fstype, labeltype=labeltype)
                if not partitions:
                    test.fail("Fail to format disks.")
                cmd_list = params["cmd_list"]
                for partition in partitions:
                    if "/" not in partition:
                        partition += ":"
                    else:
                        partition = partition.split("/")[-1]
                    error_context.context("Copy file into / out of partition:"
                                          " %s..." % partition, logging.info)
                    for cmd_l in cmd_list.split():
                        cmd = params.get(cmd_l)
                        if cmd:
                            session.cmd(cmd % partition, timeout=cmd_timeout)
                    cmd = params["compare_command"]
                    key_word = params["check_result_key_word"]
                    output = session.cmd_output(cmd)
                    if key_word not in output:
                        test.fail("Files on guest os root fs and disk differ")
                    if dd_test != "no":
                        error_context.context("dd test on partition: %s..."
                                              % partition, logging.info)
                        status, output = session.cmd_status_output(
                            dd_test % (partition, partition), timeout=cmd_timeout)
                        if status != 0:
                            test.fail("dd test fail: %s" % output)
            need_reboot = params.get("need_reboot", "no")
            need_shutdown = params.get("need_shutdown", "no")
            if need_reboot == "yes":
                error_context.context("Rebooting guest ...", logging.info)
                session = vm.reboot(session=session, timeout=login_timeout)
            if need_shutdown == "yes":
                error_context.context("Shutting down guest ...", logging.info)
                vm.graceful_shutdown(timeout=login_timeout)
                if vm.is_alive():
                    test.fail("Fail to shut down guest.")
                error_context.context("Start the guest again.", logging.info)
                vm = env.get_vm(params["main_vm"])
                vm.create(params=params)
                session = vm.wait_for_login(timeout=login_timeout)
            error_context.context("Delete partitions in guest.", logging.info)
            for disk in disks:
                utils_disk.clean_partition(session, disk, ostype)
    finally:
        _do_post_cmd(session)
Example #12
0
def run(test, params, env):
    """
    QEMU 'disk images extension in io-error status' test

    1) Create folder and mounted it as tmpfs type.
    2) Create a raw image file with small size(50M) under the tmpfs folder.
    3) Attach loop device with above raw image file.
    4) Create qcow2 image on the loop device with larger size (500M).
    5) Boot vm with loop device as data disk.
    6) Access  guest vm and execute dd operation on the data disk.
     the IO size is same as the loop device virtual disk size.
    7) Verify vm status is paused status in qmp or hmp.
    8) Continue to increase disk size of the raw image file,
     and update the loop device.
    9) Verify vm status whether in expected status:
      if the raw image file size is smaller than loop device virtual disk size,
      it is in paused status,Otherwise it is in running status.

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def cleanup_test_env(dirname, loop_device_name):
        cmd = "if losetup -l {0};then losetup -d {0};fi;".format(
            loop_device_name)
        cmd += "umount -l {0};rm -rf {0};".format(dirname)
        process.system_output(cmd, shell=True)

    def prepare_tmpfs_folder(dirname):
        cmd = "umount -l {0};rm -rf {0};mkdir -p {0};".format(dirname)
        process.system_output(cmd, ignore_status=True, shell=True)
        cmd = "mount -t tmpfs -o rw,nosuid,nodev,seclabel tmpfs {}".format(
            dirname)
        process.system_output(cmd, shell=True)

    def create_image_on_loop_device(backend_img, device_img):
        backend_img.create(backend_img.params)
        backend_filename = backend_img.image_filename
        loop_device_name = device_img.image_filename
        cmd = "losetup -d {}".format(loop_device_name)
        process.system_output(cmd, ignore_status=True, shell=True)
        cmd = "losetup {0} {1} && chmod 666 {0}".format(
            loop_device_name, backend_filename)
        process.system_output(cmd, shell=True)
        device_img.create(device_img.params)

    def update_loop_device_backend_size(backend_img, device_img, size):
        cmd = "qemu-img resize -f raw %s %s && losetup -c %s" % (
            backend_img.image_filename, size, device_img.image_filename)
        process.system_output(cmd, shell=True)

    current_size = int(params["begin_size"][0:-1])
    max_size = int(params["max_size"][0:-1])
    increment_size = int(params["increment_size"][0:-1])
    size_unit = params["increment_size"][-1]
    guest_cmd = params["guest_cmd"]

    loop_device_backend_img_tag = params["loop_device_backend_img_tag"]
    loop_device_img_tag = params["loop_device_img_tag"]

    loop_device_backend_img_param = params.object_params(
        loop_device_backend_img_tag)
    loop_device_img_param = params.object_params(loop_device_img_tag)
    tmpfs_folder = params.get("tmpfs_folder", "/tmp/xtmpfs")

    if loop_device_backend_img_param["image_format"] != "raw":
        test.cancel("Wrong loop device backend image format in config file.")

    error_context.context("Start to setup tmpfs folder", logging.info)
    prepare_tmpfs_folder(tmpfs_folder)

    error_context.context("Start to create image on loop device", logging.info)
    loop_device_backend_img = QemuImg(loop_device_backend_img_param,
                                      data_dir.get_data_dir(),
                                      loop_device_backend_img_tag)
    loop_device_img = QemuImg(loop_device_img_param, data_dir.get_data_dir(),
                              loop_device_img_tag)
    create_image_on_loop_device(loop_device_backend_img, loop_device_img)

    try:
        # start to boot vm
        params["start_vm"] = "yes"
        timeout = int(params.get("login_timeout", 360))
        os_type = params["os_type"]
        driver_name = params.get("driver_name")
        disk_serial = params["disk_serial"]

        env_process.preprocess_vm(test, params, env, params["main_vm"])
        error_context.context("Get the main VM", logging.info)
        vm = env.get_vm(params["main_vm"])
        vm.verify_alive()

        session = vm.wait_for_login(timeout=timeout)
        if os_type == 'windows' and driver_name:
            session = utils_test.qemu.windrv_check_running_verifier(
                session, vm, test, driver_name, timeout)

        if os_type == 'windows':
            img_size = loop_device_img_param["image_size"]
            guest_cmd = utils_misc.set_winutils_letter(session, guest_cmd)
            disk = utils_disk.get_windows_disks_index(session, img_size)[0]
            utils_disk.update_windows_disk_attributes(session, disk)
            logging.info("Formatting disk:%s" % disk)
            driver = utils_disk.configure_empty_disk(session, disk, img_size,
                                                     os_type)[0]
            output_path = driver + ":\\test.dat"

        else:
            output_path = get_linux_drive_path(session, disk_serial)

        if not output_path:
            test.fail("Can not get output file path in guest.")

        logging.debug("Get output file path %s" % output_path)

        guest_cmd = guest_cmd % output_path
        wait_timeout = int(params.get("wait_timeout", 60))

        session.sendline(guest_cmd)

        test.assertTrue(vm.wait_for_status("paused", wait_timeout))

        while current_size < max_size:
            current_size += increment_size
            current_size_string = str(current_size) + size_unit

            error_context.context(
                "Update backend image size to %s" % current_size_string,
                logging.info)
            update_loop_device_backend_size(loop_device_backend_img,
                                            loop_device_img,
                                            current_size_string)

            vm.monitor.cmd("cont")

            # Verify the guest status
            if current_size < max_size:
                test.assertTrue(vm.wait_for_status("paused", wait_timeout))
            else:
                test.assertTrue(vm.wait_for_status("running", wait_timeout))
    finally:
        cleanup_test_env(tmpfs_folder, params["loop_device"])
Example #13
0
def run(test, params, env):
    """
    Test disk trimming in windows guest
    1) boot the vm with a data disk
    2) format the data disk without quick mode
    3) check the disk file size in host, and record for compare
    4) trim the data disk in guest
    5) check the disk file again in host, the file size should shrink

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _get_size_value(size_str):
        """
        Get size value form size string

        :param size_str: data size string
        :return: the size numeric value, measured by MB
        """
        size_str = utils_misc.normalize_data_size(size_str)
        size = float(size_str)
        return size

    def _disk_size_smaller(ori_size):
        """
        Check till the disk size becomes smaller than ori_size
        :param ori_size: original size to compare to
        :return: new size if it smaller than ori_size, else None
        """
        output = process.system_output(host_check_cmd, shell=True).decode()
        new_size = _get_size_value(str(output))
        logging.info("Current data disk size: %sMB", new_size)
        if new_size < ori_size:
            return new_size
        return None

    def query_system_events(filter_options):
        """Query the system events in filter options."""
        logging.info("Query the system event log.")
        cmd = params.get("query_cmd") % filter_options
        return params.get("searched_keywords") in session.cmd(cmd).strip()

    host_check_cmd = params.get("host_check_cmd")
    image_dir = os.path.join(data_dir.get_data_dir(), 'images')
    host_check_cmd %= image_dir
    image_name = params["stg_name"]
    stg_param = params.object_params(image_name)
    image_size_str = stg_param["image_size"]
    guest_trim_cmd = params["guest_trim_cmd"]
    driver_verifier = params["driver_verifier"]
    event_id = params.get("event_id")

    timeout = float(params.get("timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=timeout)
    error_context.context("Check if the driver is installed and verified",
                          logging.info)
    session = utils_test.qemu.windrv_check_running_verifier(
        session, vm, test, driver_verifier, timeout)

    error_context.context("Format data disk", logging.info)
    disk_index = utils_misc.wait_for(
        lambda: utils_disk.get_windows_disks_index(session, image_size_str),
        120)
    if not disk_index:
        test.error("Failed to get the disk index of size %s" % image_size_str)
    if not utils_disk.update_windows_disk_attributes(session, disk_index):
        test.error("Failed to enable data disk %s" % disk_index)
    drive_letter_list = utils_disk.configure_empty_windows_disk(
        session, disk_index[0], image_size_str, quick_format=False)
    if not drive_letter_list:
        test.error("Failed to format the data disk")
    drive_letter = drive_letter_list[0]

    error_context.context("Check size from host before disk trimming")
    output = process.system_output(host_check_cmd, shell=True).decode()
    ori_size = _get_size_value(output)
    logging.info("Data disk size: %sMB", ori_size)

    error_context.context("Trim data disk in guest")
    status, output = session.cmd_status_output(guest_trim_cmd % drive_letter,
                                               timeout=timeout)
    if status:
        test.error("Error when trim the volume, status=%s, output=%s" %
                   (status, output))
    if event_id:
        time.sleep(10)
        session = vm.reboot(session)
        if query_system_events(params['filter_options']):
            test.fail("Disk corruption after trim for %s" %
                      params.get("block_size"))

    error_context.context("Check size from host after disk trimming")
    new_size = utils_misc.wait_for(lambda: _disk_size_smaller(ori_size), 20,
                                   10, 1)

    if new_size is None:
        test.error("Data disk size is not smaller than: %sMB" % ori_size)
def run(test, params, env):
    """
    Test to check the size of data disk increased can be detected
    automatically inside windows guest.

    Steps:
        1) Start a windows guest with a data disk and format it.
        2) Increase this data disk by qmp command.
        3) Copy a file to this data disk.
        4) The guest can detect the data disk size increased
           automatically.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def increase_block_device(dev):
        """Increase the block device."""
        logging.info("Start to increase image '%s' to %s.", img,
                     img_resize_size)
        resize_size = int(
            float(
                normalize_data_size(
                    re.search(r'(\d+\.?(\d+)?\w)', img_resize_size).group(1),
                    "B")))
        args = (dev, resize_size)
        if vm.check_capability(Flags.BLOCKDEV):
            args = (None, resize_size, dev)
        vm.monitor.block_resize(*args)
        return resize_size

    def get_disk_size_by_diskpart(index):
        """Get the disk size by the diskpart."""
        cmd = ' && '.join(
            ("echo list disk > {0}", "echo exit >> {0}", "diskpart /s {0}",
             "del /f {0}")).format('disk_script')
        pattern = r'Disk\s+%s\s+Online\s+(\d+\s+\w+)\s+\d+\s+\w+' % index
        return re.search(pattern, session.cmd_output(cmd), re.M).group(1)

    def check_disk_size(index):
        """Check the disk size after increasing inside guest."""
        logging.info(
            'Check whether the size of disk %s is equal to %s after '
            'increasing inside guest.', index, img_resize_size)
        v, u = re.search(r"(\d+\.?\d*)\s*(\w?)", img_resize_size).groups()
        size = get_disk_size_by_diskpart(index)
        logging.info('The size of disk %s is %s', index, size)
        if normalize_data_size(size, u) != v:
            test.fail('The size of disk %s is not equal to %s' %
                      (index, img_resize_size))

    img = params.get("images").split()[-1]
    img_params = params.object_params(img)
    img_size = img_params.get("image_size")
    img_resize_size = img_params.get('image_resize_size')
    img_filename = storage.get_image_filename(img_params,
                                              data_dir.get_data_dir())

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = utils_test.qemu.windrv_check_running_verifier(
        vm.wait_for_login(), vm, test, 'viostor', 300)
    indices = utils_disk.get_windows_disks_index(session, img_size)
    utils_disk.update_windows_disk_attributes(session, indices)
    index = indices[0]
    mpoint = utils_disk.configure_empty_windows_disk(session, index,
                                                     img_size)[0]
    increase_block_device(vm.get_block({'file': img_filename}))
    vm.copy_files_to('/home/dd_file', "%s:\\dd_file" % mpoint)
    check_disk_size(index)
Example #15
0
def run(test, params, env):
    """
    KVM reboot test:
    1) Log into a guest with virtio data disk
    2) Format the disk and copy file to it
    3) Stop the guest and boot up it again with the data disk set to readonly
    4) Try to copy file to the data disk
    5) Try to copy file from the data disk

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    error_context.context("TEST STEPS 1: Try to log into guest.", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)

    error_context.context("TEST STEPS 2: Format the disk and copy file to it",
                          logging.info)
    os_type = params["os_type"]
    copy_cmd = params.get("copy_cmd", "copy %s %s")
    fstype = params.get("fstype", "ntfs")
    data_image_size = params.get("image_size_data", "1G")
    data_image_num = int(
        params.get("data_image_num",
                   len(params.objects("images")) - 1))
    error_context.context("Get windows disk index that to "
                          "be formatted", logging.info)
    disk_index_list = utils_disk.get_windows_disks_index(
        session, data_image_size)
    if len(disk_index_list) < data_image_num:
        test.fail("Fail to list all data disks. "
                  "Set disk number: %d, "
                  "get disk number in guest: %d." %
                  (data_image_num, len(disk_index_list)))
    src_file = utils_misc.set_winutils_letter(session,
                                              params["src_file"],
                                              label="WIN_UTILS")
    error_context.context(
        "Clear readonly for all disks and online "
        "them in guest.", logging.info)
    if not utils_disk.update_windows_disk_attributes(session, disk_index_list):
        test.fail("Failed to update windows disk attributes.")
    error_context.context("Format disk %s in guest." % disk_index_list[0],
                          logging.info)
    drive_letter = utils_disk.configure_empty_disk(session,
                                                   disk_index_list[0],
                                                   data_image_size,
                                                   os_type,
                                                   fstype=fstype)
    if not drive_letter:
        test.fail("Fail to format disks.")
    dst_file = params["dst_file"] % drive_letter[0]
    session.cmd(copy_cmd % (src_file, dst_file))

    msg = "TEST STEPS 3: Stop the guest and boot up again with the data disk"
    msg += " set to readonly"
    error_context.context(msg, logging.info)
    session.close()
    vm.destroy()

    data_img = params.get("images").split()[-1]
    params["image_readonly_%s" % data_img] = "yes"
    params["force_create_image_%s" % data_img] = "no"
    env_process.preprocess(test, params, env)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)

    error_context.context(
        "TEST STEPS 4: Write to the readonly disk expect:"
        "The media is write protected", logging.info)
    dst_file_readonly = params["dst_file_readonly"] % drive_letter[0]
    o = session.cmd_output(copy_cmd % (src_file, dst_file_readonly))
    if not o.find("write protect"):
        test.fail("Write in readonly disk should failed\n. {}".format(o))

    error_context.context("TEST STEPS 5: Try to read from the readonly disk",
                          logging.info)
    s, o = session.cmd_status_output(copy_cmd % (dst_file, r"C:\\"))
    if s != 0:
        test.fail("Read file failed\n. {}".format(o))

    session.close()