Kmod fixed? [PATCH]

Shaw Carruthers (shaw@shawc.demon.co.uk)
Mon, 30 Mar 1998 21:32:37 +0100 (GMT+0100)


I have been playing around with kmod. I modified your algorithm so that
delslot merely marks a slot for reuse and makeslot only creates new slots
if there are none free for reuse.

This seems more stable, I suspect that in the earlier version there was a
race caused by delslot.

Here is a patch for 2.1.91 against your last full kmod.c. It contains a
few diagnostic printks.

What do you think?

--- kmod.c Mon Mar 30 20:51:11 1998
+++ linux/kernel/kmod.c Mon Mar 30 20:34:08 1998
@@ -24,8 +24,7 @@
#define MODRQ_REMOVE 4
#define MODRQ_FAILURE 8
#define MODRQ_CLEANUP 16
-
-static inline _syscall1(int,delete_module,const char *,name_user)
+#define MODRQ_REUSE 32

/*
kmod_unload_delay and modprobe_path are set via /proc/sys.
@@ -49,7 +48,7 @@
struct wait_queue *mreq_queue;
int info;
pid_t pid;
- char *module_name;
+ char module_name[64];
char * argv[4];
struct modslot *next;
};
@@ -66,43 +65,53 @@
static struct semaphore queue_access = MUTEX;


-struct modslot *makeslot(int info, char *modname)
+
+struct modslot *makeslot(int info, const char *modname)
{
int i;
struct modslot *slot;
+ slot = modlist ;
+ while(slot!=NULL)
+ {
+ printk("kmod-retrying:%x\n",slot);
+ if (slot->info == MODRQ_REUSE) break;
+ slot = slot->next;
+ };
+
+ if ( slot==NULL)
+ {
slot = kmalloc(sizeof(struct modslot), GFP_KERNEL);
+ slot->next = modlist;
+ modlist = slot;
+ printk("kmod-creating:%x\n",slot);
+ };
+
+ printk("kmod-using:%x\n",slot);
slot->mreq_queue = NULL;
slot->pid = -1;
slot->info = info;
- slot->module_name = modname;
for(i=0;i < 4;i++)
slot->argv[i] = template_argv[i];
- slot->next = modlist;
- modlist = slot;
+ printk ("trying:%s\n",modname);
+ strncpy(slot->module_name, modname, sizeof(slot->module_name));
+ slot->module_name[sizeof(slot->module_name)-1] = '\0';
+ slot->argv[2] = slot->module_name;

return(slot);
-};
+}

void delslot(struct modslot **last, struct modslot **del)
{
- if((*last) == NULL) {
- modlist = (*del)->next;
- kfree(*del);
- *del = modlist;
- }
- else {
- (*last)->next = (*del)->next;
- kfree(*del);
- (*del) = (*last)->next;
- }
-
+ (*last) = (*del);
+ (*del)->info = MODRQ_REUSE;
+ (*del) = (*del)->next;

}


void install_module(struct modslot *slot) {
pid_t pid, pid2;
-
+ int err;
/*
By forking off two processes, we create a system where the main
kmod loop can keep going while a request is being served.
@@ -121,21 +130,22 @@
Call modprobe with module_name. If execve returns,
print out an error.
*/
- slot->argv[2] = slot->module_name;
- execve(modprobe_path, slot->argv, envp);
- printk("Modprobe load failed - couldn't load %s\n",slot->module_name);
+ err = execve(modprobe_path, slot->argv, envp);
+ printk("kmod-Modprobe load failed - couldn't load %s\n",slot->module_name);
+ printk("kmod-Error code %d\n",errno);
slot->info = MODRQ_FAILURE;
_exit(0);
} else {
- printk("error, fork failed in kmod - couldn't load %s\n",slot->module_name);
+ printk("kmod-error, fork failed in kmod - couldn't load %s\n",slot->module_name);
slot->info = MODRQ_FAILURE;
wake_up(&(slot->mreq_queue));
}
_exit(0);
};
slot->pid = pid;
+ printk("kmod-pid:%d\n",pid);
if (pid < 0) {
- printk("KMod: Couldn't fork - Cannot load %s\n",slot->module_name);
+ printk("kmod-KMod: Couldn't fork - Cannot load %s\n",slot->module_name);
slot->info = MODRQ_FAILURE;
wake_up(&(slot->mreq_queue));
}
@@ -175,6 +185,7 @@

down(&queue_access);
slot = modlist;
+ printk("kmod-checking:%x\n",slot);
last = NULL;
while(slot!=NULL) {
switch (slot->info) {
@@ -185,7 +196,8 @@
break;

case MODRQ_CLEANUP :
- waitpid(slot->pid,NULL,0);
+ if(waitpid(slot->pid,NULL,0) != slot->pid)
+ printk("kmod-Something fishy\n");
delslot(&last, &slot);
break;

@@ -222,7 +234,7 @@
*/

down(&queue_access);
- makeslot(MODRQ_REMOVE, NULL);
+ makeslot(MODRQ_REMOVE, "");

wake_up(&kmod_queue);
up(&queue_access);
@@ -233,7 +245,7 @@

int kmod_init(void)
{
- printk("Starting kmod\n");
+ printk("kmod-Starting kmod\n");
kernel_thread(kmod_thread, NULL, 0);

kmod_unload_timer.next = NULL;

--
Shaw Carruthers - shaw@shawc.demon.co.uk
London SW14 7JW UK
This is not a sig( with homage to Magritte).
  

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu