VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / init / main.c
index 613aaab..cafeaeb 100644 (file)
 #include <linux/efi.h>
 #include <linux/unistd.h>
 #include <linux/rmap.h>
+#include <linux/mempolicy.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
+#include <asm/setup.h>
 
 /*
  * This is one of the first .c files built. Error out early
@@ -110,6 +112,9 @@ extern void time_init(void);
 void (*late_time_init)(void);
 extern void softirq_init(void);
 
+/* Untouched command line (eg. for /proc) saved by arch-specific code. */
+char saved_command_line[COMMAND_LINE_SIZE];
+
 static char *execute_command;
 
 /* Setup configured maximum number of CPUs to activate */
@@ -156,8 +161,14 @@ static int __init obsolete_checksetup(char *line)
        do {
                int n = strlen(p->str);
                if (!strncmp(line, p->str, n)) {
-                       if (!p->setup_func) {
-                               printk(KERN_WARNING "Parameter %s is obsolete, ignored\n", p->str);
+                       if (p->early) {
+                               /* Already done in parse_early_param?  (Needs
+                                * exact match on param part) */
+                               if (line[n] == '\0' || line[n] == '=')
+                                       return 1;
+                       } else if (!p->setup_func) {
+                               printk(KERN_WARNING "Parameter %s is obsolete,"
+                                      " ignored\n", p->str);
                                return 1;
                        } else if (p->setup_func(line + n))
                                return 1;
@@ -268,6 +279,8 @@ static int __init unknown_bootoption(char *param, char *val)
                                panic_later = "Too many boot env vars at `%s'";
                                panic_param = param;
                        }
+                       if (!strncmp(param, envp_init[i], val - param))
+                               break;
                }
                envp_init[i] = param;
        } else {
@@ -385,10 +398,43 @@ static void __init smp_init(void)
 static void noinline rest_init(void)
 {
        kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+       numa_default_policy();
        unlock_kernel();
        cpu_idle();
 } 
 
+/* Check for early params. */
+static int __init do_early_param(char *param, char *val)
+{
+       struct obs_kernel_param *p;
+       extern struct obs_kernel_param __setup_start, __setup_end;
+
+       for (p = &__setup_start; p < &__setup_end; p++) {
+               if (p->early && strcmp(param, p->str) == 0) {
+                       if (p->setup_func(val) != 0)
+                               printk(KERN_WARNING
+                                      "Malformed early option '%s'\n", param);
+               }
+       }
+       /* We accept everything at this stage. */
+       return 0;
+}
+
+/* Arch code calls this early on, or if not, just before other parsing. */
+void __init parse_early_param(void)
+{
+       static __initdata int done = 0;
+       static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
+
+       if (done)
+               return;
+
+       /* All fall through to do_early_param. */
+       strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE);
+       parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
+       done = 1;
+}
+
 /*
  *     Activate the first processor.
  */
@@ -396,7 +442,6 @@ static void noinline rest_init(void)
 asmlinkage void __init start_kernel(void)
 {
        char * command_line;
-       extern char saved_command_line[];
        extern struct kernel_param __start___param[], __stop___param[];
 /*
  * Interrupts are still disabled. Do necessary setups, then
@@ -424,6 +469,7 @@ asmlinkage void __init start_kernel(void)
        build_all_zonelists();
        page_alloc_init();
        printk("Kernel command line: %s\n", saved_command_line);
+       parse_early_param();
        parse_args("Booting kernel", command_line, __start___param,
                   __stop___param - __start___param,
                   &unknown_bootoption);
@@ -454,8 +500,10 @@ asmlinkage void __init start_kernel(void)
                initrd_start = 0;
        }
 #endif
+       vfs_caches_init_early();
        mem_init();
        kmem_cache_init();
+       numa_policy_init();
        if (late_time_init)
                late_time_init();
        calibrate_delay();
@@ -645,6 +693,7 @@ static int init(void * unused)
        free_initmem();
        unlock_kernel();
        system_state = SYSTEM_RUNNING;
+       numa_default_policy();
 
        if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
                printk("Warning: unable to open an initial console.\n");
@@ -669,3 +718,16 @@ static int init(void * unused)
 
        panic("No init found.  Try passing init= option to kernel.");
 }
+
+static int early_param_test(char *rest)
+{
+       printk("early_parm_test: %s\n", rest ?: "(null)");
+       return rest ? 0 : -EINVAL;
+}
+early_param("testsetup", early_param_test);
+static int early_setup_test(char *rest)
+{
+       printk("early_setup_test: %s\n", rest ?: "(null)");
+       return 0;
+}
+__setup("testsetup_long", early_setup_test);