Beispiel #1
0
def check_device_was_created(test, uuid, adapter, domain):
    """
    Check if the device was created successfully

    :param test: test object
    :param uuid: id for mediated device
    :param adapter: adapter of crypto device in host
    :param domain: domain of crypto device in host
    """
    devices_cmd = ("cat /sys/devices/vfio_ap/matrix/%s/matrix" % uuid)
    status, output = utils_misc.cmd_status_output(devices_cmd, verbose=True)
    mdev_created_successfully = output == "%s.%s" % (adapter, domain)
    if not mdev_created_successfully:
        raise test.fail("mdev device was not create successfully through "
                        "nodev-API")
def check_dasd_partition_table(session, device_target):
    """
    Checks that the partition table can be read
    with 'fdasd'

    :param session: guest session, run command on host if None
    :param device_target: the expected target device name, e.g. 'vdb'
    """

    cmd = "fdasd -p /dev/%s" % device_target
    err, out = cmd_status_output(cmd, shell=True, session=session)
    if err or not re.findall("reading vtoc.*ok", out):
        raise TestError("Couldn't get partition table. %s" % out)
    logging.debug("Confirmed partition table was read correctly:")
    logging.debug(out)
Beispiel #3
0
def make_dasd_part(path, session):
    """
    Creates a partition spanning full disk on path

    :param path: dasd disk path, e.g. /dev/dasda
    :param session: guest session
    :return: True if partitioning succeeded
    """

    cmd = "fdasd -a %s" % path
    err, out = cmd_status_output(cmd, shell=True, session=session)
    if err:
        raise TestError("Couldn't create partition. Status code '%s'. %s." %
                        (err, out))
    return True
Beispiel #4
0
def set_vf_mac(ethname, mac_addr, vf_idx=0, session=None):
    """
    Set mac address for VF

    :param ethname: The name of the network interface
    :param mac_addr: The mac address to be set
    :param vf_idx: The index of VF
    :param session: The session object to the host
    :return: The command status and output
    """
    cmd = "ip link set {0} vf {1} mac {2}".format(ethname, vf_idx, mac_addr)
    return utils_misc.cmd_status_output(cmd,
                                        shell=True,
                                        verbose=True,
                                        session=session)
Beispiel #5
0
def get_iface_name(pci_id, session=None):
    """
    Get iface by the given pci

    :param pci_id: PCI ID of a device(eg. 0000:05:10.1)
    :param session: The session object to the host
    :return: The iface(eg. enp5s0f0)
    """
    cmd = "ls /sys/bus/pci/devices/%s/net" % pci_id
    status, iface_name = utils_misc.cmd_status_output(cmd,
                                                      shell=True,
                                                      session=session)
    if status:
        raise exceptions.TestError("Unable to get iface name of %s." % pci_id)
    return iface_name
Beispiel #6
0
def format_dasd(path, session):
    """
    Formats dasd disk and creates filesystem on path

    :param path: dasd disk path, e.g. /dev/dasda
    :param session: guest session
    :raises TestError: if disk can't be formatted
    :return: True if formatting succeeded
    """

    cmd = "dasdfmt -b 4096 -M quick --force -p -y %s" % path
    err, out = cmd_status_output(cmd, shell=True, session=session)
    if err:
        raise TestError("Couldn't format disk. %s" % out)
    return True
Beispiel #7
0
def set_vf(pci_addr, vf_no=4, session=None):
    """
    Enable VFs for PF

    :param pci_addr: The pci address
    :param vf_no: The value to be set
    :param session: The session object to the host
    :return: True if successful
    """
    logging.debug("pci_addr is %s", pci_addr)
    cmd = "echo %s > %s/sriov_numvfs" % (vf_no, pci_addr)
    s, o = utils_misc.cmd_status_output(cmd,
                                        shell=True,
                                        verbose=True,
                                        session=session)
    return not s
Beispiel #8
0
def get_vf_mac(ethname, vf_idx=0, session=None):
    """
    Get admin mac address for VF via 'ip' command.

    :param ethname: The name of the network interface
    :param vf_idx: The index of VF
    :param session: The session object to the host
    :return: VF's admin mac
    """
    cmd = "ip link show %s |awk '/vf %d/ {print $4}'" % (ethname, vf_idx)
    status, vf_mac = utils_misc.cmd_status_output(
            cmd, shell=True, verbose=True, session=session)

    if status or not vf_mac:
        raise exceptions.TestError("Unable to get VF's mac address. status: %s,"
                                   "stdout: %s." % (status, vf_mac))
    return vf_mac.strip()
Beispiel #9
0
    def set_online(chpids):
        """
        Sets all two digit chip ids configured.

        :param chpids: string of concatenated chipds, e.g. "11122122"
        :raises OSError: if some command call fails
        """

        ids = ChannelPaths._split(chpids)
        for i in ids:
            err, out = cmd_status_output("chchp -c 1 %s" % i,
                                         shell=True,
                                         timeout=CMD_TIMEOUT,
                                         verbose=VERBOSE)
            if err:
                raise OSError("Couldn't set all channel paths configured."
                              " %s" % out)
Beispiel #10
0
def get_pci_from_iface(iface, session=None):
    """
    Get pci by the given iface

    :param iface: The name of the network interface
    :param session: The session object to the host
    :return: Device's pci(eg. 0000:05:00.0)
    """
    cmd = "ethtool -i %s | awk '/bus-info/ {print $NF}'" % iface.strip()
    status, pci = utils_misc.cmd_status_output(cmd,
                                               shell=True,
                                               verbose=True,
                                               session=session)
    if status:
        raise exceptions.TestError("Unable to get device's pci. status: %s, "
                                   "stdout: %s." % (status, pci))
    return pci
Beispiel #11
0
def get_vf_pci_id(pf_pci, vf_index=0, session=None):
    """
    Get pci_id of VF

    :param pf_pci: The pci id of PF
    :param vf_index: VF's index
    :param session: The session object to the host
    :return: VF's pci id
    """
    cmd = "ls /sys/bus/pci/devices/{}/virtfn{}/net".format(pf_pci, vf_index)
    status, vf_name = utils_misc.cmd_status_output(cmd,
                                                   shell=True,
                                                   verbose=True,
                                                   session=session)
    if status or not vf_name:
        raise exceptions.TestError(
            "Unable to get VF. status: %s, stdout: %s." % (status, vf_name))
    return get_pci_from_iface(vf_name, session=session)
