aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/dev-kmsg29
-rw-r--r--kernel/printk.c23
2 files changed, 41 insertions, 11 deletions
diff --git a/Documentation/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg
index 281ecc5f9709..7e7e07a82e0e 100644
--- a/Documentation/ABI/testing/dev-kmsg
+++ b/Documentation/ABI/testing/dev-kmsg
@@ -58,16 +58,18 @@ Description: The /dev/kmsg character device node provides userspace access
58 58
59 The output format consists of a prefix carrying the syslog 59 The output format consists of a prefix carrying the syslog
60 prefix including priority and facility, the 64 bit message 60 prefix including priority and facility, the 64 bit message
61 sequence number and the monotonic timestamp in microseconds. 61 sequence number and the monotonic timestamp in microseconds,
62 The values are separated by a ','. Future extensions might 62 and a flag field. All fields are separated by a ','.
63 add more comma separated values before the terminating ';'. 63
64 Unknown values should be gracefully ignored. 64 Future extensions might add more comma separated values before
65 the terminating ';'. Unknown fields and values should be
66 gracefully ignored.
65 67
66 The human readable text string starts directly after the ';' 68 The human readable text string starts directly after the ';'
67 and is terminated by a '\n'. Untrusted values derived from 69 and is terminated by a '\n'. Untrusted values derived from
68 hardware or other facilities are printed, therefore 70 hardware or other facilities are printed, therefore
69 all non-printable characters in the log message are escaped 71 all non-printable characters and '\' itself in the log message
70 by "\x00" C-style hex encoding. 72 are escaped by "\x00" C-style hex encoding.
71 73
72 A line starting with ' ', is a continuation line, adding 74 A line starting with ' ', is a continuation line, adding
73 key/value pairs to the log message, which provide the machine 75 key/value pairs to the log message, which provide the machine
@@ -75,11 +77,11 @@ Description: The /dev/kmsg character device node provides userspace access
75 userspace. 77 userspace.
76 78
77 Example: 79 Example:
78 7,160,424069;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) 80 7,160,424069,-;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored)
79 SUBSYSTEM=acpi 81 SUBSYSTEM=acpi
80 DEVICE=+acpi:PNP0A03:00 82 DEVICE=+acpi:PNP0A03:00
81 6,339,5140900;NET: Registered protocol family 10 83 6,339,5140900,-;NET: Registered protocol family 10
82 30,340,5690716;udevd[80]: starting version 181 84 30,340,5690716,-;udevd[80]: starting version 181
83 85
84 The DEVICE= key uniquely identifies devices the following way: 86 The DEVICE= key uniquely identifies devices the following way:
85 b12:8 - block dev_t 87 b12:8 - block dev_t
@@ -87,4 +89,13 @@ Description: The /dev/kmsg character device node provides userspace access
87 n8 - netdev ifindex 89 n8 - netdev ifindex
88 +sound:card0 - subsystem:devname 90 +sound:card0 - subsystem:devname
89 91
92 The flags field carries '-' by default. A 'c' indicates a
93 fragment of a line. All following fragments are flagged with
94 '+'. Note, that these hints about continuation lines are not
95 neccessarily correct, and the stream could be interleaved with
96 unrelated messages, but merging the lines in the output
97 usually produces better human readable results. A similar
98 logic is used internally when messages are printed to the
99 console, /proc/kmsg or the syslog() syscall.
100
90Users: dmesg(1), userspace kernel log consumers 101Users: dmesg(1), userspace kernel log consumers
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++) {