Busybox modprobe has a couple of irritating quirks:
authorGlenn L McGrath <bug1@ihug.co.nz>
Mon, 8 Sep 2003 00:32:49 +0000 (00:32 -0000)
committerGlenn L McGrath <bug1@ihug.co.nz>
Mon, 8 Sep 2003 00:32:49 +0000 (00:32 -0000)
 - attempting to modprobe a module that is already loaded yields "Failed
to load module", whereas modutils quietly ignores such a request.

 - if a module genuinely can't be loaded due to missing symbols or
similar problems, modprobe doesn't produce any useful diagnostics
because the output from insmod has been redirected to /dev/null.

Here's a patch to address these issue

Patch by Philip Blundell

modutils/modprobe.c

index b4bff51000b69250bd44bb4b0dce8f774a61454a..07cbb6fc78996b28125ebf6013fdf3c16abaae7b 100644 (file)
@@ -319,6 +319,32 @@ static struct dep_t *build_dep ( void )
        return first;
 }
 
+/* return 1 = loaded, 0 = not loaded, -1 = can't tell */
+static int already_loaded (const char *name)
+{
+       int fd;
+       char buffer[256];
+
+       fd = open ("/proc/modules", O_RDONLY);
+       if (fd < 0)
+               return -1;
+
+       while ( reads ( fd, buffer, sizeof( buffer ))) {
+               char *p;
+
+               p = strchr (buffer, ' ');
+               if (p) {
+                       *p = 0;
+                       if (strcmp (name, buffer) == 0) {
+                               close (fd);
+                               return 1;
+                       }
+               }
+       }
+
+       close (fd);
+       return 0;
+}
 
 static int mod_process ( struct mod_list_t *list, int do_insert )
 {
@@ -326,10 +352,13 @@ static int mod_process ( struct mod_list_t *list, int do_insert )
        int rc = 1;
 
        while ( list ) {
-               if ( do_insert )
-                       snprintf ( lcmd, sizeof( lcmd ) - 1, "insmod %s %s %s %s %s 2>/dev/null", do_syslog ? "-s" : "", autoclean ? "-k" : "", quiet ? "-q" : "", list-> m_module, list-> m_options ? list-> m_options : "" );
-               else
-                       snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s 2>/dev/null", do_syslog ? "-s" : "", list-> m_module );
+               if ( do_insert ) {
+                       if (already_loaded (list->m_module) != 1)
+                               snprintf ( lcmd, sizeof( lcmd ) - 1, "insmod %s %s %s %s %s", do_syslog ? "-s" : "", autoclean ? "-k" : "", quiet ? "-q" : "", list-> m_module, list-> m_options ? list-> m_options : "" );
+               } else {
+                       if (already_loaded (list->m_module) != 0)
+                               snprintf ( lcmd, sizeof( lcmd ) - 1, "rmmod %s %s", do_syslog ? "-s" : "", list-> m_module );
+               }
                
                if ( verbose )
                        printf ( "%s\n", lcmd );