Exemple #1
0
def restart_ovs_and_pfs_netdevs():
    sriov_map = common.get_sriov_map()
    processutils.execute('/usr/bin/systemctl', 'restart', 'openvswitch')
    for item in sriov_map:
        if item['device_type'] == 'pf':
            if_down_interface(item['name'])
            if_up_interface(item['name'])
Exemple #2
0
def _get_vf_name_from_map(pf_name, vfid):
    sriov_map = common.get_sriov_map()
    for item in sriov_map:
        if (item['device_type'] == 'vf'
                and item['device'].get('name') == pf_name
                and item['device'].get('vfid') == vfid):
            return item['name']
Exemple #3
0
def update_sriov_pf_map(ifname,
                        numvfs,
                        noop,
                        promisc=None,
                        link_mode='legacy',
                        vdpa=False):
    if not noop:
        cur_numvfs = sriov_config.get_numvfs(ifname)
        if cur_numvfs > 0 and cur_numvfs != numvfs:
            msg = ("Can't change the numvfs for %s" % ifname)
            raise sriov_config.SRIOVNumvfsException(msg)
        sriov_map = common.get_sriov_map()
        for item in sriov_map:
            if item['device_type'] == 'pf' and item['name'] == ifname:
                item['numvfs'] = numvfs
                item['vdpa'] = vdpa
                if promisc is not None:
                    item['promisc'] = promisc
                item['link_mode'] = link_mode
                break
        else:
            new_item = {}
            new_item['device_type'] = 'pf'
            new_item['name'] = ifname
            new_item['numvfs'] = numvfs
            new_item['vdpa'] = vdpa
            if promisc is not None:
                new_item['promisc'] = promisc
            new_item['link_mode'] = link_mode
            sriov_map.append(new_item)

        write_yaml_config(common.SRIOV_CONFIG_FILE, sriov_map)
Exemple #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
Exemple #5
0
def _wait_for_vf_creation(pf_name, numvfs):
    vf_count = 0
    pf_config = common.get_sriov_map(pf_name)
    vdpa = False
    if len(pf_config):
        vdpa = pf_config[0].get('vdpa', False)
    while vf_count < numvfs:
        try:
            # wait for 5 seconds after every udev event
            event = vf_queue.get(True, 5)
            vf_name = os.path.basename(event["device"])
            pf_path = _get_pf_path(event["device"])
            logger.debug(f"{event['device']}: Got udev event: {event}")
            if pf_path:
                pf_nic = os.listdir(pf_path)
                # NOTE(dvd): For vDPA devices, the VF event we're interrested
                # in contains all the VFs. We can also use this to build a dict
                # to correlate the VF pci address to the PF when creating the
                # vdpa representator udev rule
                #
                # Data structure sample for vDPA:
                # pf_path:
                #   /sys/devices/pci0000:00/0000:00:02.2/0000:06:01.2/physfn/net
                # pf_nic: ['enp6s0f1np1_0', 'enp6s0f1np1_1', 'enp6s0f1np1']
                # pf_name: enp6s0f1np1
                if vf_name not in vf_to_pf and pf_name in pf_nic:
                    vf_to_pf[vf_name] = {
                        'device': event['device'],
                        'pf': pf_name
                    }
                    logger.info(
                        f"{pf_name}: VF {vf_name} created"
                    )
                    vf_count += 1
                elif vf_name in vf_to_pf:
                    logger.debug(
                        f"{pf_name}: VF {vf_name} was already created"
                    )
                elif vdpa:
                    logger.warning(f"{pf_name}: This PF is not in {pf_path}")
                else:
                    logger.warning(
                        f"{pf_name}: Unable to parse event {event['device']}"
                    )
            elif not vdpa:
                logger.warning(f"{event['device']}: Unable to find PF")
        except queue.Empty:
            logger.info(f"{pf_name}: Timeout in the creation of VFs")
            return
    logger.info(f"{pf_name}: Required VFs are created")