Beispiel #12
0
def set_vf(pci_addr, vf_no=4, session=None, timeout=60):
    """
    Enable VFs for PF

    :param pci_addr: The pci address
    :param vf_no: The value to be set
    :param session: The session object to the host
    :param timeout: Time limit in seconds to wait for cmd to complete
    :return: True if successful
    """
    LOG.debug("pci_addr is %s", pci_addr)
    cmd = "echo %s > %s/sriov_numvfs" % (vf_no, pci_addr)
    s, o = utils_misc.cmd_status_output(cmd,
                                        shell=True,
                                        timeout=timeout,
                                        verbose=True,
                                        session=session)
    return not s
Beispiel #13
0
def get_vf_pci_id(pf_pci, vf_index=0, session=None):
    """
    Get pci_id of VF

    :param pf_pci: The pci id of PF
    :param vf_index: VF's index
    :param session: The session object to the host
    :return: VF's pci id
    """
    cmd = "readlink /sys/bus/pci/devices/{}/virtfn{}".format(pf_pci, vf_index)
    status, tmp_vf = utils_misc.cmd_status_output(cmd,
                                                  shell=True,
                                                  verbose=True,
                                                  session=session)
    if status or not tmp_vf:
        raise exceptions.TestError(
            "Unable to get VF. status: %s, stdout: %s." % (status, tmp_vf))
    return os.path.basename(tmp_vf)
Beispiel #14
0
def virt_install_with_hostdev(vm_name, mdev_nodedev, target_address,
                              disk_path):
    """
    Runs virt-install with hostdev

    :param vm_name: guest name
    :param mdev_nodedev: mdev name as node device
    :param target_address: hostdev target address definition
    :param disk_path: path to the disk image for import
    """
    cmd = ("virt-install --import --name %s"
           " --hostdev %s,%s"
           " --disk %s"
           " --vcpus 2 --memory 2048"
           " --nographics --noautoconsole" %
           (vm_name, mdev_nodedev, target_address, disk_path))
    err, out = cmd_status_output(cmd, shell=True, verbose=True)
    if err:
        raise TestError("Couldn't install vm with hostdev: %s" % out)
Beispiel #15
0
def get_vcpu_line(vm_name, cmd, extra=''):
    """
    Get the <vcpu xxx> line in the dumpxml

    :param vm_name: the vm name
    :param cmd: the command to get vcpu line
    :param extra: the extra option for virsh command
    :return: str, the line in dumpxml with <vcpu xxx>
    """
    dumpxml_path = os.path.join(data_dir.get_tmp_dir(),
                                '{}.dumpxml'.format(vm_name))
    virsh.dumpxml(vm_name,
                  extra=extra,
                  to_file=dumpxml_path,
                  ignore_status=False)
    _, output = utils_misc.cmd_status_output(cmd + dumpxml_path,
                                             ignore_status=False)
    os.remove(dumpxml_path)
    return output
Beispiel #16
0
def read_write(session):
    """
    Writes, flushes and reads test file

    :param session: guest session
    :raises TestError: if read/write operation fails
    """

    TESTFILE = "%s/testfile" % MOUNT
    cmd1 = "echo kaixo > %s" % TESTFILE
    cmd2 = "sync %s" % TESTFILE
    cmd3 = "cat %s" % TESTFILE
    err, out = None, None
    for cmd in [cmd1, cmd2, cmd3]:
        err, out = cmd_status_output(cmd, shell=True, session=session)
        if err:
            raise TestError("Some read/write operation failed. %s" % out)
        if cmd == cmd3 and "kaixo" not in out:
            raise TestError("Didn't get the written value '%s'"
                            " from file '%s'" % ("kaixo", out))
Beispiel #17
0
    def get_info(self):
        """
        Gets crypto device info

        :return: CryptoDeviceInfo instance
        """
        info = CryptoDeviceInfo()
        err, out = cmd_status_output("lszcrypt -V",
                                     shell=True,
                                     session=self.session,
                                     timeout=CMD_TIMEOUT,
                                     verbose=VERBOSE)
        if err:
            if NO_DEVICES not in out:
                raise OSError("Error when running lszcrypt: %s" % out)
        else:
            out = out.strip().split('\n')[2:]
            for entry in out:
                info.append(entry)
        return info
Beispiel #18
0
    def set_standby(chpids):
        """
        Sets all two digit chip ids standby.

        WARNING: Be careful of using this function.
        Setting all chipds of a device removes the device fully.
        A simple reboot won't restore them.

        :param chpids: string of concatenated chipds, e.g. "11122122"
        :raises OSError: if some command call fails
        """

        ids = ChannelPaths._split(chpids)
        for i in ids:
            err, out = cmd_status_output("chchp -c 0 %s" % i,
                                         shell=True,
                                         timeout=CMD_TIMEOUT,
                                         verbose=VERBOSE)
            if err:
                raise OSError("Couldn't set all channel paths standby."
                              " %s" % out)
Beispiel #19
0
def create_disk(disk_type,
                path=None,
                size="500M",
                disk_format="raw",
                extra='',
                session=None):
    """
    Create disk on local or remote

    :param disk_type: Disk type
    :param path: The path of disk
    :param size: The size of disk
    :param disk_format: The format of disk
    :param extra: Extra parameters
    :param session: Session object to a remote host or guest
    :return: The path of disk
    :raise: TestError if the disk can't be created
    """

    if session:
        if disk_type == "file":
            disk_cmd = ("qemu-img create -f %s %s %s %s" %
                        (disk_format, extra, path, size))
        else:
            # TODO: Add implementation for other types
            raise exceptions.TestError("Unknown disk type %s" % disk_type)

        status, stdout = utils_misc.cmd_status_output(disk_cmd,
                                                      session=session)
        if status:
            raise exceptions.TestError(
                "Failed to create img on remote: cmd: {} "
                "status: {}, stdout: {}".format(disk_cmd, status, stdout))
        return path
    else:
        return libvirt.create_local_disk(disk_type,
                                         path=path,
                                         size=size,
                                         disk_format=disk_format,
                                         extra=extra)
