Beispiel #1
0
def run(test, params, env):
    """
    Test hot plug and unplug NVMe device.

    Steps:
        1. Install guest with local filesystem.
        2. Hot plug NVMe device to guest.
        3. Check if the NVMe device exists in qemu side.
        4. Check if the NVMe has been successfully added to guest.
        5. Run fio in the hot plugged NVMe device in guest.
        6. Unplug the NVMe device.
        7. Check if the NVMe device still exists.
        8. Check if the NVMe has been successfully removed from guest.
        9. Reboot guest.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    unattended_install.run(test, params, env)

    if params.get('remove_options'):
        for option in params.get('remove_options').split():
            del params[option]
    params['cdroms'] = params.get('default_cdroms')

    params['start_vm'] = 'yes'
    env_process.preprocess_vm(test, params, env, params["main_vm"])
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login()

    plug = BlockDevicesPlug(vm)
    plug.hotplug_devs_serial()
    target = '/dev/%s' % plug[0]
    os_type = params['os_type']
    data_img_size = params.get('image_size_%s' % params.get('data_img_tag'))
    if os_type == 'windows':
        utils_disk.update_windows_disk_attributes(session, plug[0])
        drive_letter = utils_disk.configure_empty_disk(session, plug[0],
                                                       data_img_size,
                                                       os_type)[0]
        target = r'%s\:\\%s' % (drive_letter, params.get('fio_filename'))
    fio = generate_instance(params, vm, 'fio')
    for option in params['fio_options'].split(';'):
        fio.run('--filename=%s %s' % (target, option))
    plug.unplug_devs_serial()
    vm.reboot(session)
Beispiel #2
0
 def hotplug_unplug_block_repeatedly(times):
     """Hot plug then unplug block devices repeatedly."""
     vm_pid = vm.get_pid()
     plug = BlockDevicesPlug(vm)
     info = ('The number of AIO file descriptors is %s '
             'after %s block device.')
     for i in range(times):
         logging.info('Iteration %d: Hot plug then unplug '
                      'block device.', i)
         plug.hotplug_devs_serial()
         orig_fds_num = _get_aio_fds_num(vm_pid)
         logging.info(info, orig_fds_num, 'hot plugging')
         plug.unplug_devs_serial()
         new_fds_num = _get_aio_fds_num(vm_pid)
         logging.info(info, new_fds_num, 'unplugging')
         if new_fds_num != orig_fds_num:
             test.fail('The the number of AIO descriptors is '
                       'changed, from %s to %s.' %
                       (orig_fds_num, new_fds_num))
def run(test, params, env):
    """
    Test to resize block device then unplug it.

    Steps:
        1) Boot the guest with a data disk.
        2) For Windows: Check whether viostor.sys verifier enabled in
           guest.
        3) Resize the data disk, e.g, enlarge to 10GB; shrink to 1GB.
        4) Check the data disk in guest whether is enlarge or shrink
           to the excepted size.
        5) Reboot guest.
        6) Unplug the data disk.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def _change_vm_power():
        """ Change the vm power. """
        method, command = params['command_opts'].split(',')
        logging.info('Sending command(%s): %s' % (method, command))
        if method == 'shell':
            power_session = vm.wait_for_login()
            power_session.sendline(command)
        else:
            getattr(vm.monitor, command)()
        if shutdown_vm:
            if not utils_misc.wait_for(
                    lambda: vm.monitor.get_event("SHUTDOWN"), 600):
                raise test.fail("Not received SHUTDOWN QMP event.")

    def _check_vm_status(timeout=600):
        """ Check the status of vm. """
        action = 'shutdown' if shutdown_vm else 'login'
        if not getattr(vm, 'wait_for_%s' % action)(timeout=timeout):
            test.fail('Failed to %s vm.' % action)

    def _block_resize(dev):
        """ Resize the block size. """
        resize_size = int(
            float(
                normalize_data_size(
                    re.search(r'(\d+\.?(\d+)?\w)',
                              params['resize_size']).group(1), "B")))
        size = str(data_image_size +
                   resize_size) if resize_op == ENLARGE else str(
                       data_image_size - resize_size)
        logging.info("Start to %s image '%s' to %sB." %
                     (resize_op, data_image, size))
        if vm.check_capability(Flags.BLOCKDEV):
            args = (None, size, dev)
        else:
            args = (dev, size)
        vm.monitor.block_resize(*args)
        return size

    def _check_img_size(size):
        """ Check the size of image after resize. """
        img = qemu_storage.QemuImg(data_image_params, data_dir.get_data_dir(),
                                   data_image)
        if json.loads(img.info(True, 'json'))['virtual-size'] != int(size):
            test.fail('The virtual size is not equal to %sB after %s.' %
                      (size, resize_op))

    shutdown_vm = params.get('shutdown_vm', 'no') == 'yes'
    reboot = params.get('reboot_vm', 'no') == 'yes'
    data_image = params.get("images").split()[-1]
    data_image_params = params.object_params(data_image)
    data_image_size = int(
        float(normalize_data_size(data_image_params.get("image_size"), "B")))
    data_image_filename = storage.get_image_filename(data_image_params,
                                                     data_dir.get_data_dir())
    resize_op = SHRINK if '-' in params['resize_size'] else ENLARGE
    is_windows = params['os_type'] == 'windows'

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login()
    plug = BlockDevicesPlug(vm)

    if is_windows:
        utils_test.qemu.windrv_check_running_verifier(session, vm, test,
                                                      params['driver_name'],
                                                      300)
    _check_img_size(_block_resize(vm.get_block({'file': data_image_filename})))

    if reboot:
        _change_vm_power()
        _check_vm_status()
    plug.unplug_devs_serial()
