112 lines
3.4 KiB
Plaintext
112 lines
3.4 KiB
Plaintext
|
From: Jeff Mahoney <jeffm@suse.com>
|
||
|
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 <jeffm@suse.com>
|
||
|
---
|
||
|
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);
|