Beispiel #20
0
 def get_info(self):
     """
     Calls lscss and stores lines
     """
     err, out = cmd_status_output("lscss", shell=True,
                                  session=self.session,
                                  timeout=CMD_TIMEOUT,
                                  verbose=VERBOSE)
     if err:
         raise OSError("Error when running lscss: %s" % out)
     # skip header and split according to HEADER
     self.devices = [[
         x[:8],
         x[9:17],
         x[19:26],
         x[27:34],
         x[35:38],
         x[40:42],
         x[44:46],
         x[48:50],
         x[53:61],
         x[62:]] for x in out.split("\n")[2:]]
def get_device_path(disk_id):
    """
    Gets the device path for the DASD disk

    :param disk_id: disk id cssid.ssid.devno, e.g. 0.0.5000
    :return: absolute device path, e.g. '/dev/dasda'
    """

    cmd = "lszdev %s" % disk_id
    err, out = cmd_status_output(cmd, shell=True)
    if err:
        raise TestError("Couldn't get device info. %s" % out)
    """ Expected output looks like:
    TYPE       ID        ON   PERS  NAMES
    dasd-eckd  0.0.5000  yes  yes   dasda
    """
    try:
        info = out.split('\n')
        values = re.split(r"\s+", info[1])
        name = values[-1]
        return "/dev/" + name
    except:
        raise TestError("Couldn't create device path from '%s', '%s', '%s'" %
                        (out, info, values))
Beispiel #22
0
def check_cmd_in_guest(cmd_in_guest, vm_session, params, test):
    """
    Execute a command within the guest and do checking

    :param cmd_in_guest: str, commands to execute in the VM
    :param vm_session: aexpect session for the VM
    :param params: dict, parameters to use
                  hidden_attr's value should be a dict
    :param test: test object
    :raises: test.fail if checkpoints fail
    """
    _, output = utils_misc.cmd_status_output(cmd_in_guest,
                                             shell=True,
                                             ignore_status=False,
                                             verbose=True,
                                             session=vm_session)
    logging.debug("Command '%s' result: %s", cmd_in_guest, output)
    hidden_attr = params.get('hidden_attr')
    if hidden_attr:
        (repl, found) = ('not', True) if hidden_attr['kvm_hidden_state'] == 'on' else ('', False)
        if output.count('KVM') == found:
            test.fail("'KVM' is %s expected when state is "
                      "%s" % (repl, hidden_attr['kvm_hidden_state']))
    logging.debug("Checking in check_cmd_in_guest() is successful.")