Exemple #6
0
def is_partitioned_pf(dev_name: str) -> bool:
    """Check if any nic-partition(VF) is already used

    Given a PF device, returns True if any VFs of this
    device are in-use.
    """
    sriov_map = common.get_sriov_map()
    for config in sriov_map:
        devtype = config.get('device_type', None)
        if devtype == 'vf':
            name = config.get('device', {}).get('name')
            vf_name = config.get('name')
            if dev_name == name:
                logger.warning(f"{name} has VF({vf_name}) used by host")
                return True
    return False
Exemple #7
0
def configure_sriov_vf():
    sriov_map = common.get_sriov_map()
    for item in sriov_map:
        raise_error = True
        if item['device_type'] == 'vf':
            pf_name = item['device']['name']
            vfid = item['device']['vfid']
            base_cmd = ('ip', 'link', 'set', 'dev', pf_name, 'vf', str(vfid))
            logger.info(f"{pf_name}: Configuring settings for VF: {vfid} "
                        f"VF name: {item['name']}")
            raise_error = True
            if 'macaddr' in item:
                cmd = base_cmd + ('mac', item['macaddr'])
                run_ip_config_cmd(*cmd)
            if 'vlan_id' in item:
                vlan_cmd = base_cmd + ('vlan', str(item['vlan_id']))
                if 'qos' in item:
                    vlan_cmd = vlan_cmd + ('qos', str(item['qos']))
                run_ip_config_cmd(*vlan_cmd)
            if 'max_tx_rate' in item:
                cmd = base_cmd + ('max_tx_rate', str(item['max_tx_rate']))
                if item['max_tx_rate'] == 0:
                    raise_error = False
                run_ip_config_cmd_safe(raise_error, *cmd)
            if 'min_tx_rate' in item:
                cmd = base_cmd + ('min_tx_rate', str(item['min_tx_rate']))
                if item['min_tx_rate'] == 0:
                    raise_error = False
                run_ip_config_cmd_safe(raise_error, *cmd)
            if 'spoofcheck' in item:
                cmd = base_cmd + ('spoofchk', item['spoofcheck'])
                run_ip_config_cmd(*cmd)
            if 'state' in item:
                cmd = base_cmd + ('state', item['state'])
                run_ip_config_cmd(*cmd)
            if 'trust' in item:
                cmd = base_cmd + ('trust', item['trust'])
                run_ip_config_cmd(*cmd)
            if 'promisc' in item:
                run_ip_config_cmd('ip', 'link', 'set', 'dev', item['name'],
                                  'promisc', item['promisc'])
            if 'driver' in item:
                common.set_driverctl_override(item['pci_address'],
                                              item['driver'])
Exemple #8
0
def update_sriov_vf_map(pf_name,
                        vfid,
                        vf_name,
                        vlan_id=0,
                        qos=0,
                        spoofcheck=None,
                        trust=None,
                        state=None,
                        macaddr=None,
                        promisc=None,
                        pci_address=None,
                        min_tx_rate=0,
                        max_tx_rate=0,
                        driver=None):
    sriov_map = common.get_sriov_map()
    for item in sriov_map:
        if (item['device_type'] == 'vf'
                and item['device'].get('name') == pf_name
                and item['device'].get('vfid') == vfid):
            item.update(
                _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state,
                               macaddr, promisc, pci_address, min_tx_rate,
                               max_tx_rate, driver))
            _clear_empty_values(item)
            break
    else:
        new_item = {}
        new_item['device_type'] = 'vf'
        new_item['device'] = {"name": pf_name, "vfid": vfid}
        new_item.update(
            _set_vf_fields(vf_name, vlan_id, qos, spoofcheck, trust, state,
                           macaddr, promisc, pci_address, min_tx_rate,
                           max_tx_rate, driver))
        _clear_empty_values(new_item)
        sriov_map.append(new_item)

    write_yaml_config(common.SRIOV_CONFIG_FILE, sriov_map)
