Messages in this thread Patch in this message | | | Date | Mon, 30 Mar 1998 21:32:37 +0100 (GMT+0100) | From | Shaw Carruthers <> | Subject | Kmod fixed? [PATCH] |
| |
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
| |