Beispiel #23
0
def run(test, params, env):
    """
    Test storage migration
    1) Do storage migration(copy-storage-all/copy-storage-inc) with
    TLS encryption - NBD transport
    2) Cancel storage migration with TLS encryption
    3) Copy only the top image for storage migration with backing chain

    :param test: test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """

    def prepare_nfs_backingfile(vm, params):
        """
        Create an image using nfs type backing_file

        :param vm: The guest
        :param params: the parameters used
        """
        mnt_path_name = params.get("nfs_mount_dir", "nfs-mount")
        exp_opt = params.get("export_options", "rw,no_root_squash,fsid=0")
        exp_dir = params.get("export_dir", "nfs-export")
        backingfile_img = params.get("source_dist_img", "nfs-img")
        disk_format = params.get("disk_format", "qcow2")
        img_name = params.get("img_name", "test.img")
        precreation = "yes" == params.get("precreation", "yes")
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
        disk_xml = vmxml.devices.by_device_tag('disk')[0]
        src_disk_format = disk_xml.xmltreefile.find('driver').get('type')
        first_disk = vm.get_first_disk_devices()
        blk_source = first_disk['source']
        disk_img = os.path.join(os.path.dirname(blk_source), img_name)

        res = libvirt.setup_or_cleanup_nfs(True, mnt_path_name, is_mount=True,
                                           export_options=exp_opt,
                                           export_dir=exp_dir)
        mnt_path = res["mount_dir"]
        params["selinux_status_bak"] = res["selinux_status_bak"]

        if vm.is_alive():
            vm.destroy(gracefully=False)

        disk_cmd = ("qemu-img convert -f %s -O %s %s %s/%s" %
                    (src_disk_format, disk_format,
                     blk_source, mnt_path, backingfile_img))
        process.run(disk_cmd, ignore_status=False, verbose=True)
        local_image_list.append("%s/%s" % (mnt_path, backingfile_img))
        logging.debug("Create a local image backing on NFS.")
        disk_cmd = ("qemu-img create -f %s -b %s/%s %s" %
                    (disk_format, mnt_path, backingfile_img, disk_img))
        process.run(disk_cmd, ignore_status=False, verbose=True)
        local_image_list.append(disk_img)
        if precreation:
            logging.debug("Create an image backing on NFS on remote host.")
            remote_session = remote.remote_login("ssh", server_ip, "22",
                                                 server_user, server_pwd,
                                                 r'[$#%]')
            utils_misc.make_dirs(os.path.dirname(blk_source), remote_session)
            status, stdout = utils_misc.cmd_status_output(
                disk_cmd, session=remote_session)
            logging.debug("status: {}, stdout: {}".format(status, stdout))
            remote_image_list.append("%s/%s" % (mnt_path, backingfile_img))
            remote_image_list.append(disk_img)
            remote_session.close()

        params.update({'disk_source_name': disk_img,
                       'disk_type': 'file',
                       'disk_source_protocol': 'file'})
        libvirt.set_vm_disk(vm, params)

    migration_test = migration.MigrationTest()
    migration_test.check_parameters(params)

    # Local variables
    server_ip = params["server_ip"] = params.get("remote_ip")
    server_user = params["server_user"] = params.get("remote_user", "root")
    server_pwd = params["server_pwd"] = params.get("remote_pwd")
    client_ip = params["client_ip"] = params.get("local_ip")
    client_pwd = params["client_pwd"] = params.get("local_pwd")
    virsh_options = params.get("virsh_options", "")
    copy_storage_option = params.get("copy_storage_option")
    extra = params.get("virsh_migrate_extra", "")
    options = params.get("virsh_migrate_options", "--live --verbose")
    backingfile_type = params.get("backingfile_type")
    check_str_local_log = params.get("check_str_local_log", "")
    disk_format = params.get("disk_format", "qcow2")
    log_file = params.get("log_outputs", "/var/log/libvirt/libvirtd.log")
    daemon_conf_dict = eval(params.get("daemon_conf_dict", '{}'))
    cancel_migration = "yes" == params.get("cancel_migration", "no")
    migrate_again = "yes" == params.get("migrate_again", "no")
    precreation = "yes" == params.get("precreation", "yes")
    tls_recovery = "yes" == params.get("tls_auto_recovery", "yes")
    func_params_exists = "yes" == params.get("func_params_exists", "no")
    status_error = "yes" == params.get("status_error", "no")

    local_image_list = []
    remote_image_list = []
    tls_obj = None

    func_name = None
    daemon_conf = None
    mig_result = None
    remote_session = None
    vm_session = None

    # params for migration connection
    params["virsh_migrate_desturi"] = libvirt_vm.complete_uri(
                                       params.get("migrate_dest_host"))
    dest_uri = params.get("virsh_migrate_desturi")

    vm_name = params.get("migrate_main_vm")
    vm = env.get_vm(vm_name)
    vm.verify_alive()

    extra = "{} {}".format(extra, copy_storage_option)

    extra_args = {}
    if func_params_exists:
        extra_args.update({'func_params': params})
    if cancel_migration:
        func_name = migration_test.do_cancel

    # For safety reasons, we'd better back up  xmlfile.
    vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    orig_config_xml = vmxml.copy()

    try:
        if backingfile_type:
            if backingfile_type == "nfs":
                prepare_nfs_backingfile(vm, params)

        if extra.count("copy-storage-all") and precreation:
            blk_source = vm.get_first_disk_devices()['source']
            vsize = utils_misc.get_image_info(blk_source).get("vsize")
            remote_session = remote.remote_login("ssh", server_ip, "22",
                                                 server_user, server_pwd,
                                                 r'[$#%]')
            utils_misc.make_dirs(os.path.dirname(blk_source), remote_session)
            disk_cmd = ("qemu-img create -f %s %s %s" %
                        (disk_format, blk_source, vsize))
            status, stdout = utils_misc.cmd_status_output(
                disk_cmd, session=remote_session)
            logging.debug("status: {}, stdout: {}".format(status, stdout))
            remote_image_list.append(blk_source)
            remote_session.close()

        # Update libvirtd configuration
        if daemon_conf_dict:
            if os.path.exists(log_file):
                os.remove(log_file)
            daemon_conf = libvirt.customize_libvirt_config(daemon_conf_dict)

        if extra.count("--tls"):
            tls_obj = TLSConnection(params)
            if tls_recovery:
                tls_obj.auto_recover = True
                tls_obj.conn_setup()

        if not vm.is_alive():
            vm.start()

        logging.debug("Guest xml after starting:\n%s",
                      vm_xml.VMXML.new_from_dumpxml(vm_name))
        # Check local guest network connection before migration
        vm_session = vm.wait_for_login(restart_network=True)
        migration_test.ping_vm(vm, params)

        # Execute migration process
        vms = [vm]

        migration_test.do_migration(vms, None, dest_uri, 'orderly',
                                    options, thread_timeout=900,
                                    ignore_status=True, virsh_opt=virsh_options,
                                    extra_opts=extra, func=func_name,
                                    **extra_args)

        mig_result = migration_test.ret
        migration_test.check_result(mig_result, params)

        if migrate_again and status_error:
            logging.debug("Sleeping 10 seconds before rerun migration")
            time.sleep(10)
            if cancel_migration:
                func_name = None
            params["status_error"] = "no"
            migration_test.do_migration(vms, None, dest_uri, 'orderly',
                                        options, thread_timeout=900,
                                        ignore_status=True,
                                        virsh_opt=virsh_options,
                                        extra_opts=extra, func=func_name,
                                        **extra_args)

            mig_result = migration_test.ret
            migration_test.check_result(mig_result, params)
        if int(mig_result.exit_status) == 0:
            migration_test.ping_vm(vm, params, uri=dest_uri)

        if check_str_local_log:
            libvirt.check_logfile(check_str_local_log, log_file)

    finally:
        logging.debug("Recover test environment")
        # Clean VM on destination and source
        try:
            migration_test.cleanup_dest_vm(vm, vm.connect_uri, dest_uri)
            if vm.is_alive():
                vm.destroy(gracefully=False)
        except Exception as err:
            logging.error(err)

        logging.info("Recovery VM XML configration")
        orig_config_xml.sync()

        if daemon_conf:
            logging.debug("Recover the configurations")
            libvirt.customize_libvirt_config(None, is_recover=True,
                                             config_object=daemon_conf)
        if tls_obj:
            logging.debug("Clean up local objs")
            del tls_obj
        for source_file in local_image_list:
            libvirt.delete_local_disk("file", path=source_file)
        for img in remote_image_list:
            remote.run_remote_cmd("rm -rf %s" % img, params)

        if remote_session:
            remote_session.close()
Beispiel #24
0
    def prepare_nfs_backingfile(vm, params):
        """
        Create an image using nfs type backing_file

        :param vm: The guest
        :param params: the parameters used
        """
        mnt_path_name = params.get("nfs_mount_dir", "nfs-mount")
        exp_opt = params.get("export_options", "rw,no_root_squash,fsid=0")
        exp_dir = params.get("export_dir", "nfs-export")
        backingfile_img = params.get("source_dist_img", "nfs-img")
        disk_format = params.get("disk_format", "qcow2")
        img_name = params.get("img_name", "test.img")
        precreation = "yes" == params.get("precreation", "yes")
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
        disk_xml = vmxml.devices.by_device_tag('disk')[0]
        src_disk_format = disk_xml.xmltreefile.find('driver').get('type')
        first_disk = vm.get_first_disk_devices()
        blk_source = first_disk['source']
        disk_img = os.path.join(os.path.dirname(blk_source), img_name)

        res = libvirt.setup_or_cleanup_nfs(True,
                                           mnt_path_name,
                                           is_mount=True,
                                           export_options=exp_opt,
                                           export_dir=exp_dir)
        mnt_path = res["mount_dir"]
        params["selinux_status_bak"] = res["selinux_status_bak"]

        if vm.is_alive():
            vm.destroy(gracefully=False)

        disk_cmd = ("qemu-img convert -f %s -O %s %s %s/%s" %
                    (src_disk_format, disk_format, blk_source, mnt_path,
                     backingfile_img))
        process.run(disk_cmd, ignore_status=False, verbose=True)
        local_image_list.append("%s/%s" % (mnt_path, backingfile_img))
        logging.debug("Create a local image backing on NFS.")
        disk_cmd = ("qemu-img create -f %s -b %s/%s %s" %
                    (disk_format, mnt_path, backingfile_img, disk_img))
        process.run(disk_cmd, ignore_status=False, verbose=True)
        local_image_list.append(disk_img)
        if precreation:
            logging.debug("Create an image backing on NFS on remote host.")
            remote_session = remote.remote_login("ssh", server_ip, "22",
                                                 server_user, server_pwd,
                                                 r'[$#%]')
            utils_misc.make_dirs(os.path.dirname(blk_source), remote_session)
            status, stdout = utils_misc.cmd_status_output(
                disk_cmd, session=remote_session)
            logging.debug("status: {}, stdout: {}".format(status, stdout))
            remote_image_list.append("%s/%s" % (mnt_path, backingfile_img))
            remote_image_list.append(disk_img)
            remote_session.close()

        params.update({
            'disk_source_name': disk_img,
            'disk_type': 'file',
            'disk_source_protocol': 'file'
        })
        libvirt.set_vm_disk(vm, params)
