[2/2] usertools/devbind: check if module is loaded before binding

Message ID 1862ad94e15a61121aea75a2933dc8a44bb12623.1563982007.git.anatoly.burakov@intel.com (mailing list archive)
State Superseded, archived
Headers
Series Small usability improvements for devbind |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Anatoly Burakov July 24, 2019, 3:34 p.m. UTC
  Currently, if an attempt is made to bind a device to a driver that
is not loaded, a confusing and misleading error message appears.
Fix it so that, before binding to the driver, we actually check if
it is loaded in the kernel first.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 usertools/dpdk-devbind.py | 48 ++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 21 deletions(-)
  

Comments

Stephen Hemminger July 24, 2019, 4:28 p.m. UTC | #1
On Wed, 24 Jul 2019 16:34:44 +0100
Anatoly Burakov <anatoly.burakov@intel.com> wrote:

> +# check if a specific kernel module is loaded
> +def module_is_loaded(module):
> +    # Get list of sysfs modules (both built-in and dynamically loaded)
> +    sysfs_path = '/sys/module/'
> +
> +    # Get the list of directories in sysfs_path
> +    sysfs_mods = [os.path.join(sysfs_path, o) for o
> +                  in os.listdir(sysfs_path)
> +                  if os.path.isdir(os.path.join(sysfs_path, o))]
> +
> +    # get module names
> +    sysfs_mods = [os.path.basename(a) for a in sysfs_mods]
> +
> +    # special case for vfio_pci (module is named vfio-pci,
> +    # but its .ko is named vfio_pci)
> +    sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods]
> +
> +    return module in sysfs_mods
> +

You could just check if the one module exist rather than getting full
list.

Maybe vfio-pci should be renamed vfil_pci earlier in the code.
  
Anatoly Burakov July 24, 2019, 4:47 p.m. UTC | #2
On 24-Jul-19 5:28 PM, Stephen Hemminger wrote:
> On Wed, 24 Jul 2019 16:34:44 +0100
> Anatoly Burakov <anatoly.burakov@intel.com> wrote:
> 
>> +# check if a specific kernel module is loaded
>> +def module_is_loaded(module):
>> +    # Get list of sysfs modules (both built-in and dynamically loaded)
>> +    sysfs_path = '/sys/module/'
>> +
>> +    # Get the list of directories in sysfs_path
>> +    sysfs_mods = [os.path.join(sysfs_path, o) for o
>> +                  in os.listdir(sysfs_path)
>> +                  if os.path.isdir(os.path.join(sysfs_path, o))]
>> +
>> +    # get module names
>> +    sysfs_mods = [os.path.basename(a) for a in sysfs_mods]
>> +
>> +    # special case for vfio_pci (module is named vfio-pci,
>> +    # but its .ko is named vfio_pci)
>> +    sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods]
>> +
>> +    return module in sysfs_mods
>> +
> 
> You could just check if the one module exist rather than getting full
> list.

I tried to reduce the amount of changes made, but i suppose i could fix 
this.

> 
> Maybe vfio-pci should be renamed vfil_pci earlier in the code.
> 

Good point.
  

Patch

diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index f7c4c6434..53112c999 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -146,6 +146,25 @@  def check_output(args, stderr=None):
     return subprocess.Popen(args, stdout=subprocess.PIPE,
                             stderr=stderr).communicate()[0]
 
+# check if a specific kernel module is loaded
+def module_is_loaded(module):
+    # Get list of sysfs modules (both built-in and dynamically loaded)
+    sysfs_path = '/sys/module/'
+
+    # Get the list of directories in sysfs_path
+    sysfs_mods = [os.path.join(sysfs_path, o) for o
+                  in os.listdir(sysfs_path)
+                  if os.path.isdir(os.path.join(sysfs_path, o))]
+
+    # get module names
+    sysfs_mods = [os.path.basename(a) for a in sysfs_mods]
+
+    # special case for vfio_pci (module is named vfio-pci,
+    # but its .ko is named vfio_pci)
+    sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods]
+
+    return module in sysfs_mods
+
 
 def check_modules():
     '''Checks that igb_uio is loaded'''
@@ -155,27 +174,9 @@  def check_modules():
     mods = [{"Name": driver, "Found": False} for driver in dpdk_drivers]
 
     # first check if module is loaded
-    try:
-        # Get list of sysfs modules (both built-in and dynamically loaded)
-        sysfs_path = '/sys/module/'
-
-        # Get the list of directories in sysfs_path
-        sysfs_mods = [os.path.join(sysfs_path, o) for o
-                      in os.listdir(sysfs_path)
-                      if os.path.isdir(os.path.join(sysfs_path, o))]
-
-        # Extract the last element of '/sys/module/abc' in the array
-        sysfs_mods = [a.split('/')[-1] for a in sysfs_mods]
-
-        # special case for vfio_pci (module is named vfio-pci,
-        # but its .ko is named vfio_pci)
-        sysfs_mods = [a if a != 'vfio_pci' else 'vfio-pci' for a in sysfs_mods]
-
-        for mod in mods:
-            if mod["Name"] in sysfs_mods:
-                mod["Found"] = True
-    except:
-        pass
+    for mod in mods:
+        if module_is_loaded(mod["Name"]):
+            mod["Found"] = True
 
     # check if we have at least one loaded module
     if True not in [mod["Found"] for mod in mods] and b_flag is not None:
@@ -521,6 +522,11 @@  def bind_all(dev_list, driver, force=False):
         # driver generated error - it's not a valid device ID, so all is well
         pass
 
+    # check if we're attempting to bind to a driver that isn't loaded
+    if not module_is_loaded(driver):
+        print("ERROR: Driver '%s' is not loaded." % driver)
+        sys.exit(1)
+
     try:
         dev_list = map(dev_id_from_dev_name, dev_list)
     except ValueError as ex: