aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorAl Viro2012-10-10 20:28:25 -0500
committerAl Viro2012-10-12 12:35:07 -0500
commita74fb73c12398b250fdc5e333a11e15a9e3a84fc (patch)
tree2bec2f6e20320f5a4bc01d1e19d7190842ef1c37 /init
parentfb45550d76bb584857cf0ea3be79fa78207a3cff (diff)
downloadkernel-omap-a74fb73c12398b250fdc5e333a11e15a9e3a84fc.tar.gz
kernel-omap-a74fb73c12398b250fdc5e333a11e15a9e3a84fc.tar.xz
kernel-omap-a74fb73c12398b250fdc5e333a11e15a9e3a84fc.zip
infrastructure for saner ret_from_kernel_thread semantics
* allow kernel_execve() leave the actual return to userland to caller (selected by CONFIG_GENERIC_KERNEL_EXECVE). Callers updated accordingly. * architecture that does select GENERIC_KERNEL_EXECVE in its Kconfig should have its ret_from_kernel_thread() do this: call schedule_tail call the callback left for it by copy_thread(); if it ever returns, that's because it has just done successful kernel_execve() jump to return from syscall IOW, its only difference from ret_from_fork() is that it does call the callback. * such an architecture should also get rid of ret_from_kernel_execve() and __ARCH_WANT_KERNEL_EXECVE This is the last part of infrastructure patches in that area - from that point on work on different architectures can live independently. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'init')
-rw-r--r--init/main.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/init/main.c b/init/main.c
index a490ffecb7b9..02df2ddc5f83 100644
--- a/init/main.c
+++ b/init/main.c
@@ -69,6 +69,7 @@
69#include <linux/slab.h> 69#include <linux/slab.h>
70#include <linux/perf_event.h> 70#include <linux/perf_event.h>
71#include <linux/file.h> 71#include <linux/file.h>
72#include <linux/ptrace.h>
72 73
73#include <asm/io.h> 74#include <asm/io.h>
74#include <asm/bugs.h> 75#include <asm/bugs.h>
@@ -788,10 +789,10 @@ static void __init do_pre_smp_initcalls(void)
788 do_one_initcall(*fn); 789 do_one_initcall(*fn);
789} 790}
790 791
791static void run_init_process(const char *init_filename) 792static int run_init_process(const char *init_filename)
792{ 793{
793 argv_init[0] = init_filename; 794 argv_init[0] = init_filename;
794 kernel_execve(init_filename, argv_init, envp_init); 795 return kernel_execve(init_filename, argv_init, envp_init);
795} 796}
796 797
797static void __init kernel_init_freeable(void); 798static void __init kernel_init_freeable(void);
@@ -810,7 +811,8 @@ static int __ref kernel_init(void *unused)
810 flush_delayed_fput(); 811 flush_delayed_fput();
811 812
812 if (ramdisk_execute_command) { 813 if (ramdisk_execute_command) {
813 run_init_process(ramdisk_execute_command); 814 if (!run_init_process(ramdisk_execute_command))
815 return 0;
814 printk(KERN_WARNING "Failed to execute %s\n", 816 printk(KERN_WARNING "Failed to execute %s\n",
815 ramdisk_execute_command); 817 ramdisk_execute_command);
816 } 818 }
@@ -822,14 +824,16 @@ static int __ref kernel_init(void *unused)
822 * trying to recover a really broken machine. 824 * trying to recover a really broken machine.
823 */ 825 */
824 if (execute_command) { 826 if (execute_command) {
825 run_init_process(execute_command); 827 if (!run_init_process(execute_command))
828 return 0;
826 printk(KERN_WARNING "Failed to execute %s. Attempting " 829 printk(KERN_WARNING "Failed to execute %s. Attempting "
827 "defaults...\n", execute_command); 830 "defaults...\n", execute_command);
828 } 831 }
829 run_init_process("/sbin/init"); 832 if (!run_init_process("/sbin/init") ||
830 run_init_process("/etc/init"); 833 !run_init_process("/etc/init") ||
831 run_init_process("/bin/init"); 834 !run_init_process("/bin/init") ||
832 run_init_process("/bin/sh"); 835 !run_init_process("/bin/sh"))
836 return 0;
833 837
834 panic("No init found. Try passing init= option to kernel. " 838 panic("No init found. Try passing init= option to kernel. "
835 "See Linux Documentation/init.txt for guidance."); 839 "See Linux Documentation/init.txt for guidance.");