Commit 5fd29d6c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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: default avatarArjan van de Ven <arjan@infradead.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 03347e25
...@@ -102,7 +102,7 @@ extern const char linux_proc_banner[]; ...@@ -102,7 +102,7 @@ extern const char linux_proc_banner[];
* line that had no enclosing \n). Only to be used by core/arch code * line that had no enclosing \n). Only to be used by core/arch code
* during early bootup (a continued line is not SMP-safe otherwise). * during early bootup (a continued line is not SMP-safe otherwise).
*/ */
#define KERN_CONT "" #define KERN_CONT "<c>"
extern int console_printk[]; extern int console_printk[];
......
...@@ -687,20 +687,33 @@ asmlinkage int vprintk(const char *fmt, va_list args) ...@@ -687,20 +687,33 @@ asmlinkage int vprintk(const char *fmt, va_list args)
sizeof(printk_buf) - printed_len, fmt, args); sizeof(printk_buf) - printed_len, fmt, args);
p = printk_buf;
/* Do we have a loglevel in the string? */
if (p[0] == '<') {
unsigned char c = p[1];
if (c && p[2] == '>') {
switch (c) {
case '0' ... '7': /* loglevel */
current_log_level = c - '0';
if (!new_text_line) {
emit_log_char('\n');
new_text_line = 1;
}
/* Fallthrough - skip the loglevel */
case 'c': /* KERN_CONT */
p += 3;
break;
}
}
}
/* /*
* Copy the output into log_buf. If the caller didn't provide * Copy the output into log_buf. If the caller didn't provide
* appropriate log level tags, we insert them here * appropriate log level tags, we insert them here
*/ */
for (p = printk_buf; *p; p++) { for ( ; *p; p++) {
if (new_text_line) { if (new_text_line) {
/* If a token, set current_log_level and skip over */
if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
p[2] == '>') {
current_log_level = p[1] - '0';
p += 3;
printed_len -= 3;
}
/* Always output the token */ /* Always output the token */
emit_log_char('<'); emit_log_char('<');
emit_log_char(current_log_level + '0'); emit_log_char(current_log_level + '0');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment