Beispiel #1
0
def get_vf_pcis_list(pf_name):
    vf_pcis_list = []
    pf_files = os.listdir(common.get_dev_path(pf_name, "_device"))
    for pf_file in pf_files:
        if pf_file.startswith("virtfn"):
            vf_info = common.get_file_data(common.get_dev_path(pf_name,
                                           f"{pf_file}/uevent"))
            vf_pcis_list.append(re.search(r'PCI_SLOT_NAME=(.*)',
                                          vf_info, re.MULTILINE).group(1))
    return vf_pcis_list
Beispiel #2
0
def _is_available_nic(interface_name, check_active=True):
    try:
        if interface_name == 'lo':
            return False

        if not is_real_nic(interface_name):
            return False

        operstate = None
        with open(common.get_dev_path(interface_name, '_operstate'), 'r') as f:
            operstate = f.read().rstrip().lower()
        if check_active and operstate != 'up':
            return False

        # If SR-IOV Virtual Functions (VF) are enabled in an interface, there
        # will be additional nics created for each VF. It has to be ignored in
        # the nic numbering. All the VFs will have a reference to the PF with
        # directory name as 'physfn', if this directory is present it should be
        # ignored.
        if common.is_vf_by_name(interface_name):
            return False

        # nic is available
        return True

    except IOError:
        return False
Beispiel #3
0
def is_real_nic(interface_name):
    if interface_name == 'lo':
        return True

    device_dir = common.get_dev_path(interface_name, '_device')
    has_device_dir = os.path.isdir(device_dir)

    address = None
    try:
        with open(common.get_dev_path(interface_name, "_address"), 'r') as f:
            address = f.read().rstrip()
    except IOError:
        return False

    if has_device_dir and address:
        return True
    else:
        return False
Beispiel #4
0
def _is_vf_by_name(interface_name, check_mapping_file=False):
    vf_path_check = common.get_dev_path(interface_name, 'physfn')
    is_sriov_vf = os.path.isdir(vf_path_check)
    if not is_sriov_vf and check_mapping_file:
        sriov_map = common.get_sriov_map()
        for item in sriov_map:
            if (item['name'] == interface_name
                    and item['device_type'] == 'vf'):
                is_sriov_vf = True
    return is_sriov_vf
Beispiel #5
0
def get_interface_driver(ifname):
    try:
        uevent = common.get_dev_path(ifname, 'device/uevent')
        with open(uevent, 'r') as f:
            out = f.read().strip()
            for line in out.split('\n'):
                if 'DRIVER' in line:
                    driver = line.split('=')
                    if len(driver) == 2:
                        return driver[1]
    except IOError:
        return
Beispiel #6
0
def set_numvfs(ifname, numvfs):
    """Setting sriov_numvfs for PF

    Wrapper that will set the sriov_numvfs file for a PF.

    After numvfs has been set for an interface, _wait_for_vf_creation will be
    called to monitor the creation.

    Some restrictions:
    - if current number of VF is already defined, we can't change numvfs
    - if sriov_numvfs doesn't exist for an interface, we can't create it

    :param ifname: interface name (ie: p1p1)
    :param numvfs: an int that represents the number of VFs to be created.
    :returns: int -- the number of current VFs on ifname
    :raises: SRIOVNumvfsException
    """
    curr_numvfs = get_numvfs(ifname)
    logger.debug(f"{ifname}: Interface has {curr_numvfs} configured, setting "
                 f"to {numvfs}")
    if not isinstance(numvfs, int):
        msg = (f"{ifname}: Unable to configure pf with numvfs: {numvfs}\n"
               f"numvfs must be an integer")
        raise SRIOVNumvfsException(msg)

    if numvfs != curr_numvfs:
        if curr_numvfs != 0:
            logger.warning(f"{ifname}: Numvfs already configured to "
                           f"{curr_numvfs}")
            return curr_numvfs

        sriov_numvfs_path = common.get_dev_path(ifname, "sriov_numvfs")
        try:
            logger.debug(f"Setting {sriov_numvfs_path} to {numvfs}")
            with open(sriov_numvfs_path, "w") as f:
                f.write("%d" % numvfs)
        except IOError as exc:
            msg = (f"{ifname} Unable to configure pf  with numvfs: {numvfs}\n"
                   f"{exc}")
            raise SRIOVNumvfsException(msg)

        _wait_for_vf_creation(ifname, numvfs)
        curr_numvfs = get_numvfs(ifname)
        if curr_numvfs != numvfs:
            msg = (f"{ifname}: Unable to configure pf with numvfs: {numvfs}\n"
                   "sriov_numvfs file is not set to the targeted number of "
                   "vfs")
            raise SRIOVNumvfsException(msg)
    return curr_numvfs
