Virtual functions are created in different ways per operating system. Accordingly, we have abstracted the functions for managing virtual functions into different classes per OS. This patch adds stubs for creating virtual functions and gathering virtual function info.
Bugzilla ID: 1500 Signed-off-by: Jeremy Spewock <jspew...@iol.unh.edu> Signed-off-by: Patrick Robb <pr...@iol.unh.edu> --- dts/framework/testbed_model/linux_session.py | 37 +++++++++++++++++++- dts/framework/testbed_model/os_session.py | 27 ++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/dts/framework/testbed_model/linux_session.py b/dts/framework/testbed_model/linux_session.py index 7c2b110c99..35cc7f6852 100644 --- a/dts/framework/testbed_model/linux_session.py +++ b/dts/framework/testbed_model/linux_session.py @@ -16,7 +16,11 @@ from typing_extensions import NotRequired -from framework.exception import ConfigurationError, RemoteCommandExecutionError +from framework.exception import ( + ConfigurationError, + InternalError, + RemoteCommandExecutionError, +) from framework.utils import expand_range from .cpu import LogicalCore @@ -183,6 +187,37 @@ def bring_up_link(self, ports: Iterable[Port]) -> None: f"ip link set dev {port.logical_name} up", privileged=True, verify=True ) + def create_vfs(self, pf_port: Port) -> None: + """Overrides :meth:`~.os_session.OSSession.create_vfs`. + + Raises: + InternalError: If the number of VFs is greater than 0 but less than the + maximum for `pf_port`. + """ + sys_bus_path = f"/sys/bus/pci/devices/{pf_port.pci}".replace(":", "\\:") + curr_num_vfs = int(self.send_command(f"cat {sys_bus_path}/sriov_numvfs").stdout) + max_num_vfs = int( + self.send_command(f"cat {sys_bus_path}/sriov_totalvfs", privileged=True).stdout + ) + if 0 < curr_num_vfs < max_num_vfs: + raise InternalError("There are existing VFs on the port which must be deleted.") + if curr_num_vfs == 0: + self.send_command(f"echo {max_num_vfs} > {sys_bus_path}/sriov_numvfs", privileged=True) + + def get_pci_addr_of_vfs(self, pf_port: Port) -> list[str]: + """Overrides :meth:`~.os_session.OSSession.get_pci_addr_of_vfs`.""" + sys_bus_path = f"/sys/bus/pci/devices/{pf_port.pci}".replace(":", "\\:") + curr_num_vfs = int(self.send_command(f"cat {sys_bus_path}/sriov_numvfs").stdout) + if curr_num_vfs > 0: + pci_addrs = self.send_command( + 'awk -F "PCI_SLOT_NAME=" "/PCI_SLOT_NAME=/ {print \\$2}" ' + + f"{sys_bus_path}/virtfn*/uevent", + privileged=True, + ) + return pci_addrs.stdout.splitlines() + else: + return [] + @cached_property def _lshw_net_info(self) -> list[LshwOutput]: output = self.send_command("lshw -quiet -json -C network", verify=True) diff --git a/dts/framework/testbed_model/os_session.py b/dts/framework/testbed_model/os_session.py index 354c607357..a4ad9940b2 100644 --- a/dts/framework/testbed_model/os_session.py +++ b/dts/framework/testbed_model/os_session.py @@ -554,3 +554,30 @@ def configure_port_mtu(self, mtu: int, port: Port) -> None: mtu: Desired MTU value. port: Port to set `mtu` on. """ + + @abstractmethod + def create_vfs(self, pf_port: Port) -> None: + """Creates virtual functions for `pf_port`. + + Checks how many virtual functions (VFs) `pf_port` supports, and creates that + number of VFs on the port. + + Args: + pf_port: The port to create virtual functions on. + + Raises: + InternalError: If the number of VFs is greater than 0 but less than the + maximum for `pf_port`. + """ + + @abstractmethod + def get_pci_addr_of_vfs(self, pf_port: Port) -> list[str]: + """Find the PCI addresses of all virtual functions (VFs) on the port `pf_port`. + + Args: + pf_port: The port to find the VFs on. + + Returns: + A list containing all of the PCI addresses of the VFs on the port. If the port has no + VFs then the list will be empty. + """ -- 2.48.1