From: Jeff Mahoney Subject: init: move populate_rootfs back to start_kernel References: bnc#533555 Patch-mainline: Probably never Mainline commit 8d610dd5 introduced the rootfs_initcall and moved populate_rootfs out of start_kernel. This was because of issues with userspace helpers being executed way too early. Things like pipes weren't initialized yet and users were seeing Oopses or unpredictable behavior in certain circumstances. The fix worked by causing the execve to fail because it couldn't lookup the helper in the file system since the file system wasn't populate yet. It turns out that's a really late place to fail since the entire usermodehelper infrastructure depends on a work queue that is already checked to see if it has been initialized. We can fail earlier without having to fork threads that will ultimately fail. This patch moves populate_rootfs back to start_kernel and avoids the race against a very early userspace by moving the initialization of khelper_wq to rootfs_initcall. This may seem like a small win, but it is essential for my next patch which adds the ability to override ACPI tables at boot-time. Signed-off-by: Jeff Mahoney --- include/linux/init.h | 1 include/linux/kmod.h | 2 init/initramfs.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++-- init/main.c | 10 +++ kernel/kmod.c | 4 + 5 files changed, 161 insertions(+), 9 deletions(-) --- a/include/linux/init.h +++ b/include/linux/init.h @@ -146,6 +146,7 @@ extern unsigned int reset_devices; /* used by init/main.c */ void setup_arch(char **); void prepare_namespace(void); +int populate_rootfs(void); extern void (*late_time_init)(void); --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -98,8 +98,6 @@ call_usermodehelper_keys(char *path, cha return call_usermodehelper_exec(info, wait); } -extern void usermodehelper_init(void); - struct file; extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[], struct file **filp); --- a/init/initramfs.c +++ b/init/initramfs.c @@ -565,7 +709,7 @@ static void __init clean_rootfs(void) } #endif -static int __init populate_rootfs(void) +int __init populate_rootfs(void) { char *err = unpack_to_rootfs(__initramfs_start, __initramfs_end - __initramfs_start); @@ -605,4 +749,3 @@ static int __init populate_rootfs(void) } return 0; } -rootfs_initcall(populate_rootfs); --- a/init/main.c +++ b/init/main.c @@ -713,6 +713,15 @@ asmlinkage void __init start_kernel(void check_bugs(); + /* + * Do this before starting ACPI so we can read-in + * override tables before the tables are actually + * loaded. The usermode helper won't be initialized + * until much later so we don't race against things + * calling out to userspace. + */ + populate_rootfs(); + acpi_early_init(); /* before LAPIC and SMP init */ sfi_init_late(); @@ -810,7 +819,6 @@ static void __init do_basic_setup(void) { init_workqueues(); cpuset_init_smp(); - usermodehelper_init(); init_tmpfs(); driver_init(); init_irq_proc(); --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -531,8 +531,10 @@ int call_usermodehelper_pipe(char *path, } EXPORT_SYMBOL(call_usermodehelper_pipe); -void __init usermodehelper_init(void) +static int __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); BUG_ON(!khelper_wq); + return 0; } +rootfs_initcall(usermodehelper_init);