eCryptfs: fix Tag 1 parsing code
[safe/jmp/linux-2.6] / kernel / printk.c
index 4961410..b2b5c3a 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/tty_driver.h>
 #include <linux/console.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/nmi.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/interrupt.h>                   /* For in_interrupt() */
@@ -162,6 +164,61 @@ out:
 
 __setup("log_buf_len=", log_buf_len_setup);
 
+#ifdef CONFIG_BOOT_PRINTK_DELAY
+
+static unsigned int boot_delay; /* msecs delay after each printk during bootup */
+static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
+
+static int __init boot_delay_setup(char *str)
+{
+       unsigned long lpj;
+       unsigned long long loops_per_msec;
+
+       lpj = preset_lpj ? preset_lpj : 1000000;        /* some guess */
+       loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
+
+       get_option(&str, &boot_delay);
+       if (boot_delay > 10 * 1000)
+               boot_delay = 0;
+
+       printk_delay_msec = loops_per_msec;
+       printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
+               "HZ: %d, printk_delay_msec: %llu\n",
+               boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
+       return 1;
+}
+__setup("boot_delay=", boot_delay_setup);
+
+static void boot_delay_msec(void)
+{
+       unsigned long long k;
+       unsigned long timeout;
+
+       if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
+               return;
+
+       k = (unsigned long long)printk_delay_msec * boot_delay;
+
+       timeout = jiffies + msecs_to_jiffies(boot_delay);
+       while (k) {
+               k--;
+               cpu_relax();
+               /*
+                * use (volatile) jiffies to prevent
+                * compiler reduction; loop termination via jiffies
+                * is secondary and may or may not happen.
+                */
+               if (time_after(jiffies, timeout))
+                       break;
+               touch_nmi_watchdog();
+       }
+}
+#else
+static inline void boot_delay_msec(void)
+{
+}
+#endif
+
 /*
  * Commands to do_syslog:
  *
@@ -449,13 +506,16 @@ static int printk_time = 1;
 #else
 static int printk_time = 0;
 #endif
-module_param(printk_time, int, S_IRUGO | S_IWUSR);
+module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
 
 static int __init printk_time_setup(char *str)
 {
        if (*str)
                return 0;
        printk_time = 1;
+       printk(KERN_NOTICE "The 'time' option is deprecated and "
+               "is scheduled for removal in early 2008\n");
+       printk(KERN_NOTICE "Use 'printk.time=<value>' instead\n");
        return 1;
 }
 
@@ -483,6 +543,9 @@ static int have_callable_console(void)
  * @fmt: format string
  *
  * This is printk().  It can be called from any context.  We want it to work.
+ * Be aware of the fact that if oops_in_progress is not set, we might try to
+ * wake klogd up which could deadlock on runqueue lock if printk() is called
+ * from scheduler code.
  *
  * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
  * call the console drivers.  If we fail to get the semaphore we place the output
@@ -521,6 +584,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
        static char printk_buf[1024];
        static int log_level_unknown = 1;
 
+       boot_delay_msec();
+
        preempt_disable();
        if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
                /* If a crash is occurring during printk() on this CPU,
@@ -726,6 +791,25 @@ int __init add_preferred_console(char *name, int idx, char *options)
        return 0;
 }
 
+int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options)
+{
+       struct console_cmdline *c;
+       int i;
+
+       for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++)
+               if (strcmp(console_cmdline[i].name, name) == 0 &&
+                         console_cmdline[i].index == idx) {
+                               c = &console_cmdline[i];
+                               memcpy(c->name, name_new, sizeof(c->name));
+                               c->name[sizeof(c->name) - 1] = 0;
+                               c->options = options;
+                               c->index = idx_new;
+                               return i;
+               }
+       /* not found */
+       return -1;
+}
+
 #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND
 /**
  * suspend_console - suspend the console subsystem
@@ -942,6 +1026,9 @@ void register_console(struct console *console)
        if (preferred_console < 0 || bootconsole || !console_drivers)
                preferred_console = selected_console;
 
+       if (console->early_setup)
+               console->early_setup();
+
        /*
         *      See if we want to use this console driver. If we
         *      didn't select a console we take the first one
@@ -985,12 +1072,15 @@ void register_console(struct console *console)
        if (!(console->flags & CON_ENABLED))
                return;
 
-       if (bootconsole) {
+       if (bootconsole && (console->flags & CON_CONSDEV)) {
                printk(KERN_INFO "console handover: boot [%s%d] -> real [%s%d]\n",
                       bootconsole->name, bootconsole->index,
                       console->name, console->index);
                unregister_console(bootconsole);
                console->flags &= ~CON_PRINTBUFFER;
+       } else {
+               printk(KERN_INFO "console [%s%d] enabled\n",
+                      console->name, console->index);
        }
 
        /*
@@ -1052,6 +1142,19 @@ int unregister_console(struct console *console)
 }
 EXPORT_SYMBOL(unregister_console);
 
+static int __init disable_boot_consoles(void)
+{
+       if (console_drivers != NULL) {
+               if (console_drivers->flags & CON_BOOT) {
+                       printk(KERN_INFO "turn off boot console %s%d\n",
+                               console_drivers->name, console_drivers->index);
+                       return unregister_console(console_drivers);
+               }
+       }
+       return 0;
+}
+late_initcall(disable_boot_consoles);
+
 /**
  * tty_write_message - write a message to a certain tty, not just the console.
  * @tty: the destination tty_struct