Ejemplo n.º 1
0
def run_qemu_img(test, params, env):
    """
    'qemu-img' functions test:
    1) Judge what subcommand is going to be tested
    2) Run subcommand test

    @param test: kvm test object
    @param params: Dictionary with the test parameters
    @param env: Dictionary with test environment.
    """
    cmd = virt_utils.get_path(test.bindir, params.get("qemu_img_binary"))
    if not os.path.exists(cmd):
        raise error.TestError("Binary of 'qemu-img' not found")
    image_format = params.get("image_format")
    image_size = params.get("image_size", "10G")
    image_name = virt_utils.get_image_filename(params, test.bindir)


    def _check(cmd, img):
        """
        Simple 'qemu-img check' function implementation.

        @param cmd: qemu-img base command.
        @param img: image to be checked
        """
        cmd += " check %s" % img
        logging.info("Checking image '%s'...", img)
        try:
            output = utils.system_output(cmd)
        except error.CmdError, e:
            if "does not support checks" in str(e):
                return (True, "")
            else:
                return (False, str(e))
        return (True, output)
Ejemplo n.º 2
0
    def rebase_test(cmd):
        """
        Subcommand 'qemu-img rebase' test

        Change the backing file of a snapshot image in "unsafe mode":
        Assume the previous backing file had missed and we just have to change
        reference of snapshot to new one. After change the backing file of a
        snapshot image in unsafe mode, the snapshot should work still.

        @param cmd: qemu-img base command.
        """
        if not 'rebase' in utils.system_output(cmd + ' --help',
                                               ignore_status=True):
            raise error.TestNAError("Current kvm user space version does not"
                                    " support 'rebase' subcommand")
        sn_fmt = params.get("snapshot_format", "qcow2")
        sn1 = params.get("image_name_snapshot1")
        sn1 = virt_utils.get_path(test.bindir, sn1) + ".%s" % sn_fmt
        base_img = virt_utils.get_image_filename(params, test.bindir)
        _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format)

        # Create snapshot2 based on snapshot1
        sn2 = params.get("image_name_snapshot2")
        sn2 = virt_utils.get_path(test.bindir, sn2) + ".%s" % sn_fmt
        _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt)

        rebase_mode = params.get("rebase_mode")
        if rebase_mode == "unsafe":
            os.remove(sn1)

        _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode)

        # Check sn2's format and backing_file
        actual_base_img = _info(cmd, sn2, "backing file")
        base_img_name = os.path.basename(params.get("image_name"))
        if not base_img_name in actual_base_img:
            raise error.TestFail("After rebase the backing_file of 'sn2' is "
                                 "'%s' which is not expected as '%s'"
                                 % (actual_base_img, base_img_name))
        s, o = _check(cmd, sn2)
        if not s:
            raise error.TestFail("Check image '%s' failed after rebase;"
                                 "got error: %s" % (sn2, o))
        try:
            os.remove(sn2)
            os.remove(sn1)
        except Exception:
            pass
Ejemplo n.º 3
0
                logging.error(fail_log)
        return f_fail

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    logging.info("Starting physical resources check test")
    logging.info("Values assigned to VM are the values we expect " "to see reported by the Operating System")
    # Define a failure counter, as we want to check all physical
    # resources to know which checks passed and which ones failed
    n_fail = []

    # We will check HDs with the image name
    image_name = virt_utils.get_image_filename(params, test.bindir)

    # Check cpu count
    logging.info("CPU count check")
    expected_cpu_nr = int(params.get("smp"))
    actual_cpu_nr = vm.get_cpu_count()
    if expected_cpu_nr != actual_cpu_nr:
        fail_log = "CPU count mismatch:\n"
        fail_log += "    Assigned to VM: %s \n" % expected_cpu_nr
        fail_log += "    Reported by OS: %s" % actual_cpu_nr
        n_fail.append(fail_log)
        logging.error(fail_log)

    # Check memory size
    logging.info("Memory size check")
    expected_mem = int(params.get("mem"))