Beispiel #4
0
def run(test, params, env):
    """
    Test hotplug of block devices.

    1) Boot up guest with virtio-blk or virtio-scsi system disk.
    2) Hoplug a virtio-blk or virtio-scsi data disk by qmp.
    3) Do read/write data on hotplug block.
    4) Unplug block device during serving block io, then verify devices.
    5) repeat step2~step4 100 times.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def _check_iozone_status():
        ck_session = vm.wait_for_login(timeout=360)
        if not utils_misc.wait_for(lambda: check_cmd[os_type].split(
        )[-1].lower() in ck_session.cmd_output(check_cmd[os_type]).lower(),
                                   180,
                                   step=3.0):
            test.fail("Iozone is not alive!")
        ck_session.close()

    def _run_iozone_background():
        logging.info("Start iozone under background.")
        thread = utils_misc.InterruptedThread(
            iozone.run, (params['iozone_options'].format(mount_point),
                         float(params['iozone_timeout'])))
        thread.start()
        _check_iozone_status()
        return thread

    check_cmd = {
        'linux': 'pgrep -lx iozone',
        'windows': 'TASKLIST /FI "IMAGENAME eq IOZONE.EXE'
    }
    os_type = params['os_type']
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=360)

    iozone = generate_instance(params, vm, 'iozone')
    plug = BlockDevicesPlug(vm)
    need_format = True
    try:
        for i in range(int(params['repeat_time'])):
            logging.info('Start to run testing.(iteration: %d).', (i + 1))
            plug.hotplug_devs_serial()
            if need_format:
                if os_type == 'windows':
                    utils_disk.update_windows_disk_attributes(session, plug[0])
                mount_point = utils_disk.configure_empty_disk(
                    session, plug[0], params['image_size_stg0'], os_type)[0]
                if os_type == 'windows':
                    need_format = False
            iozone_thread = _run_iozone_background()
            time.sleep(float(params['sleep_time']))
            _check_iozone_status()
            plug.unplug_devs_serial()
            iozone_thread.join(suppress_exception=True)
    finally:
        iozone.clean(force=True)
        session.close()
Beispiel #5
0
def run(test, params, env):
    """
    Boot vm with virtio device:virtio-blk-pci, virtio-scsi-pci, virtio-net-pci
    and use aer=on for virtio devices.

    1) Boot guest with virtio-blk-pci, virtio-scsi-pci, virtio-net-pci device,
       and use aer=on,ats=on for virtio devices.
    2) check if aer and ats capabilitie in guest os

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def get_pci_addr_by_devid(dev_id):
        """
        Get pci address by device id.
        """
        def _get_device_by_devid(devices, dev_id):
            """
            Get device info with device id from 'info pci' output.
            """
            device_found = {}
            for dev in devices:
                if dev['qdev_id'] == dev_id:
                    device_found = dev
                    break
                elif dev['class_info'].get('desc') == 'PCI bridge':
                    pci_bridge_devices = dev['pci_bridge'].get('devices')
                    if not pci_bridge_devices:
                        continue
                    device_found = _get_device_by_devid(
                        pci_bridge_devices, dev_id)
                    if device_found:
                        break
            return device_found

        dev_addr = ''
        dev_addr_fmt = '%02d:%02d.%d'
        pci_info = vm.monitor.info('pci', debug=False)
        device = _get_device_by_devid(pci_info[0]['devices'], dev_id)
        if device:
            dev_addr = dev_addr_fmt % (device['bus'], device['slot'],
                                       device['function'])
        return dev_addr

    def check_dev_cap_in_guest(dev_id, capbilities):
        """
        Check the specified device's capabilities in guest os

        :params dev_id: device id in qemu command line
        :params capbilities: the capabilities list that expected to be found
        :return True if get all the capabilities, else False
        """

        dev_addr = get_pci_addr_by_devid(dev_id)
        for cap in capbilities:
            check_cmd = "lspci -vvv -s %s | grep '%s'" % (dev_addr, cap)
            if session.cmd_status(check_cmd) != 0:
                logging.error("Failed to get capability '%s' for device %s",
                              cap, dev_id)
                return False
        return True

    if params.object_params('qmpmonitor1').get('monitor_type') == 'human':
        test.cancel("Please run test with qmp monitor")

    vm = env.get_vm(params["main_vm"])
    session = vm.wait_for_login()
    capabilities = params['capabilities'].split(',')
    images = params.objects('images')

    dev_ids = []
    blk_image = images[1]
    blk_dev = vm.devices.get_by_qid(blk_image)[0]
    blk_dev_id = blk_dev.params['id']
    dev_ids.append(blk_dev_id)

    scsi_dev = vm.devices.get_by_params({'driver': 'virtio-scsi-pci'})[0]
    scsi_dev_id = scsi_dev.params['id']
    dev_ids.append(scsi_dev_id)

    nic_id = vm.virtnet[0].device_id
    nic_dev = vm.devices.get_by_qid(nic_id)[0]
    nic_dev_id = nic_dev.params['id']
    dev_ids.append(nic_dev_id)

    try:
        for dev_id in dev_ids:
            if not check_dev_cap_in_guest(dev_id, capabilities):
                test.fail('Check capabilities %s for device %s failed' %
                          (capabilities, dev_id))

        plug = BlockDevicesPlug(vm)
        for img in params.get("hotplug_images", "").split():
            plug.unplug_devs_serial(img)
            plug.hotplug_devs_serial(img)
            blk_dev = vm.devices.get_by_qid(img)[0]
            blk_dev_id = blk_dev.params['id']
            if not check_dev_cap_in_guest(blk_dev_id, capabilities):
                test.fail('Check capabilities %s for device %s failed' %
                          (capabilities, blk_dev_id))
    finally:
        session.close()
