From 22aeee1b87731618356f2792d49795a01f40ec19 Mon Sep 17 00:00:00 2001 From: waleed mousa Date: Thu, 11 Apr 2019 06:44:36 -0400 Subject: [PATCH] Modify udev rule for VF representor rename It seems that if we have more than one NIC in SR_IOV switchdev mode, the names of the represntors will overlap for those NICS, like pf0vf0 for the first port of the first NIC and pf0vf0 for the first port of the second NIC, so we need to rename the VF representor as "_" "enp3s0f0_2" in order to be unique and consistent Change-Id: I25263926e736ed0e4fafaa9aa9891e5961226462 Closes-Bug: #1823526 --- os_net_config/sriov_config.py | 46 +++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/os_net_config/sriov_config.py b/os_net_config/sriov_config.py index 2a6c8029..238f9b62 100644 --- a/os_net_config/sriov_config.py +++ b/os_net_config/sriov_config.py @@ -35,6 +35,30 @@ from oslo_concurrency import processutils logger = logging.getLogger(__name__) _SYS_CLASS_NET = '/sys/class/net' _UDEV_RULE_FILE = '/etc/udev/rules.d/70-persistent-net.rules' + +# In order to keep VF representor name consistent specially after the upgrade +# proccess, we should have a udev rule to handle that. +# The udev rule will rename the VF representor as "_" +_REP_LINK_NAME_FILE = "/etc/udev/rep-link-name.sh" +_REP_LINK_NAME_DATA = '''#!/bin/bash +SWID="$1" +PORT="$2" +parent_phys_port_name=${PORT%vf*} +parent_phys_port_name=${parent_phys_port_name//f} +for i in `ls -1 /sys/class/net/*/phys_port_name` +do + nic=`echo $i | cut -d/ -f 5` + sw_id=`cat /sys/class/net/$nic/phys_switch_id 2>/dev/null` + phys_port_name=`cat /sys/class/net/$nic/phys_port_name 2>/dev/null` + if [ "$parent_phys_port_name" = "$phys_port_name" ] && + [ "$sw_id" = "$SWID" ] + then + echo "NAME=${nic}_${PORT##pf*vf}" + break + exit + fi +done''' + # Create a queue for passing the udev network events vf_queue = Queue.Queue() @@ -160,30 +184,42 @@ def _wait_for_vf_creation(pf_name, numvfs): logger.info("Required VFs are created for PF %s" % pf_name) +def create_rep_link_name_script(): + with open(_REP_LINK_NAME_FILE, "w") as f: + f.write(_REP_LINK_NAME_DATA) + # Make the _REP_LINK_NAME_FILE executable + os.chmod(_REP_LINK_NAME_FILE, 0o755) + + def add_udev_rule_for_sriov_pf(pf_name): pf_pci = get_pf_pci(pf_name) udev_data_line = 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '\ - 'KERNELS=="%s", NAME="%s"\n' % (pf_pci, pf_name) + 'KERNELS=="%s", NAME="%s"' % (pf_pci, pf_name) add_udev_rule(udev_data_line, _UDEV_RULE_FILE) def add_udev_rule_for_vf_representors(): udev_data_line = 'SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}'\ '!="", ATTR{phys_port_name}=="pf*vf*", '\ - 'NAME="$attr{phys_port_name}"\n' + 'IMPORT{program}="%s '\ + '$attr{phys_switch_id} $attr{phys_port_name}" '\ + 'NAME="$env{NAME}"' % _REP_LINK_NAME_FILE + create_rep_link_name_script() add_udev_rule(udev_data_line, _UDEV_RULE_FILE) def add_udev_rule(udev_data, udev_file): + udev_data = udev_data.strip() if not os.path.exists(udev_file): with open(udev_file, "w") as f: - f.write(udev_data) + f.write(udev_data + "\n") reload_udev_rules() else: file_data = get_file_data(udev_file) - if udev_data not in file_data: + udev_lines = file_data.split("\n") + if udev_data not in udev_lines: with open(udev_file, "a") as f: - f.write(udev_data) + f.write(udev_data + "\n") reload_udev_rules()