aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorMichael Opdenacker <michael.opdenacker@free-electrons.com>2013-11-12 18:10:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-12 22:09:26 -0500
commitba24762bd53faaf39cc8b991175636954b7ef4be (patch)
tree2f738251e10357223e70f2894cd8eb867e630b6e /init
parentdf3ef3af503e131f7848652af8be21747fd57419 (diff)
init: make init failures more explicit
This patch proposes to make init failures more explicit. Before this, the "No init found" message didn't help much. It could sometimes be misleading and actually mean "No *working* init found". This message could hide many different issues: - no init program candidates found at all - some init program candidates exist but can't be executed (missing execute permissions, failed to load shared libraries, executable compiled for an unknown architecture...) This patch notifies the kernel user when a candidate init program is found but can't be executed. In each failure situation, the error code is displayed, to quickly find the root cause. "No init found" is also replaced by "No working init found", which is more correct. This will help embedded Linux developers (especially the newcomers), regularly making and debugging new root filesystems. Credits to Geert Uytterhoeven and Janne Karhunen for their improvement suggestions. Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Tested-by: Janne Karhunen <Janne.Karhunen@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'init')
-rw-r--r--init/main.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/init/main.c b/init/main.c
index aa061ef17626..67ee8ef0a669 100644
--- a/init/main.c
+++ b/init/main.c
@@ -810,10 +810,26 @@ static int run_init_process(const char *init_filename)
810 (const char __user *const __user *)envp_init); 810 (const char __user *const __user *)envp_init);
811} 811}
812 812
813static int try_to_run_init_process(const char *init_filename)
814{
815 int ret;
816
817 ret = run_init_process(init_filename);
818
819 if (ret && ret != -ENOENT) {
820 pr_err("Starting init: %s exists but couldn't execute it (error %d)\n",
821 init_filename, ret);
822 }
823
824 return ret;
825}
826
813static noinline void __init kernel_init_freeable(void); 827static noinline void __init kernel_init_freeable(void);
814 828
815static int __ref kernel_init(void *unused) 829static int __ref kernel_init(void *unused)
816{ 830{
831 int ret;
832
817 kernel_init_freeable(); 833 kernel_init_freeable();
818 /* need to finish all async __init code before freeing the memory */ 834 /* need to finish all async __init code before freeing the memory */
819 async_synchronize_full(); 835 async_synchronize_full();
@@ -825,9 +841,11 @@ static int __ref kernel_init(void *unused)
825 flush_delayed_fput(); 841 flush_delayed_fput();
826 842
827 if (ramdisk_execute_command) { 843 if (ramdisk_execute_command) {
828 if (!run_init_process(ramdisk_execute_command)) 844 ret = run_init_process(ramdisk_execute_command);
845 if (!ret)
829 return 0; 846 return 0;
830 pr_err("Failed to execute %s\n", ramdisk_execute_command); 847 pr_err("Failed to execute %s (error %d)\n",
848 ramdisk_execute_command, ret);
831 } 849 }
832 850
833 /* 851 /*
@@ -837,18 +855,19 @@ static int __ref kernel_init(void *unused)
837 * trying to recover a really broken machine. 855 * trying to recover a really broken machine.
838 */ 856 */
839 if (execute_command) { 857 if (execute_command) {
840 if (!run_init_process(execute_command)) 858 ret = run_init_process(execute_command);
859 if (!ret)
841 return 0; 860 return 0;
842 pr_err("Failed to execute %s. Attempting defaults...\n", 861 pr_err("Failed to execute %s (error %d). Attempting defaults...\n",
843 execute_command); 862 execute_command, ret);
844 } 863 }
845 if (!run_init_process("/sbin/init") || 864 if (!try_to_run_init_process("/sbin/init") ||
846 !run_init_process("/etc/init") || 865 !try_to_run_init_process("/etc/init") ||
847 !run_init_process("/bin/init") || 866 !try_to_run_init_process("/bin/init") ||
848 !run_init_process("/bin/sh")) 867 !try_to_run_init_process("/bin/sh"))
849 return 0; 868 return 0;
850 869
851 panic("No init found. Try passing init= option to kernel. " 870 panic("No working init found. Try passing init= option to kernel. "
852 "See Linux Documentation/init.txt for guidance."); 871 "See Linux Documentation/init.txt for guidance.");
853} 872}
854 873