Beispiel #25
0
def run(test, params, env):
    """
    Test virsh migrate command.
    """

    def check_vm_network_accessed(session=None, ping_dest="www.baidu.com"):
        """
        The operations to the VM need to be done before or after
        migration happens

        :param session: The session object to the host
        :param ping_dest: The destination to be ping

        :raise: test.fail when ping fails
        """
        # Confirm local/remote VM can be accessed through network.
        logging.info("Check VM network connectivity")
        status, output = utils_test.ping(ping_dest,
                                         count=10,
                                         timeout=20,
                                         output_func=logging.debug,
                                         session=session)
        if status != 0:
            test.fail("Ping failed, status: %s,"
                      " output: %s" % (status, output))

    def get_vm_ifaces(session=None):
        """
        Get interfaces of vm

        :param session: The session object to the host
        :return: interfaces
        """
        p_iface, v_iface = utils_net.get_remote_host_net_ifs(session)

        return p_iface

    def check_vm_iface_num(iface_list, exp_num=3):
        """
        Check he number of interfaces

        :param iface_list: The interface list
        :param exp_num: The expected number
        :raise: test.fail when interfaces' number is not equal to exp_num
        """
        if len(iface_list) != exp_num:
            test.fail("%d interfaces should be found on the vm, "
                      "but find %s." % (exp_num, iface_list))

    def create_or_del_networks(pf_name, params, remote_virsh_session=None,
                               is_del=False):
        """
        Create or delete network on local or remote

        :param params: Dictionary with the test parameters
        :param pf_name: The name of PF
        :param remote_virsh_session: The virsh session object to the remote host
        :param is_del: Whether the networks should be deleted
        :raise: test.fail when fails to define/start network
        """
        net_hostdev_name = params.get("net_hostdev_name", "hostdev-net")
        net_hostdev_fwd = params.get("net_hostdev_fwd",
                                     '{"mode": "hostdev", "managed": "yes"}')
        net_bridge_name = params.get("net_bridge_name", "host-bridge")
        net_bridge_fwd = params.get("net_bridge_fwd", '{"mode": "bridge"}')
        bridge_name = params.get("bridge_name", "br0")

        net_dict = {"net_name": net_hostdev_name,
                    "net_forward": net_hostdev_fwd,
                    "net_forward_pf": '{"dev": "%s"}' % pf_name}
        bridge_dict = {"net_name": net_bridge_name,
                       "net_forward": net_bridge_fwd,
                       "net_bridge": '{"name": "%s"}' % bridge_name}

        if not is_del:
            for net_params in (net_dict, bridge_dict):
                net_dev = libvirt.create_net_xml(net_params.get("net_name"),
                                                 net_params)
                if not remote_virsh_session:
                    if net_dev.get_active():
                        net_dev.undefine()
                    net_dev.define()
                    net_dev.start()
                else:
                    remote.scp_to_remote(server_ip, '22', server_user, server_pwd,
                                         net_dev.xml, net_dev.xml, limit="",
                                         log_filename=None, timeout=600,
                                         interface=None)
                    remote_virsh_session.net_define(net_dev.xml, **virsh_args)
                    remote_virsh_session.net_start(net_params.get("net_name"),
                                                   **virsh_args)

        else:
            virsh_session = virsh
            if remote_virsh_session:
                virsh_session = remote_virsh_session
            for nname in (net_hostdev_name, net_bridge_name):
                if nname not in virsh_session.net_state_dict():
                    continue
                virsh_session.net_destroy(nname, debug=True, ignore_status=True)
                virsh_session.net_undefine(nname, debug=True, ignore_status=True)

    def check_vm_network_connection(net_name, expected_conn=0):
        """
        Check network connections in network xml

        :param net_name: The network to be checked
        :param expected_conn: The expected value
        :raise: test.fail when fails
        """
        output = virsh.net_dumpxml(net_name, debug=True).stdout_text
        if expected_conn == 0:
            reg_pattern = r"<network>"
        else:
            reg_pattern = r"<network connections='(\d)'>"
        res = re.findall(reg_pattern, output, re.I)
        if not res:
            test.fail("Unable to find expected connection in %s." % net_name)
        if expected_conn != 0:
            if expected_conn != int(res[0]):
                test.fail("Unable to get expected connection number."
                          "Expected: %s, Actual %s" % (expected_conn, int(res[0])))

    def get_hostdev_addr_from_xml():
        """
        Get VM hostdev address

        :return: pci driver id
        """
        address_dict = {}
        for ifac in vm_xml.VMXML.new_from_dumpxml(vm_name).devices.by_device_tag("interface"):
            if ifac.type_name == "hostdev":
                address_dict = ifac.hostdev_address.attrs

        return libvirt.pci_info_from_address(address_dict, 16, "id")

    def check_vfio_pci(pci_path, status_error=False):
        """
        Check if vf driver is vfio-pci

        :param pci_path: The absolute path of pci device
        :param status_error: Whether the driver should be vfio-pci
        """
        cmd = "readlink %s/driver | awk -F '/' '{print $NF}'" % pci_path
        output = process.run(cmd, shell=True, verbose=True).stdout_text.strip()
        if (output == "vfio-pci") == status_error:
            test.fail("Get incorrect dirver %s, it should%s be vfio-pci."
                      % (output, ' not' if status_error else ''))

    def update_iface_xml(vmxml):
        """
        Update interfaces for guest

        :param vmxml: vm_xml.VMXML object
        """
        vmxml.remove_all_device_by_type('interface')
        vmxml.sync()

        iface_dict = {"type": "network", "source": "{'network': 'host-bridge'}",
                      "mac": mac_addr, "model": "virtio",
                      "teaming": '{"type":"persistent"}',
                      "alias": '{"name": "ua-backup0"}',
                      "inbound": '{"average":"5"}',
                      "outbound": '{"average":"5"}'}

        iface_dict2 = {"type": "network", "source": "{'network': 'hostdev-net'}",
                       "mac": mac_addr, "model": "virtio",
                       "teaming": '{"type":"transient", "persistent": "ua-backup0"}'}

        iface = interface.Interface('network')
        for ifc in (iface_dict, iface_dict2):
            iface.xml = libvirt.modify_vm_iface(vm.name, "get_xml", ifc)
            vmxml.add_device(iface)
        vmxml.sync()

    migration_test = migration.MigrationTest()
    migration_test.check_parameters(params)

    # Params for NFS shared storage
    shared_storage = params.get("migrate_shared_storage", "")
    if shared_storage == "":
        default_guest_asset = defaults.get_default_guest_os_info()['asset']
        default_guest_asset = "%s.qcow2" % default_guest_asset
        shared_storage = os.path.join(params.get("nfs_mount_dir"),
                                      default_guest_asset)
        logging.debug("shared_storage:%s", shared_storage)

    # Params to update disk using shared storage
    params["disk_type"] = "file"
    params["disk_source_protocol"] = "netfs"
    params["mnt_path_name"] = params.get("nfs_mount_dir")

    # Local variables
    virsh_args = {"debug": True}
    virsh_options = params.get("virsh_options", "")

    server_ip = params.get("server_ip")
    server_user = params.get("server_user", "root")
    server_pwd = params.get("server_pwd")
    client_ip = params.get("client_ip")
    client_pwd = params.get("client_pwd")
    extra = params.get("virsh_migrate_extra")
    options = params.get("virsh_migrate_options")

    bridge_name = params.get("bridge_name", "br0")
    net_hostdev_name = params.get("net_hostdev_name", "hostdev-net")
    net_bridge_name = params.get("net_bridge_name", "host-bridge")
    driver = params.get("driver", "ixgbe")
    vm_tmp_file = params.get("vm_tmp_file", "/tmp/test.txt")
    cmd_during_mig = params.get("cmd_during_mig")
    net_failover_test = "yes" == params.get("net_failover_test", "no")
    cancel_migration = "yes" == params.get("cancel_migration", "no")
    try:
        vf_no = int(params.get("vf_no", "4"))
    except ValueError as e:
        test.error(e)

    migr_vm_back = "yes" == params.get("migrate_vm_back", "no")
    err_msg = params.get("err_msg")
    status_error = "yes" == params.get("status_error", "no")
    cmd_parms = {'server_ip': server_ip, 'server_user': server_user,
                 'server_pwd': server_pwd}
    remote_virsh_dargs = {'remote_ip': server_ip, 'remote_user': server_user,
                          'remote_pwd': server_pwd, 'unprivileged_user': None,
                          'ssh_remote_auth': True}
    destparams_dict = copy.deepcopy(params)

    remote_virsh_session = None
    vm_session = None
    vm = None
    mig_result = None
    func_name = None
    extra_args = {}
    default_src_vf = 0
    default_dest_vf = 0
    default_src_rp_filter = 1
    default_dest_rp_filer = 1

    if not libvirt_version.version_compare(6, 0, 0):
        test.cancel("This libvirt version doesn't support migration with "
                    "net failover devices.")

    # params for migration connection
    params["virsh_migrate_desturi"] = libvirt_vm.complete_uri(
                                       params.get("migrate_dest_host"))
    params["virsh_migrate_connect_uri"] = libvirt_vm.complete_uri(
                                       params.get("migrate_source_host"))
    src_uri = params.get("virsh_migrate_connect_uri")
    dest_uri = params.get("virsh_migrate_desturi")

    vm_name = params.get("migrate_main_vm")
    vm = env.get_vm(vm_name)
    vm.verify_alive()

    # For safety reasons, we'd better back up  xmlfile.
    new_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    orig_config_xml = new_xml.copy()

    try:
        # Create a remote runner for later use
        runner_on_target = remote.RemoteRunner(host=server_ip,
                                               username=server_user,
                                               password=server_pwd)

        server_session = remote.wait_for_login('ssh', server_ip, '22',
                                               server_user, server_pwd,
                                               r"[\#\$]\s*$")
        if net_failover_test:
            src_pf, src_pf_pci = utils_sriov.find_pf(driver)
            logging.debug("src_pf is %s. src_pf_pci: %s", src_pf, src_pf_pci)
            params['pf_name'] = src_pf
            dest_pf, dest_pf_pci = utils_sriov.find_pf(driver, server_session)
            logging.debug("dest_pf is %s. dest_pf_pci: %s", dest_pf, dest_pf_pci)
            destparams_dict['pf_name'] = dest_pf

            src_pf_pci_path = utils_misc.get_pci_path(src_pf_pci)
            dest_pf_pci_path = utils_misc.get_pci_path(dest_pf_pci, server_session)

            cmd = "cat %s/sriov_numvfs" % (src_pf_pci_path)
            default_src_vf = process.run(cmd, shell=True,
                                         verbose=True).stdout_text

            cmd = "cat %s/sriov_numvfs" % (dest_pf_pci_path)
            status, default_dest_vf = utils_misc.cmd_status_output(cmd,
                                                                   shell=True,
                                                                   session=server_session)
            if status:
                test.error("Unable to get default sriov_numvfs on target!"
                           "status: %s, output: %s" % (status, default_dest_vf))

            if not utils_sriov.set_vf(src_pf_pci_path, vf_no):
                test.error("Failed to set vf on source.")

            if not utils_sriov.set_vf(dest_pf_pci_path, vf_no, session=server_session):
                test.error("Failed to set vf on target.")

            # Create PF and bridge connection on source and target host
            cmd = 'cat /proc/sys/net/ipv4/conf/all/rp_filter'
            default_src_rp_filter = process.run(cmd, shell=True,
                                                verbose=True).stdout_text
            status, default_dest_rp_filter = utils_misc.cmd_status_output(cmd,
                                                                          shell=True,
                                                                          session=server_session)
            if status:
                test.error("Unable to get default rp_filter on target!"
                           "status: %s, output: %s" % (status, default_dest_rp_filter))
            cmd = 'echo 0 >/proc/sys/net/ipv4/conf/all/rp_filter'
            process.run(cmd, shell=True, verbose=True)
            utils_misc.cmd_status_output(cmd, shell=True, session=server_session)
            utils_sriov.add_or_del_connection(params, is_del=False)
            utils_sriov.add_or_del_connection(destparams_dict, is_del=False,
                                              session=server_session)

            if not remote_virsh_session:
                remote_virsh_session = virsh.VirshPersistent(**remote_virsh_dargs)
            create_or_del_networks(dest_pf, params,
                                   remote_virsh_session=remote_virsh_session)
            remote_virsh_session.close_session()
            create_or_del_networks(src_pf, params)
            # Change network interface xml
            mac_addr = utils_net.generate_mac_address_simple()
            update_iface_xml(new_xml)

        # Change the disk of the vm
        libvirt.set_vm_disk(vm, params)

        if not vm.is_alive():
            vm.start()

        # Check local guest network connection before migration
        if vm.serial_console is not None:
            vm.cleanup_serial_console()
        vm.create_serial_console()
        vm_session = vm.wait_for_serial_login(timeout=240)

        if net_failover_test:
            utils_net.restart_guest_network(vm_session)
        iface_list = get_vm_ifaces(vm_session)

        vm_ipv4, vm_ipv6 = utils_net.get_linux_ipaddr(vm_session, iface_list[0])
        check_vm_network_accessed(ping_dest=vm_ipv4)

        if net_failover_test:
            check_vm_iface_num(iface_list)
            check_vm_network_connection(net_hostdev_name, 1)
            check_vm_network_connection(net_bridge_name, 1)

            hostdev_pci_id = get_hostdev_addr_from_xml()
            vf_path = utils_misc.get_pci_path(hostdev_pci_id)
            check_vfio_pci(vf_path)
            if cmd_during_mig:
                s, o = utils_misc.cmd_status_output(cmd_during_mig, shell=True,
                                                    session=vm_session)
                if s:
                    test.fail("Failed to run %s in vm." % cmd_during_mig)

        if extra.count("--postcopy"):
            func_name = virsh.migrate_postcopy
            extra_args.update({'func_params': params})
        if cancel_migration:
            func_name = migration_test.do_cancel

        # Execute migration process
        vms = [vm]

        migration_test.do_migration(vms, None, dest_uri, 'orderly',
                                    options, thread_timeout=900,
                                    ignore_status=True, virsh_opt=virsh_options,
                                    func=func_name, extra_opts=extra,
                                    **extra_args)
        mig_result = migration_test.ret

        migration_test.check_result(mig_result, params)

        if int(mig_result.exit_status) == 0:
            server_session = remote.wait_for_login('ssh', server_ip, '22',
                                                   server_user, server_pwd,
                                                   r"[\#\$]\s*$")
            check_vm_network_accessed(server_session, vm_ipv4)
            server_session.close()
            if net_failover_test:
                # Check network connection
                check_vm_network_connection(net_hostdev_name)
                check_vm_network_connection(net_bridge_name)
                # VF driver should not be vfio-pci
                check_vfio_pci(vf_path, True)

                cmd_parms.update({'vm_ip': vm_ipv4,
                                  'vm_pwd': params.get("password")})
                vm_after_mig = remote.VMManager(cmd_parms)
                vm_after_mig.setup_ssh_auth()
                cmd = "ip link"
                cmd_result = vm_after_mig.run_command(cmd)
                libvirt.check_result(cmd_result)
                p_iface = re.findall(r"\d+:\s+(\w+):\s+.*", cmd_result.stdout_text)
                p_iface = [x for x in p_iface if x != 'lo']
                check_vm_iface_num(p_iface)

                # Check the output of ping command
                cmd = 'cat %s' % vm_tmp_file
                cmd_result = vm_after_mig.run_command(cmd)
                libvirt.check_result(cmd_result)

                if re.findall('Destination Host Unreachable', cmd_result.stdout_text, re.M):
                    test.fail("The network does not work well during "
                              "the migration peirod. ping output: %s"
                              % cmd_result.stdout_text)

            # Execute migration from remote
            if migr_vm_back:
                ssh_connection = utils_conn.SSHConnection(server_ip=client_ip,
                                                          server_pwd=client_pwd,
                                                          client_ip=server_ip,
                                                          client_pwd=server_pwd)
                try:
                    ssh_connection.conn_check()
                except utils_conn.ConnectionError:
                    ssh_connection.conn_setup()
                    ssh_connection.conn_check()

                # Pre migration setup for local machine
                migration_test.migrate_pre_setup(src_uri, params)

                cmd = "virsh migrate %s %s %s" % (vm_name,
                                                  virsh_options, src_uri)
                logging.debug("Start migration: %s", cmd)
                cmd_result = remote.run_remote_cmd(cmd, params, runner_on_target)
                logging.info(cmd_result)
                if cmd_result.exit_status:
                    test.fail("Failed to run '%s' on remote: %s"
                              % (cmd, cmd_result))
                logging.debug("migration back done")
                check_vm_network_accessed(ping_dest=vm_ipv4)
                if net_failover_test:
                    if vm_session:
                        vm_session.close()
                    vm_session = vm.wait_for_login()
                    iface_list = get_vm_ifaces(vm_session)
                    check_vm_iface_num(iface_list)

        else:
            check_vm_network_accessed(ping_dest=vm_ipv4)
            if net_failover_test:
                iface_list = get_vm_ifaces(vm_session)
                check_vm_iface_num(iface_list)

    finally:
        logging.debug("Recover test environment")
        # Clean VM on destination
        migration_test.cleanup_dest_vm(vm, vm.connect_uri, dest_uri)

        if vm.is_alive():
            vm.destroy(gracefully=False)

        logging.info("Recovery VM XML configration")
        orig_config_xml.sync()
        logging.debug("The current VM XML:\n%s", orig_config_xml.xmltreefile)

        server_session = remote.wait_for_login('ssh', server_ip, '22',
                                               server_user, server_pwd,
                                               r"[\#\$]\s*$")
        if 'src_pf' in locals():
            cmd = 'echo %s  >/proc/sys/net/ipv4/conf/all/rp_filter' % default_src_rp_filter
            process.run(cmd, shell=True, verbose=True)
            utils_sriov.add_or_del_connection(params, is_del=True)
            create_or_del_networks(src_pf, params, is_del=True)

        if 'dest_pf' in locals():
            cmd = 'echo %s  >/proc/sys/net/ipv4/conf/all/rp_filter' % default_dest_rp_filter
            utils_misc.cmd_status_output(cmd, shell=True, session=server_session)
            utils_sriov.add_or_del_connection(destparams_dict, session=server_session,
                                              is_del=True)
            remote_virsh_session = virsh.VirshPersistent(**remote_virsh_dargs)
            create_or_del_networks(dest_pf, params,
                                   remote_virsh_session,
                                   is_del=True)
            remote_virsh_session.close_session()

        if 'dest_pf_pci_path' in locals() and default_dest_vf != vf_no:
            utils_sriov.set_vf(dest_pf_pci_path, default_dest_vf, server_session)
        if 'src_pf_pci_path' in locals() and default_src_vf != vf_no:
            utils_sriov.set_vf(src_pf_pci_path, default_src_vf)

        # Clean up of pre migration setup for local machine
        if migr_vm_back:
            if 'ssh_connection' in locals():
                ssh_connection.auto_recover = True
            migration_test.migrate_pre_setup(src_uri, params,
                                             cleanup=True)

        server_session.close()
        if remote_virsh_session:
            remote_virsh_session.close_session()

        logging.info("Remove local NFS image")
        source_file = params.get("source_file")
        if source_file:
            libvirt.delete_local_disk("file", path=source_file)
