Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
[cascardo/linux.git] / init / main.c
index 63d3e8f..01573fd 100644 (file)
@@ -124,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];
@@ -132,10 +131,19 @@ 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
@@ -348,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);
@@ -467,7 +476,7 @@ static void __init mm_init(void)
        mem_init();
        kmem_cache_init();
        percpu_init_late();
-       pgtable_cache_init();
+       pgtable_init();
        vmalloc_init();
 }
 
@@ -693,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));
@@ -745,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);
@@ -811,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();
@@ -826,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);
        }
 
        /*
@@ -838,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.");
 }