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
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
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
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
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
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
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
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]
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))
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
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