diff --git a/dts/framework/testbed_model/linux_session.py 
b/dts/framework/testbed_model/linux_session.py

@@ -210,3 +214,37 @@ def configure_ipv4_forwarding(self, enable: bool) -> None:
          """Overrides 
:meth:`~.os_session.OSSession.configure_ipv4_forwarding`."""
          state = 1 if enable else 0
          self.send_command(f"sysctl -w net.ipv4.ip_forward={state}", 
privileged=True)
+
+    def set_num_virtual_functions(self, num: int, pf_port: Port) -> bool:
+        """Overrides 
:meth:`~.os_session.OSSession.set_num_virtual_functions`."""
+        sys_bus_path = f"/sys/bus/pci/devices/{pf_port.pci}/sriov_numvfs".replace(":", 
"\\:")
+        curr_num_vfs = int(self.send_command(f"cat {sys_bus_path}").stdout)
+        if num > 0 and curr_num_vfs >= num:
+            self._logger.info(
+                f"{curr_num_vfs} VFs already configured on port 
{pf_port.identifier.pci} on node "
+                f"{pf_port.identifier.node}."
+            )
+            return False
+        elif num > 0 and curr_num_vfs > 0:

These two conditions could be written as:
if num > 0:
    if curr_num_vfs >= num:
        return False
    elif curr_num_vfs > 0:
        raise InternalError()

Maybe it's not worth the extra indent, but it's easier to understand, so I lean towards doing it this way.


+    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",

We could use a TextParser here. Not sure if it's a good fit though.


diff --git a/dts/framework/testbed_model/os_session.py 
b/dts/framework/testbed_model/os_session.py

@@ -395,3 +395,43 @@ def configure_ipv4_forwarding(self, enable: bool) -> None:

+    @abstractmethod
+    def set_num_virtual_functions(self, num: int, pf_port: Port) -> bool:
+        """Update the number of virtual functions (VFs) on a port.
+
+        It should be noted that, due to the nature of VFs, if there are 
already VFs that exist on
+        the physical function (PF) prior to calling this function, additional 
ones cannot be added.
+        The only way to add more VFs is to remove the existing and then set 
the desired amount. For
+        this reason, this method will handle creation in the following order:
+
+        1. Use existing VFs on the PF if the number of existing VFs is greater 
than or equal to
+        `num`
+        2. Throw an exception noting that VFs cannot be created if the PF has 
some VFs already set
+        on it, but the total VFs that it has are less then `num`.
+        3. Create `num` VFs on the PF if there are none on it already
+
+        Args:
+            num: The number of VFs to set on the port.
+            pf_port: The port to add the VFs to.
+
+        Raises:
+            InternalError: If `pf_port` has less than `num` VFs configured on 
it
+                already.
+
+        Returns:
+            :data:`True` if this method successfully created VFs, 
:data:`False` if existing VFs
+            were used instead.
+        """

The whole docstring talks only about the creation of VFs, but we can also remove VFs with this.



Reply via email to