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

Reply via email to