Beispiel #7
0
def get_numvfs(ifname):
    """Getting sriov_numvfs for PF

    Wrapper that will get the sriov_numvfs file for a PF.

    :param ifname: interface name (ie: p1p1)
    :returns: int -- the number of current VFs on ifname
    :raises: SRIOVNumvfsException
    """
    sriov_numvfs_path = common.get_dev_path(ifname, "sriov_numvfs")
    logger.debug(f"{ifname}: Getting numvfs for interface")
    try:
        with open(sriov_numvfs_path, 'r') as f:
            curr_numvfs = int(f.read())
    except IOError as exc:
        msg = f"{ifname}: Unable to read numvfs: {exc}"
        raise SRIOVNumvfsException(msg)
    logger.debug(f"{ifname}: Interface has {curr_numvfs} configured")
    return curr_numvfs
Beispiel #8
0
def get_vf_devname(pf_name, vfid):
    vf_path = common.get_dev_path(pf_name, f"virtfn{vfid}/net")
    if os.path.isdir(vf_path):
        vf_nic = os.listdir(vf_path)
    else:
        # if VF devices are bound with other drivers (DPDK) then the path
        # doesn't exist. In such cases let us retrieve the vf name stored in
        # the map
        vf_name = _get_vf_name_from_map(pf_name, vfid)
        if vf_name is not None:
            return vf_name
        else:
            msg = "NIC %s with VF id: %d could not be found" % (pf_name, vfid)
            raise SriovVfNotFoundException(msg)
    if len(vf_nic) != 1:
        msg = "VF name could not be identified in %s" % vf_path
        raise SriovVfNotFoundException(msg)
    # The VF's actual device name shall be the only directory seen in the path
    # /sys/class/net/<pf_name>/device/virtfn<vfid>/net
    return vf_nic[0]
Beispiel #9
0
def add_udev_rule_for_vf_representors(pf_name):
    logger.info(f"{pf_name}: adding udev rules for vf representators")
    phys_switch_id_path = common.get_dev_path(pf_name, "_phys_switch_id")
    phys_switch_id = common.get_file_data(phys_switch_id_path).strip()
    pf_pci = get_pf_pci(pf_name)
    pf_fun_num_match = PF_FUNC_RE.search(pf_pci)
    if not pf_fun_num_match:
        logger.error(f"{pf_name}: Failed to get function number "
                     "and so failed to create a udev rule for renaming "
                     "its vf-represent")
        return

    pf_fun_num = pf_fun_num_match.group(1)
    udev_data_line = 'SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}'\
                     '=="%s", ATTR{phys_port_name}=="pf%svf*", '\
                     'IMPORT{program}="%s $attr{phys_port_name}", '\
                     'NAME="%s_$env{NUMBER}"' % (phys_switch_id,
                                                 pf_fun_num,
                                                 _REP_LINK_NAME_FILE,
                                                 pf_name)
    create_rep_link_name_script()
    return add_udev_rule(udev_data_line, _UDEV_RULE_FILE)
 def _write_numvfs(self, ifname, numvfs=0):
     os.makedirs(common.get_dev_path(ifname, '_device'))
     numvfs_file = common.get_dev_path(ifname, 'sriov_numvfs')
     with open(numvfs_file, 'w') as f:
         f.write(str(numvfs))
Beispiel #11
0
def get_pf_device_id(pf_name):
    pf_device_path = common.get_dev_path(pf_name, "device")
    pf_device_id = common.get_file_data(pf_device_path).strip()
    return pf_device_id
Beispiel #12
0
def get_pf_pci(pf_name):
    pf_pci_path = common.get_dev_path(pf_name, "uevent")
    pf_info = common.get_file_data(pf_pci_path)
    pf_pci = re.search(r'PCI_SLOT_NAME=(.*)', pf_info, re.MULTILINE).group(1)
    return pf_pci