My solution to this problem is to add code in request_module to block all
signals by sigfillsetting current->blocked, and then restore
current->blocked after the waitpid is done. This ensures that we won't
have problems with unblocked signals while waiting on modprobe. I've
tested this on ix86 and it seems to correct the problem, but I seem to
remember weirdness with the alpha and signal manipulations, so this might
not work on alphas. Diff against stock 2.1.105 included below. It may
require some modification to patch against Alan's recent kernels, as they
contain an additional fix to kmod to prevent oopsing if the root fs hasn't
been mounted (Ben - could this be part of your problem?).
Anyway, the diff seems to have the proper behavior, but it might not be
done the Right Way(tm).
Comments?
Greg Zornetzer - gaz+@andrew.cmu.edu
"Light shines brightest in the darkest night"
http://www.contrib.andrew.cmu.edu/~gaz
--------------------start of modtest.c-----------
#include <linux/module.h>
#include <asm/delay.h>
#include <linux/sched.h>
int init_module (void)
{
unsigned long curr_jif, target_jif;
curr_jif = jiffies;
target_jif = curr_jif + 20*HZ;
while(jiffies < target_jif)
schedule();
return(0);
}
void cleanup_module(void)
{
}
---------------end of modtest.c--------------
--------------------start of kmodfix.diff----------
--- linux/kernel/kmod.c~ Sun Jun 7 21:04:38 1998
+++ linux/kernel/kmod.c Fri Jun 12 12:21:40 1998
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/unistd.h>
+#include <linux/signal.h>
#include <asm/smp_lock.h>
#include <asm/uaccess.h>
@@ -92,6 +93,15 @@
{
int pid;
int waitpid_result;
+ sigset_t temp;
+
+
+ spin_lock_irq(¤t->sigmask_lock);
+ memcpy(&temp,¤t->blocked, sizeof(sigset_t));
+ sigfillset(¤t->blocked);
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
if (pid < 0) {
@@ -103,5 +113,16 @@
printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
pid, waitpid_result);
}
+
+ spin_lock_irq(¤t->sigmask_lock);
+ memcpy(¤t->blocked, &temp, sizeof(sigset_t));
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
+
return 0;
}
--------end of kmodfix.diff----------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu