Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d39f3d77 authored by Kay Sievers's avatar Kay Sievers Committed by Greg Kroah-Hartman
Browse files

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: default avatarKay Sievers <kay@vrfy.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 96efedf1
Loading
Loading
Loading
Loading
+20 −9
Original line number Original line Diff line number Diff line
@@ -58,16 +58,18 @@ Description: The /dev/kmsg character device node provides userspace access


		The output format consists of a prefix carrying the syslog
		The output format consists of a prefix carrying the syslog
		prefix including priority and facility, the 64 bit message
		prefix including priority and facility, the 64 bit message
		sequence number and the monotonic timestamp in microseconds.
		sequence number and the monotonic timestamp in microseconds,
		The values are separated by a ','. Future extensions might
		and a flag field. All fields are separated by a ','.
		add more comma separated values before the terminating ';'.

		Unknown values should be gracefully ignored.
		Future extensions might add more comma separated values before
		the terminating ';'. Unknown fields and values should be
		gracefully ignored.


		The human readable text string starts directly after the ';'
		The human readable text string starts directly after the ';'
		and is terminated by a '\n'. Untrusted values derived from
		and is terminated by a '\n'. Untrusted values derived from
		hardware or other facilities are printed, therefore
		hardware or other facilities are printed, therefore
		all non-printable characters in the log message are escaped
		all non-printable characters and '\' itself in the log message
		by "\x00" C-style hex encoding.
		are escaped by "\x00" C-style hex encoding.


		A line starting with ' ', is a continuation line, adding
		A line starting with ' ', is a continuation line, adding
		key/value pairs to the log message, which provide the machine
		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
		userspace.
		userspace.


		Example:
		Example:
		7,160,424069;pci_root PNP0A03:00: host bridge window [io  0x0000-0x0cf7] (ignored)
		7,160,424069,-;pci_root PNP0A03:00: host bridge window [io  0x0000-0x0cf7] (ignored)
		 SUBSYSTEM=acpi
		 SUBSYSTEM=acpi
		 DEVICE=+acpi:PNP0A03:00
		 DEVICE=+acpi:PNP0A03:00
		6,339,5140900;NET: Registered protocol family 10
		6,339,5140900,-;NET: Registered protocol family 10
		30,340,5690716;udevd[80]: starting version 181
		30,340,5690716,-;udevd[80]: starting version 181


		The DEVICE= key uniquely identifies devices the following way:
		The DEVICE= key uniquely identifies devices the following way:
		  b12:8        - block dev_t
		  b12:8        - block dev_t
@@ -87,4 +89,13 @@ Description: The /dev/kmsg character device node provides userspace access
		  n8           - netdev ifindex
		  n8           - netdev ifindex
		  +sound:card0 - subsystem:devname
		  +sound:card0 - subsystem:devname


		The flags field carries '-' by default. A 'c' indicates a
		fragment of a line. All following fragments are flagged with
		'+'. Note, that these hints about continuation lines are not
		neccessarily correct, and the stream could be interleaved with
		unrelated messages, but merging the lines in the output
		usually produces better human readable results. A similar
		logic is used internally when messages are printed to the
		console, /proc/kmsg or the syslog() syscall.

Users:		dmesg(1), userspace kernel log consumers
Users:		dmesg(1), userspace kernel log consumers
+21 −2
Original line number Original line Diff line number Diff line
@@ -361,6 +361,7 @@ static void log_store(int facility, int level,
struct devkmsg_user {
struct devkmsg_user {
	u64 seq;
	u64 seq;
	u32 idx;
	u32 idx;
	enum log_flags prev;
	struct mutex lock;
	struct mutex lock;
	char buf[8192];
	char buf[8192];
};
};
@@ -426,6 +427,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
	struct log *msg;
	struct log *msg;
	u64 ts_usec;
	u64 ts_usec;
	size_t i;
	size_t i;
	char cont = '-';
	size_t len;
	size_t len;
	ssize_t ret;
	ssize_t ret;


@@ -463,8 +465,25 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
	msg = log_from_idx(user->idx);
	msg = log_from_idx(user->idx);
	ts_usec = msg->ts_nsec;
	ts_usec = msg->ts_nsec;
	do_div(ts_usec, 1000);
	do_div(ts_usec, 1000);
	len = sprintf(user->buf, "%u,%llu,%llu;",

		      (msg->facility << 3) | msg->level, user->seq, ts_usec);
	/*
	 * If we couldn't merge continuation line fragments during the print,
	 * export the stored flags to allow an optional external merge of the
	 * records. Merging the records isn't always neccessarily correct, like
	 * when we hit a race during printing. In most cases though, it produces
	 * better readable output. 'c' in the record flags mark the first
	 * fragment of a line, '+' the following.
	 */
	if (msg->flags & LOG_CONT && !(user->prev & LOG_CONT))
		cont = 'c';
	else if ((msg->flags & LOG_CONT) ||
		 ((user->prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)))
		cont = '+';

	len = sprintf(user->buf, "%u,%llu,%llu,%c;",
		      (msg->facility << 3) | msg->level,
		      user->seq, ts_usec, cont);
	user->prev = msg->flags;


	/* escape non-printable characters */
	/* escape non-printable characters */
	for (i = 0; i < msg->text_len; i++) {
	for (i = 0; i < msg->text_len; i++) {