aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/printk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printk.c')
-rw-r--r--kernel/printk.c174
1 files changed, 138 insertions, 36 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 36231525e22f..da8ca817eae3 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -53,7 +53,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
53#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) 53#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
54 54
55/* printk's without a loglevel use this.. */ 55/* printk's without a loglevel use this.. */
56#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ 56#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
57 57
58/* We show everything that is MORE important than this.. */ 58/* We show everything that is MORE important than this.. */
59#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ 59#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
@@ -113,6 +113,11 @@ static unsigned con_start; /* Index into log_buf: next char to be sent to consol
113static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ 113static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */
114 114
115/* 115/*
116 * If exclusive_console is non-NULL then only this console is to be printed to.
117 */
118static struct console *exclusive_console;
119
120/*
116 * Array of consoles built from command line options (console=) 121 * Array of consoles built from command line options (console=)
117 */ 122 */
118struct console_cmdline 123struct console_cmdline
@@ -476,6 +481,8 @@ static void __call_console_drivers(unsigned start, unsigned end)
476 struct console *con; 481 struct console *con;
477 482
478 for_each_console(con) { 483 for_each_console(con) {
484 if (exclusive_console && con != exclusive_console)
485 continue;
479 if ((con->flags & CON_ENABLED) && con->write && 486 if ((con->flags & CON_ENABLED) && con->write &&
480 (cpu_online(smp_processor_id()) || 487 (cpu_online(smp_processor_id()) ||
481 (con->flags & CON_ANYTIME))) 488 (con->flags & CON_ANYTIME)))
@@ -515,6 +522,71 @@ static void _call_console_drivers(unsigned start,
515} 522}
516 523
517/* 524/*
525 * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the
526 * lower 3 bit are the log level, the rest are the log facility. In case
527 * userspace passes usual userspace syslog messages to /dev/kmsg or
528 * /dev/ttyprintk, the log prefix might contain the facility. Printk needs
529 * to extract the correct log level for in-kernel processing, and not mangle
530 * the original value.
531 *
532 * If a prefix is found, the length of the prefix is returned. If 'level' is
533 * passed, it will be filled in with the log level without a possible facility
534 * value. If 'special' is passed, the special printk prefix chars are accepted
535 * and returned. If no valid header is found, 0 is returned and the passed
536 * variables are not touched.
537 */
538static size_t log_prefix(const char *p, unsigned int *level, char *special)
539{
540 unsigned int lev = 0;
541 char sp = '\0';
542 size_t len;
543
544 if (p[0] != '<' || !p[1])
545 return 0;
546 if (p[2] == '>') {
547 /* usual single digit level number or special char */
548 switch (p[1]) {
549 case '0' ... '7':
550 lev = p[1] - '0';
551 break;
552 case 'c': /* KERN_CONT */
553 case 'd': /* KERN_DEFAULT */
554 sp = p[1];
555 break;
556 default:
557 return 0;
558 }
559 len = 3;
560 } else {
561 /* multi digit including the level and facility number */
562 char *endp = NULL;
563
564 if (p[1] < '0' && p[1] > '9')
565 return 0;
566
567 lev = (simple_strtoul(&p[1], &endp, 10) & 7);
568 if (endp == NULL || endp[0] != '>')
569 return 0;
570 len = (endp + 1) - p;
571 }
572
573 /* do not accept special char if not asked for */
574 if (sp && !special)
575 return 0;
576
577 if (special) {
578 *special = sp;
579 /* return special char, do not touch level */
580 if (sp)
581 return len;
582 }
583
584 if (level)
585 *level = lev;
586 return len;
587}
588
589/*
518 * Call the console drivers, asking them to write out 590 * Call the console drivers, asking them to write out
519 * log_buf[start] to log_buf[end - 1]. 591 * log_buf[start] to log_buf[end - 1].
520 * The console_lock must be held. 592 * The console_lock must be held.
@@ -529,13 +601,9 @@ static void call_console_drivers(unsigned start, unsigned end)
529 cur_index = start; 601 cur_index = start;
530 start_print = start; 602 start_print = start;
531 while (cur_index != end) { 603 while (cur_index != end) {
532 if (msg_level < 0 && ((end - cur_index) > 2) && 604 if (msg_level < 0 && ((end - cur_index) > 2)) {
533 LOG_BUF(cur_index + 0) == '<' && 605 /* strip log prefix */
534 LOG_BUF(cur_index + 1) >= '0' && 606 cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL);
535 LOG_BUF(cur_index + 1) <= '7' &&
536 LOG_BUF(cur_index + 2) == '>') {
537 msg_level = LOG_BUF(cur_index + 1) - '0';
538 cur_index += 3;
539 start_print = cur_index; 607 start_print = cur_index;
540 } 608 }
541 while (cur_index != end) { 609 while (cur_index != end) {
@@ -733,6 +801,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
733 unsigned long flags; 801 unsigned long flags;
734 int this_cpu; 802 int this_cpu;
735 char *p; 803 char *p;
804 size_t plen;
805 char special;
736 806
737 boot_delay_msec(); 807 boot_delay_msec();
738 printk_delay(); 808 printk_delay();
@@ -773,45 +843,52 @@ asmlinkage int vprintk(const char *fmt, va_list args)
773 printed_len += vscnprintf(printk_buf + printed_len, 843 printed_len += vscnprintf(printk_buf + printed_len,
774 sizeof(printk_buf) - printed_len, fmt, args); 844 sizeof(printk_buf) - printed_len, fmt, args);
775 845
776
777 p = printk_buf; 846 p = printk_buf;
778 847
779 /* Do we have a loglevel in the string? */ 848 /* Read log level and handle special printk prefix */
780 if (p[0] == '<') { 849 plen = log_prefix(p, &current_log_level, &special);
781 unsigned char c = p[1]; 850 if (plen) {
782 if (c && p[2] == '>') { 851 p += plen;
783 switch (c) { 852
784 case '0' ... '7': /* loglevel */ 853 switch (special) {
785 current_log_level = c - '0'; 854 case 'c': /* Strip <c> KERN_CONT, continue line */
786 /* Fallthrough - make sure we're on a new line */ 855 plen = 0;
787 case 'd': /* KERN_DEFAULT */ 856 break;
788 if (!new_text_line) { 857 case 'd': /* Strip <d> KERN_DEFAULT, start new line */
789 emit_log_char('\n'); 858 plen = 0;
790 new_text_line = 1; 859 default:
791 } 860 if (!new_text_line) {
792 /* Fallthrough - skip the loglevel */ 861 emit_log_char('\n');
793 case 'c': /* KERN_CONT */ 862 new_text_line = 1;
794 p += 3;
795 break;
796 } 863 }
797 } 864 }
798 } 865 }
799 866
800 /* 867 /*
801 * Copy the output into log_buf. If the caller didn't provide 868 * Copy the output into log_buf. If the caller didn't provide
802 * appropriate log level tags, we insert them here 869 * the appropriate log prefix, we insert them here
803 */ 870 */
804 for ( ; *p; p++) { 871 for (; *p; p++) {
805 if (new_text_line) { 872 if (new_text_line) {
806 /* Always output the token */
807 emit_log_char('<');
808 emit_log_char(current_log_level + '0');
809 emit_log_char('>');
810 printed_len += 3;
811 new_text_line = 0; 873 new_text_line = 0;
812 874
875 if (plen) {
876 /* Copy original log prefix */
877 int i;
878
879 for (i = 0; i < plen; i++)
880 emit_log_char(printk_buf[i]);
881 printed_len += plen;
882 } else {
883 /* Add log prefix */
884 emit_log_char('<');
885 emit_log_char(current_log_level + '0');
886 emit_log_char('>');
887 printed_len += 3;
888 }
889
813 if (printk_time) { 890 if (printk_time) {
814 /* Follow the token with the time */ 891 /* Add the current time stamp */
815 char tbuf[50], *tp; 892 char tbuf[50], *tp;
816 unsigned tlen; 893 unsigned tlen;
817 unsigned long long t; 894 unsigned long long t;
@@ -1160,6 +1237,11 @@ void console_unlock(void)
1160 local_irq_restore(flags); 1237 local_irq_restore(flags);
1161 } 1238 }
1162 console_locked = 0; 1239 console_locked = 0;
1240
1241 /* Release the exclusive_console once it is used */
1242 if (unlikely(exclusive_console))
1243 exclusive_console = NULL;
1244
1163 up(&console_sem); 1245 up(&console_sem);
1164 spin_unlock_irqrestore(&logbuf_lock, flags); 1246 spin_unlock_irqrestore(&logbuf_lock, flags);
1165 if (wake_klogd) 1247 if (wake_klogd)
@@ -1246,6 +1328,18 @@ void console_start(struct console *console)
1246} 1328}
1247EXPORT_SYMBOL(console_start); 1329EXPORT_SYMBOL(console_start);
1248 1330
1331static int __read_mostly keep_bootcon;
1332
1333static int __init keep_bootcon_setup(char *str)
1334{
1335 keep_bootcon = 1;
1336 printk(KERN_INFO "debug: skip boot console de-registration.\n");
1337
1338 return 0;
1339}
1340
1341early_param("keep_bootcon", keep_bootcon_setup);
1342
1249/* 1343/*
1250 * The console driver calls this routine during kernel initialization 1344 * The console driver calls this routine during kernel initialization
1251 * to register the console printing procedure with printk() and to 1345 * to register the console printing procedure with printk() and to
@@ -1382,6 +1476,12 @@ void register_console(struct console *newcon)
1382 spin_lock_irqsave(&logbuf_lock, flags); 1476 spin_lock_irqsave(&logbuf_lock, flags);
1383 con_start = log_start; 1477 con_start = log_start;
1384 spin_unlock_irqrestore(&logbuf_lock, flags); 1478 spin_unlock_irqrestore(&logbuf_lock, flags);
1479 /*
1480 * We're about to replay the log buffer. Only do this to the
1481 * just-registered console to avoid excessive message spam to
1482 * the already-registered consoles.
1483 */
1484 exclusive_console = newcon;
1385 } 1485 }
1386 console_unlock(); 1486 console_unlock();
1387 console_sysfs_notify(); 1487 console_sysfs_notify();
@@ -1393,7 +1493,9 @@ void register_console(struct console *newcon)
1393 * users know there might be something in the kernel's log buffer that 1493 * users know there might be something in the kernel's log buffer that
1394 * went to the bootconsole (that they do not see on the real console) 1494 * went to the bootconsole (that they do not see on the real console)
1395 */ 1495 */
1396 if (bcon && ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) { 1496 if (bcon &&
1497 ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
1498 !keep_bootcon) {
1397 /* we need to iterate through twice, to make sure we print 1499 /* we need to iterate through twice, to make sure we print
1398 * everything out, before we unregister the console(s) 1500 * everything out, before we unregister the console(s)
1399 */ 1501 */