On Fri, Mar 11, 2011 at 7:11 PM, Lennart Poettering
<lenn...@poettering.net> wrote:
> On Fri, 11.03.11 08:45, Michael Biebl (mbi...@gmail.com) wrote:
>
>>
>> 2011/3/11 Rainer Gerhards <rgerha...@hq.adiscon.com>:
>> >
>> > So isn't that already a solution?
>> >
>>
>> The problem with PRINTK_TIME afaics is that it needs to be turned on
>> explicitly whereas I'd expect SO_TIMESTAMP will be available always
>> (if the kernel is recent enough)?
>
> PRINTK_TIME applies to /proc/kmsg data. SO_TIMESTAMP applies to /dev/log
> sockets.
>
>> In any case you'd need to interpret that data on the rsyslog side, to
>> compute a correct time stamp and then (optionally) strip off the [
>> 5913.491848] markers.
>
> Yupp, that's what I'd like to see.
>
> But there's actually something else I'd like to see, as well:
>
> Parse the <x> priority field read from /proc/kmsg like it is normally
> done for /dev/log messages.
>
> i.e. traditionally, since only the kernel wrote to dmesg all lines where
> prefixed with prios from the range 0..7 only. And some tools can just
> parse that: a prefix of "<" plus one number from 0..7 plus ">". It would
> be cool to beef that up and parse the full 8bit priority field there
> too, i.e. not just the 3 bit for the priority, but also the 5 bit for
> the facility. Since facility=0 refers to kernel messages the kernel
> messages would be identified as facility=kernel, but in case user code
> logs something there it can pass the correct facility and the userspace
> syslog daemon should then not override that facility with kernel
> anymore.
>
> The result of this all put together would be that userspace can log via
> /dev/kmsg or via /dev/log and not metadata would be lost anymore. Not
> the prio, not the facility, and not the timestamp.
>

Well ... the problem really is that format is supposed to be single
printable character, which does not really support bit operations and
such. What about attached (completely untested) path - which adds <u>
marker to anything written into /dev/kmsg?
From: Andrey Borzenkov <arvidj...@gmail.com>
Subject: [PATCH] add KERN_USER facility for lines injected by user space

This allows preserve information that log lines came from user
space, so that later kmsg consumer can apply proper filtering.

It is intended to be used by early boot code logging (initramfs)
until syslog becomes available. When syslog starts, it can correctly
route these messages according to original producer.

Lines are expected to be in standard syslog format.

---
 drivers/char/mem.c     |    2 +-
 include/linux/printk.h |    8 ++++++++
 kernel/printk.c        |   33 ++++++++++++++++++++++++++-------
 3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 1256454..f965a00 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -821,7 +821,7 @@ static ssize_t kmsg_write(struct file *file, const char __user *buf,
 	ret = -EFAULT;
 	if (!copy_from_user(tmp, buf, count)) {
 		tmp[count] = 0;
-		ret = printk("%s", tmp);
+		ret = printk(KERN_USER "%s", tmp);
 		if (ret > count)
 			/* printk can add a prefix */
 			ret = count;
diff --git a/include/linux/printk.h b/include/linux/printk.h
index ee048e7..cd788df 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -22,6 +22,14 @@ extern const char linux_proc_banner[];
  */
 #define KERN_CONT	"<c>"
 
+/*
+ * Annotation for a "user" line. Every line written to /dev/kmsg from
+ * userspace will be prefixed with <u> to distinguish it from messages
+ * generated by kernel. This provides for proper filtering in user
+ * space later and is intended for use during early bootup.
+ */
+#define KERN_USER	"<u>"
+
 extern int console_printk[];
 
 #define console_loglevel (console_printk[0])
diff --git a/kernel/printk.c b/kernel/printk.c
index 3623152..3060e59 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -529,13 +529,20 @@ static void call_console_drivers(unsigned start, unsigned end)
 	cur_index = start;
 	start_print = start;
 	while (cur_index != end) {
-		if (msg_level < 0 && ((end - cur_index) > 2) &&
-				LOG_BUF(cur_index + 0) == '<' &&
-				LOG_BUF(cur_index + 1) >= '0' &&
-				LOG_BUF(cur_index + 1) <= '7' &&
-				LOG_BUF(cur_index + 2) == '>') {
-			msg_level = LOG_BUF(cur_index + 1) - '0';
-			cur_index += 3;
+		if (msg_level < 0) {
+			if ((end - cur_index) > 5 &&
+			    LOG_BUF(cur_index + 0) == '<' &&
+			    LOG_BUF(cur_index + 1) == 'u' &&
+			    LOG_BUF(cur_index + 2) == '>')
+				cur_index += 3;
+			if ((end - cur_index) > 2 &&
+			    LOG_BUF(cur_index + 0) == '<' &&
+			    LOG_BUF(cur_index + 1) >= '0' &&
+			    LOG_BUF(cur_index + 1) <= '7' &&
+			    LOG_BUF(cur_index + 2) == '>') {
+				msg_level = LOG_BUF(cur_index + 1) - '0';
+				cur_index += 3;
+			}
 			start_print = cur_index;
 		}
 		while (cur_index != end) {
@@ -733,6 +740,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	unsigned long flags;
 	int this_cpu;
 	char *p;
+	int from_user = 0;
 
 	boot_delay_msec();
 	printk_delay();
@@ -780,6 +788,12 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	if (p[0] == '<') {
 		unsigned char c = p[1];
 		if (c && p[2] == '>') {
+			if (printed_len >= 6 && c == 'u' && p[3] == '<' &&
+			    p[4] && p[5] == '>') {
+				c = p[4];
+				from_user = 1;
+				p += 3;
+			}
 			switch (c) {
 			case '0' ... '7': /* loglevel */
 				current_log_level = c - '0';
@@ -804,6 +818,11 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	for ( ; *p; p++) {
 		if (new_text_line) {
 			/* Always output the token */
+			if (from_user) {
+				emit_log_char('<');
+				emit_log_char('u');
+				emit_log_char('>');
+			}
 			emit_log_char('<');
 			emit_log_char(current_log_level + '0');
 			emit_log_char('>');
-- 
tg: (9179746..) u/user-printk (depends on: origin/master)
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to