Use /sys/module instead of /proc/modules.
authorEtienne Dechamps <etienne.dechamps@ovh.net>
Wed, 4 Jul 2012 13:56:40 +0000 (15:56 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 26 Jul 2012 20:45:33 +0000 (13:45 -0700)
When libzfs checks if the module is loaded or not, it currently reads
/proc/modules and searches for a line matching the module name.

Unfortunately, if the module is included in the kernel itself (built-in
module), then /proc/modules won't list it, so libzfs will wrongly conclude
that the module is not loaded, thus making all ZFS userspace tools unusable.

Fortunately, all loaded modules appear as directories in /sys/module, even
built-in ones. Thus we can use /sys/module in lieu of /proc/modules to fix
the issue.

As a bonus, the code for checking becomes much simpler.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #851

lib/libzfs/libzfs_util.c

index 982a6f0..5618a5c 100644 (file)
@@ -608,27 +608,13 @@ libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr)
 static int
 libzfs_module_loaded(const char *module)
 {
-       FILE *f;
-       int result = 0;
-       char name[256];
+       const char path_prefix[] = "/sys/module/";
+       char path[256];
 
-       f = fopen("/proc/modules", "r");
-       if (f == NULL)
-               return -1;
+       memcpy(path, path_prefix, sizeof(path_prefix) - 1);
+       strcpy(path + sizeof(path_prefix) - 1, module);
 
-       while (fgets(name, sizeof(name), f)) {
-               char *c = strchr(name, ' ');
-               if (!c)
-                       continue;
-               *c = 0;
-               if (strcmp(module, name) == 0) {
-                       result = 1;
-                       break;
-               }
-       }
-       fclose(f);
-
-       return result;
+       return (access(path, F_OK) == 0);
 }
 
 int