lkml.org 
[lkml]   [1998]   [Mar]   [18]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
DateWed, 18 Mar 1998 07:53:58 -0500
FromAndrew Lewycky <>
Subjectkmod in 2.1.90
kmod has a few races in it and some other dislikable behavior
(e.g. kmod_unload can wake up the wrong guy). I've tried to fix these,
and the patch follows.

Andrew Lewycky
alewycky@globalserve.net



--- kmod.c.old  Wed Mar 18 07:40:14 1998
+++ kmod.c      Sun Mar 15 16:45:30 1998
@@ -16,17 +16,22 @@
 */
 int kmod_unload_delay = 60;
 char modprobe_path[256] = "/sbin/modprobe";
-char module_name[64] = "";
-char * argv[] = { "modprobe", "-k", NULL, NULL, };
-char * envp[] = { "HOME=/", "TERM=linux", NULL, };
+static char module_name[64] = "";
+static int kmod_delete_requested = 0;
+static char * argv[] = { "modprobe", "-k", NULL, NULL, };
+static char * envp[] = { "HOME=/", "TERM=linux", NULL, };
 
 /*
-       kmod_queue synchronizes the kmod thread and the rest of the
system
+       kmod_worker is where the kmod kernel thread sleeps
+       kmod_queue is where proccesses sleep while a module is loading
+       kmod_semaphore must be grabbed by those wanting to make a
request
        kmod_unload_timer is what we use to unload modules
        after kmod_unload_delay seconds
 */
-struct wait_queue * kmod_queue = NULL;
-struct timer_list kmod_unload_timer;
+static struct wait_queue * kmod_worker = NULL;
+static struct wait_queue * kmod_queue = NULL;
+static struct semaphore kmod_semaphore = MUTEX_LOCKED;
+static struct timer_list kmod_unload_timer;
 
 /*
        kmod_thread is the thread that does most of the work. 
kmod_unload and
@@ -34,8 +39,6 @@
 */
 int kmod_thread(void * data)
 {
-       int pid;
-
        /*
                Initialize basic thread information
        */
@@ -50,7 +53,7 @@
        */
 
        while (1) {
-               interruptible_sleep_on(&kmod_queue);
+               interruptible_sleep_on(&kmod_worker);
 
                /*
                        If request_module woke us up, we should try to
@@ -59,10 +62,8 @@
                        (if somehow both want us to do something, ignore
the
                         delete_module request)
                */
-               if (module_name[0] == '\0') {
-                       delete_module(NULL);
-               } else {
-                       pid = fork();
+               if (module_name[0] != '\0') {
+                       pid_t pid = fork();
                        if (pid > 0) {
                                waitpid(pid, NULL, 0);
                                module_name[0] = '\0';
@@ -83,6 +84,11 @@
                                printk("error, fork failed in kmod\n");
                        }
                }
+
+               if (kmod_delete_requested) {
+                       kmod_delete_requested = 0;
+                       delete_module(NULL);
+               }
        }
 
        return 0;       /* Never reached. */
@@ -100,7 +106,8 @@
                 we are in the bottom half of the kernel (right?))
                once it is awake, reset the timer
        */
-       wake_up(&kmod_queue);
+       kmod_delete_requested = 1;
+       wake_up(&kmod_worker);
        kmod_unload_timer.expires = jiffies + (kmod_unload_delay * HZ);
        add_timer(&kmod_unload_timer);
 }
@@ -118,6 +125,8 @@
        kmod_unload_timer.function = kmod_unload;
        add_timer(&kmod_unload_timer);
 
+       up(&kmod_semaphore);
+
        return 0;
 }
 
@@ -127,6 +136,8 @@
 */
 int request_module(const char * name)
 {
+       down(&kmod_semaphore);
+
        /* first, copy the name of the module into module_name */
        /* then wake_up() the kmod daemon */
        /* wait for the kmod daemon to finish (it will wake us up) */
@@ -136,8 +147,10 @@
                the module into module_name.  Once that is done, wake up
                kmod_thread.
        */
-       strcpy(module_name, name);
-       wake_up(&kmod_queue);
+       strncpy(module_name, name, sizeof(module_name)-1);
+       module_name[sizeof(module_name)-1] = '\0';
+
+       wake_up(&kmod_worker);
 
        /*
                Now that we have told kmod_thread what to do, we want to
@@ -127,6 +136,8 @@
 */
 int request_module(const char * name)
 {
+       down(&kmod_semaphore);
+
        /* first, copy the name of the module into module_name */
        /* then wake_up() the kmod daemon */
        /* wait for the kmod daemon to finish (it will wake us up) */
@@ -136,8 +147,10 @@
                the module into module_name.  Once that is done, wake up
                kmod_thread.
        */
-       strcpy(module_name, name);
-       wake_up(&kmod_queue);
+       strncpy(module_name, name, sizeof(module_name)-1);
+       module_name[sizeof(module_name)-1] = '\0';
+
+       wake_up(&kmod_worker);
 
        /*
                Now that we have told kmod_thread what to do, we want to
@@ -145,5 +158,7 @@
                at which point we will be done (the module will be
loaded).
        */
        interruptible_sleep_on(&kmod_queue);
+
+       up(&kmod_semaphore);
        return 0;
 }
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 12:41    [W:0.231 / U:0.060 seconds]
©2003-2008 Jasper Spaans