Ejemplo n.º 4
0
def _qtree_check(vm, session, params, root_dir):
    """
    Tries to find differences between qemu qtree+info vs. /proc/scsi/scsi and
    vm params.

    @param vm: VM object
    @param session: ssh session to VM
    @param params: Dictionary with the test parameters
    @param root_dir: vm's root_dir (for get_image_name function)
    """
    err = 0
    # check [params_names, qtree search pattern]
    check = [['name', 'channel', 'scsiid', 'lun'],
             ['dev-prop: drive = ', 'bus-prop: channel = ',
              'bus-prop: scsi-id = ', 'bus-prop: lun = ']]
    drive_formats = ['ide', 'scsi', 'virtio-blk-pci']

    # Info about disks gathered from guest
    disks = {}
    no_virtio_disks = 0 # virtio-blk-pci disks are not in /proc/scsi/scsi

    error.context("Gather info from 'info qtree'")
    info = vm.monitor.info('qtree').split('\n')
    current = None
    line = info.pop(0)
    offset = None
    while len(info) > 0:
        if current is not None:     # Get all info about disk
            _offset = len(re_blanks.match(line).group(0))
            if offset == None:
                offset = _offset
            elif offset != _offset:
                # This line is about next device, store current and prepare
                # for next one.
                name = current.get('name')
                if not name:
                    logging.error("Skipping disk without a name: %s", current)
                    err += 1
                elif name in disks:
                    logging.error("Disk %s present multiple times in qtree",
                                   current)
                else:
                    if current['drive_format'] == 'virtio-blk-pci':
                        no_virtio_disks += 1
                    disks[name] = current
                current = None
                continue    # this line have to be proceeded in next round
            line = line[offset:]
            for i in xrange(len(check[1])):
                if line.startswith(check[1][i]):
                    current[check[0][i]] = line[len(check[1][i]):].strip()
        else:       # Look for block with disk specification
            line = line.strip()
            for fmt in drive_formats:
                if line.startswith('dev: %s' % fmt):
                    current = {'drive_format': fmt}
                    offset = None
        line = info.pop(0)  # Next line

    error.context("Gather info from 'info block'")
    info = vm.monitor.info("block").split('\n')
    for line in info:
        if not line:
            continue
        line = line.split(':', 1)
        name = line[0].strip()
        if name not in disks:
            logging.error("disk %s is in block but not in qtree", name)
            err += 1
            continue
        item = {}
        for _ in line[1].strip().split(' '):
            _ = _.split('=')
            item[_[0]] = _[1]
        if item.get('backing_file'):
            disks[name]['snapshot'] = 'yes'
            disks[name]['image_name'] = os.path.realpath(
                                                    item.get('backing_file'))
        elif item.get('file'):
            disks[name]['image_name'] = os.path.realpath(item.get('file'))
        else:
            logging.error("Can'T get info about %s disk file.", name)
            err += 1
        if item.get('ro') and item.get('ro') != '0':
            disks[name]['readonly'] = 'yes'

    error.context("Verify info from guest's /proc/scsi/scsi")
    # host, channel, id, lun, vendor
    scsis = re.findall(r'Host:\s+(\w+)\s+Channel:\s+(\d+)\s+Id:\s+(\d+)\s+'
                        'Lun:\s+(\d+)\n\s+Vendor:\s+([a-zA-Z0-9_-]+)\s+Model: ',
                        session.cmd_output('cat /proc/scsi/scsi'))
    if len(scsis) + no_virtio_disks != len(disks):
        logging.error("The number of disks in qtree and /proc/scsi/scsi is not"
                      " equal.")
        err += 1
    _disks = {}
    # Check only scsi disks
    for disk in disks.copy().iteritems():
        if disk[1]['drive_format'].startswith('scsi'):
            _disks[disk[0]] = disk[1]
    _ = []
    for scsi in scsis:
        if scsi[4].startswith('QEMU'):
            _.append("%d-%d-%d" % (int(scsi[1]), int(scsi[2]), int(scsi[3])))
    scsis = _
    # Check only channel, id and lun for now
    for disk in _disks.itervalues():
        name = '%d-%d-%d' % (int(disk['channel']), int(disk['scsiid']),
                             int(disk['lun']))
        if name not in scsis:
            logging.error('Disk %s is in qtree but not in /proc/scsi/scsi.',
                          disk)
            err += 1
            continue
        scsis.remove(name)

    error.context("Verify the info from qtree+block vs. params.")
    _disks = disks.copy()
    for name in params.objects('images'):
        current = None
        image_params = params.object_params(name)
        image_name = os.path.realpath(get_image_filename(image_params,
                                                         root_dir))
        for disk in disks.itervalues():
            if disk.get('image_name') == image_name:
                current = disk
                qname = current.get('name')
                current.pop('name')
                break
        if not current:
            logging.error("Disk %s is not in qtree but is in params.", name)
            err += 1
            continue
        for prop in check[0]:
            if (image_params.get(prop) and current.get(prop) and
                    image_params.get(prop) != current.get(prop)):
                logging.error("Disk %s's property %s=%s doesn't math params %s",
                              qname, prop, current.get(prop),
                               image_params.get(prop))
                err += 1
        _disks.pop(qname)
    if _disks:
        logging.error('Some disks were in qtree but not in autotest params: %s',
                      _disks)
        err += 1

    return err