Exemple #9
0
def configure_sriov_pf(execution_from_cli=False, restart_openvswitch=False):
    observer = udev_monitor_setup()
    udev_monitor_start(observer)

    sriov_map = common.get_sriov_map()
    dpdk_vfs_pcis_list = []
    trigger_udev_rule = False

    # Cleanup the previous config by puppet-tripleo
    cleanup_puppet_config()
    if any(item.get('vdpa') for item in sriov_map):
        common.load_kmods(MLNX5_VDPA_KMODS)
        vdpa_devices = get_vdpa_vhost_devices()

    for item in sriov_map:
        if item['device_type'] == 'pf':
            _pf_interface_up(item)
            if item.get('link_mode') == "legacy":
                # Add a udev rule to configure the VF's when PF's are
                # released by a guest
                if not is_partitioned_pf(item['name']):
                    add_udev_rule_for_legacy_sriov_pf(item['name'],
                                                      item['numvfs'])
            # When configuring vdpa, we need to configure switchdev before
            # we create the VFs
            is_mlnx = common.is_mellanox_interface(item['name'])
            vdpa = item.get('vdpa')
            # Configure switchdev mode when vdpa
            # It has to happen before we set_numvfs
            if vdpa and is_mlnx:
                configure_switchdev(item['name'])
            set_numvfs(item['name'], item['numvfs'])
            # Configure switchdev, unbind driver and configure vdpa
            if item.get('link_mode') == "switchdev" and is_mlnx:
                logger.info(f"{item['name']}: Mellanox card")
                vf_pcis_list = get_vf_pcis_list(item['name'])
                for vf_pci in vf_pcis_list:
                    if not vdpa:
                        # For DPDK, we need to unbind the driver
                        _driver_unbind(vf_pci)
                    else:
                        if vf_pci not in vdpa_devices:
                            configure_vdpa_vhost_device(vf_pci)
                        else:
                            logger.info(
                                f"{item['name']}: vDPA device already created "
                                f"for {vf_pci}"
                            )
                if vdpa:
                    common.restorecon('/dev/vhost-*')
                logger.info(f"{item['name']}: Adding udev rules")
                # Adding a udev rule to make vf-representors unmanaged by
                # NetworkManager
                add_udev_rule_to_unmanage_vf_representors_by_nm()

                # Adding a udev rule to save the sriov_pf name
                trigger_udev_rule = add_udev_rule_for_sriov_pf(item['name'])\
                    or trigger_udev_rule

                trigger_udev_rule = add_udev_rule_for_vf_representors(
                    item['name']) or trigger_udev_rule

                if not vdpa:
                    # This is used for the sriov_bind_config
                    dpdk_vfs_pcis_list += vf_pcis_list

                    # Configure flow steering mode, default to smfs
                    configure_flow_steering(item['name'],
                                            item.get('steering_mode', 'smfs'))

                    # Configure switchdev mode
                    configure_switchdev(item['name'])
                    # Adding a udev rule to rename vf-representors
                else:
                    trigger_udev_rule = add_udev_rule_for_vdpa_representors(
                        item['name']) or trigger_udev_rule

                # Moving the sriov-PFs to switchdev mode will put the netdev
                # interfaces in down state.
                # In case we are running during initial deployment,
                # bring the interfaces up.
                # In case we are running as part of the sriov_config service
                # after reboot, net config scripts, which run after
                # sriov_config service will bring the interfaces up.
                if execution_from_cli:
                    if_up_interface(item['name'])

    if dpdk_vfs_pcis_list and not vdpa:
        sriov_bind_pcis_map = {_MLNX_DRIVER: dpdk_vfs_pcis_list}
        if not execution_from_cli:
            sriov_bind_config.update_sriov_bind_pcis_map(sriov_bind_pcis_map)
        else:
            sriov_bind_config.configure_sriov_bind_service()
            sriov_bind_config.bind_vfs(sriov_bind_pcis_map)

    # Trigger udev rules if there is new rules written
    if trigger_udev_rule:
        trigger_udev_rules()

    udev_monitor_stop(observer)
    if restart_openvswitch:
        restart_ovs_and_pfs_netdevs()