FIX: init_interface driver and sr-iov 91/32891/7
authorJuraj Linkeš <juraj.linkes@pantheon.tech>
Thu, 24 Jun 2021 14:47:55 +0000 (16:47 +0200)
committerJuraj Linkeš <juraj.linkes@pantheon.tech>
Mon, 2 Aug 2021 07:11:49 +0000 (09:11 +0200)
Add checks for not unbinding a driver that is not bound and not
trying to remove VFs from interfaces not supporting SR-IOV.

Change-Id: Iae7ce37aabeadbb541fe9eac8b83b4ee18d028e6
Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
resources/libraries/python/DUTSetup.py
resources/libraries/python/InterfaceUtil.py

index 712da63..5040223 100644 (file)
@@ -400,6 +400,20 @@ class DUTSetup:
         :type numvfs: int
         :raises RuntimeError: Failed to create VFs on PCI.
         """
         :type numvfs: int
         :raises RuntimeError: Failed to create VFs on PCI.
         """
+        cmd = f"test -f /sys/bus/pci/devices/{pf_pci_addr}/sriov_numvfs"
+        sriov_unsupported, _, _ = exec_cmd(node, cmd)
+        # if sriov_numvfs doesn't exist, then sriov_unsupported != 0
+        if int(sriov_unsupported):
+            if numvfs == 0:
+                # sriov is not supported and we want 0 VFs
+                # no need to do anything
+                return
+            else:
+                raise RuntimeError(
+                    f"Can't configure {numvfs} VFs on {pf_pci_addr} device "
+                    f"on {node[u'host']} since it doesn't support SR-IOV."
+                )
+
         pci = pf_pci_addr.replace(u":", r"\:")
         command = f"sh -c \"echo {numvfs} | " \
             f"tee /sys/bus/pci/devices/{pci}/sriov_numvfs\""
         pci = pf_pci_addr.replace(u":", r"\:")
         command = f"sh -c \"echo {numvfs} | " \
             f"tee /sys/bus/pci/devices/{pci}/sriov_numvfs\""
@@ -543,61 +557,25 @@ class DUTSetup:
     def get_pci_dev_driver(node, pci_addr):
         """Get current PCI device driver on node.
 
     def get_pci_dev_driver(node, pci_addr):
         """Get current PCI device driver on node.
 
-        .. note::
-            # lspci -vmmks 0000:00:05.0
-            Slot:   00:05.0
-            Class:  Ethernet controller
-            Vendor: Red Hat, Inc
-            Device: Virtio network device
-            SVendor:        Red Hat, Inc
-            SDevice:        Device 0001
-            PhySlot:        5
-            Driver: virtio-pci
-
         :param node: DUT node.
         :param pci_addr: PCI device address.
         :type node: dict
         :type pci_addr: str
         :returns: Driver or None
         :param node: DUT node.
         :param pci_addr: PCI device address.
         :type node: dict
         :type pci_addr: str
         :returns: Driver or None
-        :raises RuntimeError: If PCI rescan or lspci command execution failed.
         :raises RuntimeError: If it is not possible to get the interface driver
             information from the node.
         """
         :raises RuntimeError: If it is not possible to get the interface driver
             information from the node.
         """
-        ssh = SSH()
-        ssh.connect(node)
-
-        for i in range(3):
-            logger.trace(f"Try number {i}: Get PCI device driver")
-
-            cmd = f"lspci -vmmks {pci_addr}"
-            ret_code, stdout, _ = ssh.exec_command(cmd)
-            if int(ret_code):
-                raise RuntimeError(f"'{cmd}' failed on '{node[u'host']}'")
-
-            for line in stdout.splitlines():
-                if not line:
-                    continue
-                name = None
-                value = None
-                try:
-                    name, value = line.split(u"\t", 1)
-                except ValueError:
-                    if name == u"Driver:":
-                        return None
-                if name == u"Driver:":
-                    return value
-
-            if i < 2:
-                logger.trace(
-                    f"Driver for PCI device {pci_addr} not found, "
-                    f"executing pci rescan and retrying"
-                )
-                cmd = u"sh -c \"echo 1 > /sys/bus/pci/rescan\""
-                ret_code, _, _ = ssh.exec_command_sudo(cmd)
-                if int(ret_code) != 0:
-                    raise RuntimeError(f"'{cmd}' failed on '{node[u'host']}'")
-
-        return None
+        driver_path = f"/sys/bus/pci/devices/{pci_addr}/driver"
+        cmd = f"test -d {driver_path}"
+        ret_code, ret_val, _ = exec_cmd(node, cmd)
+        if int(ret_code):
+            # the directory doesn't exist which means the device is not bound
+            # to any driver
+            return None
+        else:
+            cmd = f"basename $(readlink -f {driver_path})"
+            ret_val, _ = exec_cmd_no_error(node, cmd)
+            return ret_val.strip()
 
     @staticmethod
     def verify_kernel_module(node, module, force_load=False):
 
     @staticmethod
     def verify_kernel_module(node, module, force_load=False):
index af34c64..4cd7cf1 100644 (file)
@@ -1828,8 +1828,9 @@ class InterfaceUtil:
             # PCI device must be re-bound to kernel driver before creating VFs.
             DUTSetup.verify_kernel_module(node, kernel_driver, force_load=True)
             # Stop VPP to prevent deadlock.
             # PCI device must be re-bound to kernel driver before creating VFs.
             DUTSetup.verify_kernel_module(node, kernel_driver, force_load=True)
             # Stop VPP to prevent deadlock.
-            # Unbind from current driver.
-            DUTSetup.pci_driver_unbind(node, pf_pci_addr)
+            # Unbind from current driver if bound.
+            if current_driver:
+                DUTSetup.pci_driver_unbind(node, pf_pci_addr)
             # Bind to kernel driver.
             DUTSetup.pci_driver_bind(node, pf_pci_addr, kernel_driver)
 
             # Bind to kernel driver.
             DUTSetup.pci_driver_bind(node, pf_pci_addr, kernel_driver)