Beispiel #26
0
def get_forward_value():
    """
    Reads sysfs for forward value
    """
    cmd = "cat /sys/kernel/debug/kvm/diag_9c_forward"
    return cmd_status_output(cmd, shell=True)
def get_forward_value():
    """
    Reads sysfs for forward value
    """
    cmd = "cat %s" % FORWARD_VALUE_PATH
    return cmd_status_output(cmd, shell=True)
Beispiel #28
0
def run(test, params, env):
    """
    Test the libvirt API to report deprecation status of machine-types and
    devices.
    """
    libvirt_version.is_libvirt_feature_supported(params)
    vm_name = params.get("main_vm")
    deprecated_domain = params.get("deprecated_domain", "no") == "yes"
    check = params.get("check", "no") == "yes"
    vm = env.get_vm(vm_name)

    if vm.is_alive():
        vm.destroy()
    backup_xml = libvirt_xml.VMXML.new_from_dumpxml(vm_name)
    deprecated_vm = backup_xml.copy()

    try:
        vm.start()
        vm.wait_for_login().close()
        if check:
            qmp_cmd = params.get("qmp_cmd")
            domain_tree = params.get("domain_tree")
            virsh_function = params.get("virsh_function")
            # Get a list of deprecated CPU architectures/machine types by
            # executing QMP command
            qmp_list = get_deprecated_name_list_qmp(vm_name, qmp_cmd)
            # and (dom)capabilities
            domain_list = get_deprecated_domain_capabilities_list(
                eval(virsh_function), domain_tree)
            check_deprecated_output(test, qmp_list, domain_list)

        if deprecated_domain:
            deprecated_list = prepare_deprecated_vm_xml_and_provide_deprecated_list(
                params, deprecated_vm)
            if not deprecated_list:
                test.cancel("There is no deprecated cpu or machine type in "
                            "current qemu version, skipping the test.")
            # No "Messages" in the output since the default VM is still running.
            check_dominfo(test, vm_name, deprecated_list, empty=True)
            vm.destroy()
            # Update VM with a deprecated items and check dominfo
            deprecated_vm.sync()
            logging.debug("vm xml is %s", deprecated_vm)
            vm.start()
            vm.wait_for_login().close()
            check_dominfo(test, vm_name, deprecated_list)
            # Reboot the VM and check a dominfo again
            vm.reboot()
            check_dominfo(test, vm_name, deprecated_list)
            # Restart libvirtd and check a dominfo again
            libvirtd = utils_libvirtd.Libvirtd()
            libvirtd.restart()
            check_dominfo(test, vm_name, deprecated_list)
            # Save a VM to file and check a dominfo - No "Messages"
            deprecated_vm_file = "deprecated_vm"
            vm.save_to_file(deprecated_vm_file)
            check_dominfo(test, vm_name, deprecated_list, empty=True)
            # Restore a VM from file and check dominfo
            vm.restore_from_file(deprecated_vm_file)
            check_dominfo(test, vm_name, deprecated_list)
            # Destroy VM and check dominfo - No "Messages"
            vm.destroy()
            check_dominfo(test, vm_name, deprecated_list, empty=True)
            # Start the VM and shut it down internally - No "Messages" in
            # dominfo output
            vm.start()
            session = vm.wait_for_login()
            utils_misc.cmd_status_output("shutdown now", session=session)
            utils_misc.wait_for(lambda: vm.state() == 'shut off', 60)
            check_dominfo(test, vm_name, deprecated_list, empty=True)

    except (exceptions.TestFail, exceptions.TestCancel):
        raise
    except Exception as e:
        test.error('Unexpected error: {}'.format(e))
    finally:
        if vm.is_alive:
            vm.destroy()
        backup_xml.sync()