Ejemplo n.º 5
0
def run_pci_hotplug(test, params, env):
    """
    Test hotplug of PCI devices.

    (Elements between [] are configurable test parameters)
    1) PCI add a deivce (NIC / block)
    2) Compare output of monitor command 'info pci'.
    3) Compare output of guest command [reference_cmd].
    4) Verify whether pci_model is shown in [pci_find_cmd].
    5) Check whether the newly added PCI device works fine.
    6) PCI delete the device, verify whether could remove the PCI device.

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if module:
        session.cmd("modprobe %s" % module)

    # Get output of command 'info pci' as reference
    info_pci_ref = vm.monitor.info("pci")

    # Get output of command as reference
    reference = session.cmd_output(params.get("reference_cmd"))

    tested_model = params.get("pci_model")
    test_type = params.get("pci_type")
    image_format = params.get("image_format_stg")

    # Probe qemu to verify what is the supported syntax for PCI hotplug
    cmd_output = vm.monitor.cmd("?")
    if len(re.findall("\ndevice_add", cmd_output)) > 0:
        cmd_type = "device_add"
    elif len(re.findall("\npci_add", cmd_output)) > 0:
        cmd_type = "pci_add"
    else:
        raise error.TestError("Unknow version of qemu")

    # Determine syntax of drive hotplug
    # __com.redhat_drive_add == qemu-kvm-0.12 on RHEL 6
    if len(re.findall("\n__com.redhat_drive_add", cmd_output)) > 0:
        drive_cmd_type = "__com.redhat_drive_add"
    # drive_add == qemu-kvm-0.13 onwards
    elif len(re.findall("\ndrive_add", cmd_output)) > 0:
        drive_cmd_type = "drive_add"
    else:
        raise error.TestError("Unknow version of qemu")

    # Probe qemu for a list of supported devices
    devices_support = vm.monitor.cmd("%s ?" % cmd_type)

    if cmd_type == "pci_add":
        if test_type == "nic":
            pci_add_cmd = "pci_add pci_addr=auto nic model=%s" % tested_model
        elif test_type == "block":
            image_params = params.object_params("stg")
            image_filename = virt_utils.get_image_filename(image_params,
                                                       test.bindir)
            pci_add_cmd = ("pci_add pci_addr=auto storage file=%s,if=%s" %
                           (image_filename, tested_model))
        # Execute pci_add (should be replaced by a proper monitor method call)
        add_output = vm.monitor.cmd(pci_add_cmd)
        if not "OK domain" in add_output:
            raise error.TestFail("Add PCI device failed. "
                                 "Monitor command is: %s, Output: %r" %
                                 (pci_add_cmd, add_output))
        after_add = vm.monitor.info("pci")

    elif cmd_type == "device_add":
        driver_id = test_type + "-" + virt_utils.generate_random_id()
        device_id = test_type + "-" + virt_utils.generate_random_id()
        if test_type == "nic":
            if tested_model == "virtio":
                tested_model = "virtio-net-pci"
            pci_add_cmd = "device_add id=%s,driver=%s" % (device_id,
                                                          tested_model)

        elif test_type == "block":
            image_params = params.object_params("stg")
            image_filename = virt_utils.get_image_filename(image_params,
                                                       test.bindir)
            controller_model = None
            if tested_model == "virtio":
                tested_model = "virtio-blk-pci"

            if tested_model == "scsi":
                tested_model = "scsi-disk"
                controller_model = "lsi53c895a"
                if len(re.findall(controller_model, devices_support)) == 0:
                    raise error.TestError("scsi controller device (%s) not "
                                          "supported by qemu" %
                                          controller_model)

            if controller_model is not None:
                controller_id = "controller-" + device_id
                controller_add_cmd = ("device_add %s,id=%s" %
                                      (controller_model, controller_id))
                vm.monitor.cmd(controller_add_cmd)

            if drive_cmd_type == "drive_add":
                driver_add_cmd = ("drive_add auto "
                                  "file=%s,if=none,id=%s,format=%s" %
                                  (image_filename, driver_id, image_format))
            elif drive_cmd_type == "__com.redhat_drive_add":
                driver_add_cmd = ("__com.redhat_drive_add "
                                  "file=%s,format=%s,id=%s" %
                                  (image_filename, image_format, driver_id))

            pci_add_cmd = ("device_add id=%s,driver=%s,drive=%s" %
                           (device_id, tested_model, driver_id))
            vm.monitor.cmd(driver_add_cmd)

        # Check if the device is support in qemu
        if len(re.findall(tested_model, devices_support)) > 0:
            add_output = vm.monitor.cmd(pci_add_cmd)
        else:
            raise error.TestError("%s doesn't support device: %s" %
                                  (cmd_type, tested_model))
        after_add = vm.monitor.info("pci")

        if not device_id in after_add:
            raise error.TestFail("Add device failed. Monitor command is: %s"
                                 ". Output: %r" % (pci_add_cmd, add_output))

    # Define a helper function to delete the device
    def pci_del(ignore_failure=False):
        if cmd_type == "pci_add":
            result_domain, bus, slot, function = add_output.split(',')
            domain = int(result_domain.split()[2])
            bus = int(bus.split()[1])
            slot = int(slot.split()[1])
            pci_addr = "%x:%x:%x" % (domain, bus, slot)
            cmd = "pci_del pci_addr=%s" % pci_addr
        elif cmd_type == "device_add":
            cmd = "device_del %s" % device_id
        # This should be replaced by a proper monitor method call
        vm.monitor.cmd(cmd)

        def device_removed():
            after_del = vm.monitor.info("pci")
            return after_del != after_add

        if (not virt_utils.wait_for(device_removed, 10, 0, 1)
            and not ignore_failure):
            raise error.TestFail("Failed to hot remove PCI device: %s. "
                                 "Monitor command: %s" %
                                 (tested_model, cmd))

    try:
        # Compare the output of 'info pci'
        if after_add == info_pci_ref:
            raise error.TestFail("No new PCI device shown after executing "
                                 "monitor command: 'info pci'")

        # Define a helper function to compare the output
        def new_shown():
            o = session.cmd_output(params.get("reference_cmd"))
            return o != reference

        secs = int(params.get("wait_secs_for_hook_up"))
        if not virt_utils.wait_for(new_shown, 30, secs, 3):
            raise error.TestFail("No new device shown in output of command "
                                 "executed inside the guest: %s" %
                                 params.get("reference_cmd"))

        # Define a helper function to catch PCI device string
        def find_pci():
            o = session.cmd_output(params.get("find_pci_cmd"))
            return params.get("match_string") in o

        if not virt_utils.wait_for(find_pci, 30, 3, 3):
            raise error.TestFail("PCI %s %s device not found in guest. "
                                 "Command was: %s" %
                                 (tested_model, test_type,
                                  params.get("find_pci_cmd")))

        # Test the newly added device
        try:
            session.cmd(params.get("pci_test_cmd"))
        except aexpect.ShellError, e:
            raise error.TestFail("Check for %s device failed after PCI "
                                 "hotplug. Output: %r" % (test_type, e.output))

        session.close()