aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 13:57:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-16 13:57:02 -0400
commit5fd29d6ccbc98884569d6f3105aeca70858b3e0f (patch)
tree93ac507debc6b35e5863116086c57170618099cf
parent03347e2592078a90df818670fddf97a33eec70fb (diff)
printk: clean up handling of log-levels and newlines
It used to be that we would only look at the log-level in a printk() after explicit newlines, which can cause annoying problems when the previous printk() did not end with a '\n'. In that case, the log-level marker would be just printed out in the middle of the line, and be seen as just noise rather than change the logging level. This changes things to always look at the log-level in the first bytes of the printout. If a log level marker is found, it is always used as the log-level. Additionally, if no newline existed, one is added (unless the log-level is the explicit KERN_CONT marker, to explicitly show that it's a continuation of a previous line). Acked-by: Arjan van de Ven <arjan@infradead.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/kernel.h2
-rw-r--r--kernel/printk.c31
2 files changed, 23 insertions, 10 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 883cd44ff765..066bb1eddfea 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -102,7 +102,7 @@ extern const char linux_proc_banner[];
102 * line that had no enclosing \n). Only to be used by core/arch code 102 * line that had no enclosing \n). Only to be used by core/arch code
103 * during early bootup (a continued line is not SMP-safe otherwise). 103 * during early bootup (a continued line is not SMP-safe otherwise).
104 */ 104 */
105#define KERN_CONT "" 105#define KERN_CONT "<c>"
106 106
107extern int console_printk[]; 107extern int console_printk[];
108 108
diff --git a/kernel/printk.c b/kernel/printk.c
index 5052b5497c67..a87770ce73a2 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -687,20 +687,33 @@ asmlinkage int vprintk(const char *fmt, va_list args)
687 sizeof(printk_buf) - printed_len, fmt, args); 687 sizeof(printk_buf) - printed_len, fmt, args);
688 688
689 689
690 p = printk_buf;
691
692 /* Do we have a loglevel in the string? */
693 if (p[0] == '<') {
694 unsigned char c = p[1];
695 if (c && p[2] == '>') {
696 switch (c) {
697 case '0' ... '7': /* loglevel */
698 current_log_level = c - '0';
699 if (!new_text_line) {
700 emit_log_char('\n');
701 new_text_line = 1;
702 }
703 /* Fallthrough - skip the loglevel */
704 case 'c': /* KERN_CONT */
705 p += 3;
706 break;
707 }
708 }
709 }
710
690 /* 711 /*
691 * Copy the output into log_buf. If the caller didn't provide 712 * Copy the output into log_buf. If the caller didn't provide
692 * appropriate log level tags, we insert them here 713 * appropriate log level tags, we insert them here
693 */ 714 */
694 for (p = printk_buf; *p; p++) { 715 for ( ; *p; p++) {
695 if (new_text_line) { 716 if (new_text_line) {
696 /* If a token, set current_log_level and skip over */
697 if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
698 p[2] == '>') {
699 current_log_level = p[1] - '0';
700 p += 3;
701 printed_len -= 3;
702 }
703
704 /* Always output the token */ 717 /* Always output the token */
705 emit_log_char('<'); 718 emit_log_char('<');
706 emit_log_char(current_log_level + '0'); 719 emit_log_char(current_log_level + '0');