block_resize.py 5.0 KB
Newer Older
L
Lucas Meneghel Rodrigues 已提交
1 2
import logging
import re
Y
Yiqiao Pu 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
from autotest.client.shared import error
from virttest import qemu_monitor, utils_misc, storage, data_dir


@error.context_aware
def run_block_resize(test, params, env):
    """
    KVM block resize test:

    1) Start guest with data image and check the data image size.
    2) Enlarge(or Decrease) the data image and check it in guest.

    @param test: QEMU test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    def get_block_size(session, block_cmd, block_pattern):
        """
        Get block size inside guest.
        """
        output = session.cmd_output(block_cmd)
        block_size = re.findall(block_pattern, output)
        if block_size:
            if not re.search("[a-zA-Z]", block_size[0]):
                return int(block_size[0])
            else:
                return float(utils_misc.normalize_data_size(block_size[0],
L
Lucas Meneghel Rodrigues 已提交
30
                                                            order_magnitude="B"))
Y
Yiqiao Pu 已提交
31 32 33 34 35 36 37 38 39
        else:
            raise error.TestError("Can not find the block size for the"
                                  " deivce. The output of command"
                                  " is: %s" % output)

    error.context("Check image size in guest", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
L
Lucas Meneghel Rodrigues 已提交
40
    session = vm.wait_for_login(timeout=timeout)
Y
Yiqiao Pu 已提交
41 42 43 44 45

    data_image = params.get("images").split()[-1]
    data_image_params = params.object_params(data_image)
    data_image_size = data_image_params.get("image_size")
    data_image_size = float(utils_misc.normalize_data_size(data_image_size,
L
Lucas Meneghel Rodrigues 已提交
46
                                                           order_magnitude="B"))
Y
Yiqiao Pu 已提交
47 48 49 50 51 52 53 54 55 56 57
    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})

    block_size_cmd = params["block_size_cmd"]
    block_size_pattern = params.get("block_size_pattern")
    need_reboot = params.get("need_reboot", "no") == "yes"
    accept_ratio = float(params.get("accept_ratio", 0))

    block_size = get_block_size(session, block_size_cmd, block_size_pattern)
    if (block_size > data_image_size
L
Lucas Meneghel Rodrigues 已提交
58
            or block_size < data_image_size * (1 - accept_ratio)):
Y
Yiqiao Pu 已提交
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        raise error.TestError("Please check your system and image size check"
                              " command. The command output is not compatible"
                              " with the image size.")

    if params.get("guest_prepare_cmd"):
        session.cmd(params.get("guest_prepare_cmd"))

    disk_update_cmd = params.get("disk_update_cmd")
    if disk_update_cmd:
        disk_update_cmd = disk_update_cmd.split("::")

    block_size = data_image_size
    disk_change_ratio = params["disk_change_ratio"]
    for index, ratio in enumerate(disk_change_ratio.strip().split()):
        old_block_size = block_size
        block_size = int(int(data_image_size) * float(ratio))

        if block_size == old_block_size:
            logging.warn("Block size is not changed in round %s."
                         " Just skip it" % index)
            continue

        if disk_update_cmd:
            if "DISK_CHANGE_SIZE" in disk_update_cmd[index]:
                disk_unit = params.get("disk_unit", "M")
                size = abs(block_size - old_block_size)
                change_size = utils_misc.normalize_data_size("%sB" % size,
                                                             disk_unit)
                disk_update_cmd[index] = re.sub("DISK_CHANGE_SIZE",
                                                change_size.split(".")[0],
                                                disk_update_cmd[index])

        error.context("Change the disk size to %s" % block_size, logging.info)
        # So far only virtio drivers support online auto block size change in
        # linux guest. So we need manully update the the disk or even reboot
        # guest to get the right block size after change it from monitor.

        # We need shrink the disk in guest first, than in monitor
        if block_size < old_block_size and disk_update_cmd:
            session.cmd(disk_update_cmd[index])
        tmp = vm.monitor.block_resize(data_image_dev, block_size)
        if need_reboot:
            session = vm.reboot(session=session)
        # We need expand disk in monitor first than extend it in guest
        if block_size > old_block_size and disk_update_cmd:
            session.cmd(disk_update_cmd[index])

        current_size = get_block_size(session, block_size_cmd,
                                      block_size_pattern)
        if (current_size > block_size
L
Lucas Meneghel Rodrigues 已提交
109
                or current_size < block_size * (1 - accept_ratio)):
Y
Yiqiao Pu 已提交
110 111 112 113
            raise error.TestFail("Guest reported a wrong disk size:\n"
                                 "    reported: %s\n"
                                 "    expect: %s\n" % (current_size,
                                                       block_size))