aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-07-16 21:35:30 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 21:35:30 -0400
commitd39f3d77c9b1fe7cc33a14beb4a4849af0a4ac22 (patch)
treebf3a4fd34aa850a5f30f966dfd98a40a424f6b9a /kernel
parent96efedf1491cdf0616e5e4fff0711cebf20f69c7 (diff)
kmsg - export "continuation record" flag to /dev/kmsg
In some cases we are forced to store individual records for a continuation line print. Export a flag to allow the external re-construction of the line. The flag allows us to apply a similar logic externally which is used internally when the console, /proc/kmsg or the syslog() output is printed. $ cat /dev/kmsg 4,165,0,-;Free swap = 0kB 4,166,0,-;Total swap = 0kB 6,167,0,c;[ 4,168,0,+;0 4,169,0,+;1 4,170,0,+;2 4,171,0,+;3 4,172,0,+;] 6,173,0,-;[0 1 2 3 ] 6,174,0,-;Console: colour VGA+ 80x25 6,175,0,-;console [tty0] enabled Signed-off-by: Kay Sievers <kay@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/printk.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 6c3d5bf14da2..a41106e19077 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -361,6 +361,7 @@ static void log_store(int facility, int level,
361struct devkmsg_user { 361struct devkmsg_user {
362 u64 seq; 362 u64 seq;
363 u32 idx; 363 u32 idx;
364 enum log_flags prev;
364 struct mutex lock; 365 struct mutex lock;
365 char buf[8192]; 366 char buf[8192];
366}; 367};
@@ -426,6 +427,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
426 struct log *msg; 427 struct log *msg;
427 u64 ts_usec; 428 u64 ts_usec;
428 size_t i; 429 size_t i;
430 char cont = '-';
429 size_t len; 431 size_t len;
430 ssize_t ret; 432 ssize_t ret;
431 433
@@ -463,8 +465,25 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
463 msg = log_from_idx(user->idx); 465 msg = log_from_idx(user->idx);
464 ts_usec = msg->ts_nsec; 466 ts_usec = msg->ts_nsec;
465 do_div(ts_usec, 1000); 467 do_div(ts_usec, 1000);
466 len = sprintf(user->buf, "%u,%llu,%llu;", 468
467 (msg->facility << 3) | msg->level, user->seq, ts_usec); 469 /*
470 * If we couldn't merge continuation line fragments during the print,
471 * export the stored flags to allow an optional external merge of the
472 * records. Merging the records isn't always neccessarily correct, like
473 * when we hit a race during printing. In most cases though, it produces
474 * better readable output. 'c' in the record flags mark the first
475 * fragment of a line, '+' the following.
476 */
477 if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
478 cont = 'c';
479 else if ((msg->flags & LOG_CONT) ||
480 ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
481 cont = '+';
482
483 len = sprintf(user->buf, "%u,%llu,%llu,%c;",
484 (msg->facility << 3) | msg->level,
485 user->seq, ts_usec, cont);
486 user->prev = msg->flags;
468 487
469 /* escape non-printable characters */ 488 /* escape non-printable characters */
470 for (i = 0; i < msg->text_len; i++) { 489 for (i = 0; i < msg->text_len; i++) {