X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fkmod.c;h=eed53d4f5230571b6bba0597bf24d8edeef4dc27;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=8754003bbbf2c641aad3c3c6182f72c92c0e5221;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/kernel/kmod.c b/kernel/kmod.c index 8754003bb..eed53d4f5 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -47,7 +47,7 @@ static struct workqueue_struct *khelper_wq; /* modprobe_path is set via /proc/sys. */ -char modprobe_path[256] = "/sbin/modprobe"; +char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; /** * request_module - try to load a kernel module @@ -115,29 +115,6 @@ int request_module(const char *fmt, ...) EXPORT_SYMBOL(request_module); #endif /* CONFIG_KMOD */ -#ifdef CONFIG_HOTPLUG -/* - hotplug path is set via /proc/sys - invoked by hotplug-aware bus drivers, - with call_usermodehelper - - argv [0] = hotplug_path; - argv [1] = "usb", "scsi", "pci", "network", etc; - ... plus optional type-specific parameters - argv [n] = 0; - - envp [*] = HOME, PATH; optional type-specific parameters - - a hotplug bus should invoke this for device add/remove - events. the command is expected to load drivers when - necessary, and may perform additional system setup. -*/ -char hotplug_path[256] = "/sbin/hotplug"; - -EXPORT_SYMBOL(hotplug_path); - -#endif /* CONFIG_HOTPLUG */ - struct subprocess_info { struct completion *complete; char *path; @@ -154,7 +131,6 @@ static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; int retval; - cpumask_t mask = CPU_MASK_ALL; /* Unblock all signals. */ flush_signals(current); @@ -165,7 +141,7 @@ static int ____call_usermodehelper(void *data) spin_unlock_irq(¤t->sighand->siglock); /* We can run anywhere, unlike our parent keventd(). */ - set_cpus_allowed(current, mask); + set_cpus_allowed(current, CPU_MASK_ALL); retval = -EPERM; if (current->fs->root) @@ -192,10 +168,20 @@ static int wait_for_helper(void *data) allow_signal(SIGCHLD); pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); - if (pid < 0) + if (pid < 0) { sub_info->retval = pid; - else - sys_wait4(pid, &sub_info->retval, 0, NULL); + } else { + /* + * Normally it is bogus to call wait4() from in-kernel because + * wait4() wants to write the exit code to a userspace address. + * But wait_for_helper() always runs as keventd, and put_user() + * to a kernel address works OK for kernel threads, due to their + * having an mm_segment_t which spans the entire address space. + * + * Thus the __user pointer cast is valid here. + */ + sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL); + } complete(sub_info->complete); return 0; @@ -263,10 +249,8 @@ int call_usermodehelper(char *path, char **argv, char **envp, int wait) } EXPORT_SYMBOL(call_usermodehelper); -static __init int usermodehelper_init(void) +void __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); BUG_ON(!khelper_wq); - return 0; } -__initcall(usermodehelper_init);