Beispiel #6
0
def utils_test(test, params, env, vm, session):
    """
    :param test:
    :param params:
    :param env:
    :param vm:
    :param session:
    :return:
    """
    logging.info(test, params, env, vm, session)
    tgm = ThrottleGroupManager(vm)

    logging.info("query_throttle_group group1")
    tgm.get_throttle_group_props("group1")

    logging.info("query_throttle_group group4")
    tgm.get_throttle_group_props("group4")
    # stg2 nonexist
    tgm.get_throttle_group_props("stg2")
    # group5 nonexist
    logging.info("delete_throttle_group group5")
    tgm.delete_throttle_group("group5")

    logging.info("query_throttle_group group3")
    tgm.get_throttle_group_props("group3")

    # add group3 failed
    logging.info("add_throttle_group group3")
    try:
        tgm.add_throttle_group("group3", {"iopsx-total": 50})
    except Exception as err:
        logging.error(err)

    # add group3 succeed
    tgm.add_throttle_group("group3", {"iops-total": 50})
    out = tgm.get_throttle_group_props("group3")
    logging.info(out)

    logging.info("get_throttle_group group3")
    dev = tgm.get_throttle_group("group3")

    plug = BlockDevicesPlug(vm)

    # hotplug stg7
    logging.info("stg7 hot-plug")
    plug.hotplug_devs_serial("stg7")
    logging.info(vm.devices.str_bus_short())

    # hotplug stg6
    logging.info("stg6 hot-plug")
    plug.hotplug_devs_serial("stg6")
    logging.info(vm.devices.str_bus_short())

    logging.info("change stg6 from group3 to group1")
    tgm.change_throttle_group("stg6", "group1")
    logging.info("change stg3 from group1 to group2")
    tgm.change_throttle_group("stg3", "group2")
    logging.info(vm.devices.str_bus_short())
    logging.info("change stg3 from group2 to group1")
    tgm.change_throttle_group("stg3", "group1")
    logging.info(vm.devices.str_bus_short())
    vm.monitor.info("block")

    logging.info("stg6 hot-unplug")
    plug.unplug_devs_serial("stg6")
    logging.info(vm.devices.str_bus_short())

    logging.info("update throttle group")
    tgm.update_throttle_group("group3", {"bps-total": 150})
    out = tgm.get_throttle_group_props("group3")
    logging.info(out)
    logging.info(dev.raw_limits)

    logging.info("throttle group hot-unplug")
    tgm.delete_throttle_group("group3")
    logging.info(vm.devices.str_bus_short())
    tgm.get_throttle_group("group3")
    logging.info("==================")

    # image hotplug-unplug
    logging.info("unplug stg1 ")
    plug.unplug_devs_serial("stg1")
    logging.info(vm.devices.str_bus_short())

    logging.info("plug stg1")
    plug.hotplug_devs_serial("stg1")
    logging.info(vm.devices.str_bus_short())

    logging.info("unplug stg1")
    plug.unplug_devs_serial("stg1")
    logging.info(vm.devices.str_bus_short())

    logging.info("==================")
    logging.info("plug stg5 belong to no group")
    plug.hotplug_devs_serial("stg5")
    logging.info(vm.devices.str_bus_short())

    logging.info("unplug stg5")
    plug.unplug_devs_serial("stg5")
    logging.info(vm.devices.str_bus_short())
    logging.info("sleep 3...")
    time.sleep(3)

    logging.info("test simple_hotplug ...")
    image_name = "stg1"
    image_params = params.object_params(image_name)
    # include blockdevs and devices
    stg_a_devs = vm.devices.images_define_by_params(image_name, image_params,
                                                    'disk')
    for dev in stg_a_devs:
        vm.devices.simple_hotplug(dev, vm.monitor)

    image_name = "stg5"
    image_params = params.object_params(image_name)
    stg_b_devs = vm.devices.images_define_by_params(image_name, image_params,
                                                    'disk')
    for dev in stg_b_devs:
        vm.devices.simple_hotplug(dev, vm.monitor)
    logging.info(vm.devices.str_bus_short())
    time.sleep(3)

    logging.info("test simple_unplug ...")
    vm.devices.simple_unplug(stg_a_devs[-1], vm.monitor)
    vm.devices.simple_unplug(stg_b_devs[-1], vm.monitor)
    logging.info(vm.devices.str_bus_short())
    time.sleep(3)
def run(test, params, env):
    """
    Test the virtio scsi block device with virtio-scsi-pci.hotplug=on
    or off.
      Steps:
        1. Start VM with virtio-scsi-pci(system disk).
        2. Check whether vioscsi.sys verifier enabled in windows guest.
        3. Hotplug a virtio-scsi disk with virtio-scsi-pci.hotplug=off
           via qmp.
        4. Check the new disk in guest.
        5. Rescan the scsi bus in the guest and recheck the disk.
        6. Retest the step 3-4 with hotplug=on specified and then
           hot-unplug it.

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    def list_all_disks(session):
        """List all disks inside guest."""
        if is_linux:
            return utils_misc.list_linux_guest_disks(session)
        return set(session.cmd('wmic diskdrive get index').split()[1:])

    def _get_scsi_host_id(session):
        logging.info("Get the scsi host id which is hot plugged.")
        output = session.cmd("dmesg | grep \"scsi host\" | "
                             "awk 'END{print}' | awk '{print $4}'")
        return re.search(r'(\d+)', output).group(1)

    def _rescan_hba_controller_linux(session):
        session.cmd('echo "- - -" > /sys/class/scsi_host/host%s/scan' %
                    _get_scsi_host_id(session))

    def _rescan_hba_controller_windows(session):
        session.cmd(
            'echo rescan > {0} && echo exit >> {0} && diskpart / {0} '
            '&& del /f {0}'.format('diskpart_script'), 300)

    def rescan_hba_controller(session):
        """Rescan the scsi hba controller."""
        error_context.context("Rescan the scsi hba controller.", logging.info)
        if is_linux:
            _rescan_hba_controller_linux(session)
        else:
            _rescan_hba_controller_windows(session)

    is_linux = params['os_type'] == 'linux'
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=360)

    if not is_linux:
        session = qemu.windrv_check_running_verifier(session, vm, test,
                                                     params['driver_name'],
                                                     360)

    orig_disks = list_all_disks(session)
    plug = BlockDevicesPlug(vm)
    plug.hotplug_devs_serial(interval=int(params['hotplug_interval']))
    if params['need_rescan_hba'] == 'yes':
        if utils_misc.wait_for(
                lambda: bool(list_all_disks(session) - orig_disks), 30,
                step=3):
            logging.debug('The all disks: %s.', list_all_disks(session))
            test.fail('Found a new disk with virtio-scsi-pci.hotplug=off '
                      'before rescan scsi hba controller.')
        rescan_hba_controller(session)
    plug.unplug_devs_serial()
def run(test, params, env):
    """
    Test multi disk with multifunction on and off.

    1) Boot guest with system disk(multifunction=on)
    2) Hotplug 7 disks with addr 0x0.0x1~0x0.0x7
    3) hotplug 1 disk with multifunction=on (addr 0x0)
    4) Check disks in guest
    5) Run dd/iozone test on all data disks
    6) Reboot guest, check disks in guest
    7) Unplug disk8, and remove disk 1-7
    8) Hotplug disk8 with multifunction=off

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def get_image_device(qdev, img_name):
        """
        Get the image device(virtio-blk-pci/virtio-scsi-pci)
        :param qdev: DevContainer object
        :param img_name: The image name
        """
        dev = qdev.get(img_name)
        devs = [dev]
        if params['drive_format'].startswith('scsi'):
            devs.append(
                qdev.get_by_properties(
                    {'aid': dev.get_param('bus').split('.')[0]})[0])
        return devs

    image = params.objects('images')[0]
    vm_name = params['main_vm']
    set_addr(image, 0, 0,
             params)  # Add multifunction=on option before start vm
    params['start_vm'] = 'yes'
    env_process.preprocess_vm(test, params, env, vm_name)
    vm = env.get_vm(vm_name)
    qdev = vm.devices
    windows = params["os_type"] == 'windows'
    disk_op_cmd = params.get("disk_op_cmd")
    session = vm.wait_for_login()

    q35 = params['machine_type'] == 'q35'
    dev_slot = 0 if q35 else 9
    parent_bus = 'pcie_extra_root_port_0' if q35 else 'pci.0'
    image_size = '1G'
    # Generate the data disk devices to be plugged
    for i in range(1, 9):
        stg = 'stg%s' % i
        vm.params['images'] += ' %s' % stg
        vm.params['image_name_%s' % stg] = 'images/%s' % stg
        vm.params['image_size_%s' % stg] = image_size
        vm.params['remove_image_%s' % stg] = 'yes'
        vm.params['force_create_image_%s' % stg] = 'yes'
        vm.params['boot_drive_%s' % stg] = 'no'
        # Specify the address of the device, plug them into same slot
        set_addr(stg, dev_slot, i, vm.params)
        if params['drive_format'].startswith('scsi'):
            # Create oen new scsi bus for each block device
            vm.params['drive_bus_%s' % stg] = i
    # To create those image files
    env_process.process_images(env_process.preprocess_image, test, vm.params)

    plug = BlockDevicesPlug(vm)
    parent_bus_obj = qdev.get_buses({'aobject': parent_bus})[0]
    plug.hotplug_devs_serial(bus=parent_bus_obj)

    # Run io test on all the plugged disks
    io_test(session, disk_op_cmd, plug, windows, image_size)

    # Reboot the guest and check if all the disks still exist
    disks_before_reboot = block_hotplug.find_all_disks(session, windows)
    session = vm.reboot(session)
    block_hotplug.wait_plug_disks(session, 'check', disks_before_reboot, 0,
                                  windows, test)
    session.close()

    # Unplug the disk on function 7 and 0, and check if all the disks been removed
    images = vm.params.objects('images')
    unplug_dev = images[-1]
    unplug_timeout = params['unplug_timeout']
    try:
        plug.unplug_devs_serial(images=unplug_dev, timeout=unplug_timeout)
    except exceptions.TestError as e:
        if 'Actual: 8 disks. Expected: ' not in str(e):
            raise
    else:
        test.fail('All the plugged disks should be removed when'
                  ' the device at function 0 is removed.')

    # replug disk 2-7
    rest_dev = images[1:-1]
    # Remove them from DevContainer first, they are unplugged by qemu
    # but still in DevContainer
    for img in rest_dev:
        devs_rm = get_image_device(qdev, img)
        list(map(lambda x: qdev.remove(x, recursive=False), devs_rm))
    plug._create_devices(rest_dev, {'aobject': parent_bus})
    for img, devs in plug._hotplugged_devs.items():
        if img not in rest_dev:
            continue
        for dev in devs:
            args = (dev, vm.monitor)
            if isinstance(dev, QDevice):
                pci_device = qdev.is_pci_device(dev['driver'])
                if pci_device:
                    args += (parent_bus_obj, )
                elif not dev['driver'].startswith('scsi'):
                    continue
            elif not isinstance(dev, QDrive):
                continue
            try:
                plug._hotplug_atomic(*args)
            except NotImplementedError:
                # Insert might fail for file node 1-7 not been removed
                # from vm.devices, which can be ignored
                pass

    # Replug disk 8 on slot 0 with multifunction='off'
    set_addr(images[-1], dev_slot, 0, vm.params, multifunction='off')
    plug._create_devices(unplug_dev.split(), {'aobject': parent_bus})
    for img, devs in plug._hotplugged_devs.items():
        for dev in devs:
            if (img == images[-1] and isinstance(dev, QDevice)
                    and qdev.is_pci_device(dev['driver'])):
                dev['addr'] = hex(dev_slot)  # for pci bus addr might be reset
                try:
                    parent_bus_obj.prepare_hotplug(dev)
                    dev.hotplug(vm.monitor, vm.devices.qemu_version)
                except QMPCmdError as e:
                    if 'single function' not in str(e):
                        raise
                else:
                    test.fail(
                        'It should fail to hotplug a single function device'
                        ' to the address where multifunction already on.')
                break
            else:
                plug._hotplug_atomic(dev, vm.monitor)
 def unplug_path_disk(vm):
     """Unplug passthrough disk."""
     error_context.context("Unplug passthrouth device", logging.info)
     plug = BlockDevicesPlug(vm)
     plug.unplug_devs_serial()