diff options
Diffstat (limited to 'init/main.c')
| -rw-r--r-- | init/main.c | 60 | 
1 files changed, 45 insertions, 15 deletions
diff --git a/init/main.c b/init/main.c index af310afbef28..01573fdfa186 100644 --- a/init/main.c +++ b/init/main.c @@ -76,6 +76,7 @@  #include <linux/elevator.h>  #include <linux/sched_clock.h>  #include <linux/context_tracking.h> +#include <linux/random.h>  #include <asm/io.h>  #include <asm/bugs.h> @@ -123,7 +124,6 @@ EXPORT_SYMBOL(system_state);  extern void time_init(void);  /* Default late time init is NULL. archs can override this later. */  void (*__initdata late_time_init)(void); -extern void softirq_init(void);  /* Untouched command line saved by arch-specific code. */  char __initdata boot_command_line[COMMAND_LINE_SIZE]; @@ -131,11 +131,20 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE];  char *saved_command_line;  /* Command line for parameter parsing */  static char *static_command_line; +/* Command line for per-initcall parameter parsing */ +static char *initcall_command_line;  static char *execute_command;  static char *ramdisk_execute_command;  /* + * Used to generate warnings if static_key manipulation functions are used + * before jump_label_init is called. + */ +bool static_key_initialized __read_mostly = false; +EXPORT_SYMBOL_GPL(static_key_initialized); + +/*   * If set, this is an indication to the drivers that reset the underlying   * device before going ahead with the initialization otherwise driver might   * rely on the BIOS and skip the reset operation. @@ -347,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }  static void __init setup_command_line(char *command_line)  {  	saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); +	initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1);  	static_command_line = alloc_bootmem(strlen (command_line)+1);  	strcpy (saved_command_line, boot_command_line);  	strcpy (static_command_line, command_line); @@ -466,7 +476,7 @@ static void __init mm_init(void)  	mem_init();  	kmem_cache_init();  	percpu_init_late(); -	pgtable_cache_init(); +	pgtable_init();  	vmalloc_init();  } @@ -692,7 +702,7 @@ int __init_or_module do_one_initcall(initcall_t fn)  	if (preempt_count() != count) {  		sprintf(msgbuf, "preemption imbalance "); -		preempt_count() = count; +		preempt_count_set(count);  	}  	if (irqs_disabled()) {  		strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); @@ -744,9 +754,9 @@ static void __init do_initcall_level(int level)  	extern const struct kernel_param __start___param[], __stop___param[];  	initcall_t *fn; -	strcpy(static_command_line, saved_command_line); +	strcpy(initcall_command_line, saved_command_line);  	parse_args(initcall_level_names[level], -		   static_command_line, __start___param, +		   initcall_command_line, __start___param,  		   __stop___param - __start___param,  		   level, level,  		   &repair_env_string); @@ -780,6 +790,7 @@ static void __init do_basic_setup(void)  	do_ctors();  	usermodehelper_enable();  	do_initcalls(); +	random_int_secret_init();  }  static void __init do_pre_smp_initcalls(void) @@ -809,10 +820,26 @@ static int run_init_process(const char *init_filename)  		(const char __user *const __user *)envp_init);  } +static int try_to_run_init_process(const char *init_filename) +{ +	int ret; + +	ret = run_init_process(init_filename); + +	if (ret && ret != -ENOENT) { +		pr_err("Starting init: %s exists but couldn't execute it (error %d)\n", +		       init_filename, ret); +	} + +	return ret; +} +  static noinline void __init kernel_init_freeable(void);  static int __ref kernel_init(void *unused)  { +	int ret; +  	kernel_init_freeable();  	/* need to finish all async __init code before freeing the memory */  	async_synchronize_full(); @@ -824,9 +851,11 @@ static int __ref kernel_init(void *unused)  	flush_delayed_fput();  	if (ramdisk_execute_command) { -		if (!run_init_process(ramdisk_execute_command)) +		ret = run_init_process(ramdisk_execute_command); +		if (!ret)  			return 0; -		pr_err("Failed to execute %s\n", ramdisk_execute_command); +		pr_err("Failed to execute %s (error %d)\n", +		       ramdisk_execute_command, ret);  	}  	/* @@ -836,18 +865,19 @@ static int __ref kernel_init(void *unused)  	 * trying to recover a really broken machine.  	 */  	if (execute_command) { -		if (!run_init_process(execute_command)) +		ret = run_init_process(execute_command); +		if (!ret)  			return 0; -		pr_err("Failed to execute %s.  Attempting defaults...\n", -			execute_command); +		pr_err("Failed to execute %s (error %d).  Attempting defaults...\n", +			execute_command, ret);  	} -	if (!run_init_process("/sbin/init") || -	    !run_init_process("/etc/init") || -	    !run_init_process("/bin/init") || -	    !run_init_process("/bin/sh")) +	if (!try_to_run_init_process("/sbin/init") || +	    !try_to_run_init_process("/etc/init") || +	    !try_to_run_init_process("/bin/init") || +	    !try_to_run_init_process("/bin/sh"))  		return 0; -	panic("No init found.  Try passing init= option to kernel. " +	panic("No working init found.  Try passing init= option to kernel. "  	      "See Linux Documentation/init.txt for guidance.");  }  |