diff options
author | Kay Sievers <kay@vrfy.org> | 2012-07-09 21:40:39 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2012-07-09 21:40:39 +0200 |
commit | 4912b7f6508109e800f5a84ad61e2a51b3cfc8a7 (patch) | |
tree | 250422a9800087cf64688041b6b2079b95e37d62 | |
parent | beabb5dc199b5c4ff4e3e7bb73cabe077ab7abf5 (diff) | |
download | patches-4912b7f6508109e800f5a84ad61e2a51b3cfc8a7.tar.gz |
remove merged stuff, play with exporting flags
-rw-r--r-- | kmsg-export-flags.patch | 20 | ||||
-rw-r--r-- | kmsg-merge-cont.patch | 412 | ||||
-rw-r--r-- | kmsg-syslog-1-byte-read.patch | 101 | ||||
-rw-r--r-- | series | 5 |
4 files changed, 21 insertions, 517 deletions
diff --git a/kmsg-export-flags.patch b/kmsg-export-flags.patch new file mode 100644 index 0000000..67cdbd5 --- /dev/null +++ b/kmsg-export-flags.patch @@ -0,0 +1,20 @@ +--- + kernel/printk.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/kernel/printk.c ++++ b/kernel/printk.c +@@ -462,8 +462,11 @@ static ssize_t devkmsg_read(struct file + msg = log_from_idx(user->idx); + ts_usec = msg->ts_nsec; + do_div(ts_usec, 1000); +- len = sprintf(user->buf, "%u,%llu,%llu;", +- (msg->facility << 3) | msg->level, user->seq, ts_usec); ++ len = sprintf(user->buf, "%u,%llu,%llu,%s%s%s;", ++ (msg->facility << 3) | msg->level, user->seq, ts_usec, ++ msg->flags & LOG_PREFIX ? "p" : "", ++ msg->flags & LOG_NEWLINE ? "n" : "", ++ msg->flags & LOG_CONT ? "c" : ""); + + /* escape non-printable characters */ + for (i = 0; i < msg->text_len; i++) { diff --git a/kmsg-merge-cont.patch b/kmsg-merge-cont.patch deleted file mode 100644 index ba60b0e..0000000 --- a/kmsg-merge-cont.patch +++ /dev/null @@ -1,412 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg: merge continuation records while printing - -In (the unlikely) case our continuation merge buffer is busy, we unfortunately -can not merge further continuation printk()s into a single record and have to -store them separately, which leads to split-up output of these lines when they -are printed. - -Add some flags about newlines and prefix existence to these records and try to -reconstruct the full line again, when the separated records are printed. - -Reported-By: Michael Neuling <mikey@neuling.org> -Tested-By: Michael Neuling <mikey@neuling.org> -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - kernel/printk.c | 120 ++++++++++++++++++++++++++++++++++++-------------------- - 1 file changed, 78 insertions(+), 42 deletions(-) - ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -194,8 +194,10 @@ static int console_may_schedule; - */ - - enum log_flags { -- LOG_DEFAULT = 0, -- LOG_NOCONS = 1, /* already flushed, do not print to console */ -+ LOG_NOCONS = 1, /* already flushed, do not print to console */ -+ LOG_NEWLINE = 2, /* text ended with a newline */ -+ LOG_PREFIX = 4, /* text started with a prefix */ -+ LOG_CONT = 8, /* text is a fragment of a continuation line */ - }; - - struct log { -@@ -217,6 +219,7 @@ static DEFINE_RAW_SPINLOCK(logbuf_lock); - /* the next printk record to read by syslog(READ) or /proc/kmsg */ - static u64 syslog_seq; - static u32 syslog_idx; -+static enum log_flags syslog_prev; - static size_t syslog_partial; - - /* index and sequence number of the first record stored in the buffer */ -@@ -839,13 +842,26 @@ static size_t print_prefix(const struct - return len; - } - --static size_t msg_print_text(const struct log *msg, bool syslog, -- char *buf, size_t size) -+static size_t msg_print_text(const struct log *msg, enum log_flags prev, -+ bool syslog, char *buf, size_t size) - { - const char *text = log_text(msg); - size_t text_size = msg->text_len; -+ bool prefix = true; -+ bool newline = true; - size_t len = 0; - -+ if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)) -+ prefix = false; -+ -+ if (msg->flags & LOG_CONT) { -+ if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE)) -+ prefix = false; -+ -+ if (!(msg->flags & LOG_NEWLINE)) -+ newline = false; -+ } -+ - do { - const char *next = memchr(text, '\n', text_size); - size_t text_len; -@@ -863,16 +879,22 @@ static size_t msg_print_text(const struc - text_len + 1>= size - len) - break; - -- len += print_prefix(msg, syslog, buf + len); -+ if (prefix) -+ len += print_prefix(msg, syslog, buf + len); - memcpy(buf + len, text, text_len); - len += text_len; -- buf[len++] = '\n'; -+ if (next || newline) -+ buf[len++] = '\n'; - } else { - /* SYSLOG_ACTION_* buffer size only calculation */ -- len += print_prefix(msg, syslog, NULL); -- len += text_len + 1; -+ if (prefix) -+ len += print_prefix(msg, syslog, NULL); -+ len += text_len; -+ if (next || newline) -+ len++; - } - -+ prefix = true; - text = next; - } while (text); - -@@ -898,6 +920,7 @@ static int syslog_print(char __user *buf - /* messages are gone, move to first one */ - syslog_seq = log_first_seq; - syslog_idx = log_first_idx; -+ syslog_prev = 0; - syslog_partial = 0; - } - if (syslog_seq == log_next_seq) { -@@ -907,11 +930,12 @@ static int syslog_print(char __user *buf - - skip = syslog_partial; - msg = log_from_idx(syslog_idx); -- n = msg_print_text(msg, true, text, LOG_LINE_MAX); -+ n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX); - if (n - syslog_partial <= size) { - /* message fits into buffer, move forward */ - syslog_idx = log_next(syslog_idx); - syslog_seq++; -+ syslog_prev = msg->flags; - n -= syslog_partial; - syslog_partial = 0; - } else if (!len){ -@@ -954,6 +978,7 @@ static int syslog_print_all(char __user - u64 next_seq; - u64 seq; - u32 idx; -+ enum log_flags prev; - - if (clear_seq < log_first_seq) { - /* messages are gone, move to first available one */ -@@ -967,10 +992,11 @@ static int syslog_print_all(char __user - */ - seq = clear_seq; - idx = clear_idx; -+ prev = 0; - while (seq < log_next_seq) { - struct log *msg = log_from_idx(idx); - -- len += msg_print_text(msg, true, NULL, 0); -+ len += msg_print_text(msg, prev, true, NULL, 0); - idx = log_next(idx); - seq++; - } -@@ -978,10 +1004,11 @@ static int syslog_print_all(char __user - /* move first record forward until length fits into the buffer */ - seq = clear_seq; - idx = clear_idx; -+ prev = 0; - while (len > size && seq < log_next_seq) { - struct log *msg = log_from_idx(idx); - -- len -= msg_print_text(msg, true, NULL, 0); -+ len -= msg_print_text(msg, prev, true, NULL, 0); - idx = log_next(idx); - seq++; - } -@@ -990,17 +1017,19 @@ static int syslog_print_all(char __user - next_seq = log_next_seq; - - len = 0; -+ prev = 0; - while (len >= 0 && seq < next_seq) { - struct log *msg = log_from_idx(idx); - int textlen; - -- textlen = msg_print_text(msg, true, text, LOG_LINE_MAX); -+ textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX); - if (textlen < 0) { - len = textlen; - break; - } - idx = log_next(idx); - seq++; -+ prev = msg->flags; - - raw_spin_unlock_irq(&logbuf_lock); - if (copy_to_user(buf + len, text, textlen)) -@@ -1013,6 +1042,7 @@ static int syslog_print_all(char __user - /* messages are gone, move to next one */ - seq = log_first_seq; - idx = log_first_idx; -+ prev = 0; - } - } - } -@@ -1117,6 +1147,7 @@ int do_syslog(int type, char __user *buf - /* messages are gone, move to first one */ - syslog_seq = log_first_seq; - syslog_idx = log_first_idx; -+ syslog_prev = 0; - syslog_partial = 0; - } - if (from_file) { -@@ -1127,18 +1158,18 @@ int do_syslog(int type, char __user *buf - */ - error = log_next_idx - syslog_idx; - } else { -- u64 seq; -- u32 idx; -+ u64 seq = syslog_seq; -+ u32 idx = syslog_idx; -+ enum log_flags prev = syslog_prev; - - error = 0; -- seq = syslog_seq; -- idx = syslog_idx; - while (seq < log_next_seq) { - struct log *msg = log_from_idx(idx); - -- error += msg_print_text(msg, true, NULL, 0); -+ error += msg_print_text(msg, prev, true, NULL, 0); - idx = log_next(idx); - seq++; -+ prev = msg->flags; - } - error -= syslog_partial; - } -@@ -1408,10 +1439,9 @@ asmlinkage int vprintk_emit(int facility - static char textbuf[LOG_LINE_MAX]; - char *text = textbuf; - size_t text_len; -+ enum log_flags lflags = 0; - unsigned long flags; - int this_cpu; -- bool newline = false; -- bool prefix = false; - int printed_len = 0; - - boot_delay_msec(); -@@ -1450,7 +1480,7 @@ asmlinkage int vprintk_emit(int facility - recursion_bug = 0; - printed_len += strlen(recursion_msg); - /* emit KERN_CRIT message */ -- log_store(0, 2, LOG_DEFAULT, 0, -+ log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, - NULL, 0, recursion_msg, printed_len); - } - -@@ -1463,7 +1493,7 @@ asmlinkage int vprintk_emit(int facility - /* mark and strip a trailing newline */ - if (text_len && text[text_len-1] == '\n') { - text_len--; -- newline = true; -+ lflags |= LOG_NEWLINE; - } - - /* strip syslog prefix and extract log level or control flags */ -@@ -1473,7 +1503,7 @@ asmlinkage int vprintk_emit(int facility - if (level == -1) - level = text[1] - '0'; - case 'd': /* KERN_DEFAULT */ -- prefix = true; -+ lflags |= LOG_PREFIX; - case 'c': /* KERN_CONT */ - text += 3; - text_len -= 3; -@@ -1483,22 +1513,20 @@ asmlinkage int vprintk_emit(int facility - if (level == -1) - level = default_message_loglevel; - -- if (dict) { -- prefix = true; -- newline = true; -- } -+ if (dict) -+ lflags |= LOG_PREFIX|LOG_NEWLINE; - -- if (!newline) { -+ if (!(lflags & LOG_NEWLINE)) { - /* - * Flush the conflicting buffer. An earlier newline was missing, - * or another task also prints continuation lines. - */ -- if (cont.len && (prefix || cont.owner != current)) -+ if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) - cont_flush(); - - /* buffer line if possible, otherwise store it right away */ - if (!cont_add(facility, level, text, text_len)) -- log_store(facility, level, LOG_DEFAULT, 0, -+ log_store(facility, level, lflags | LOG_CONT, 0, - dict, dictlen, text, text_len); - } else { - bool stored = false; -@@ -1510,13 +1538,13 @@ asmlinkage int vprintk_emit(int facility - * flush it out and store this line separately. - */ - if (cont.len && cont.owner == current) { -- if (!prefix) -+ if (!(lflags & LOG_PREFIX)) - stored = cont_add(facility, level, text, text_len); - cont_flush(); - } - - if (!stored) -- log_store(facility, level, LOG_DEFAULT, 0, -+ log_store(facility, level, lflags, 0, - dict, dictlen, text, text_len); - } - printed_len += text_len; -@@ -1615,8 +1643,8 @@ static struct cont { - static struct log *log_from_idx(u32 idx) { return NULL; } - static u32 log_next(u32 idx) { return 0; } - static void call_console_drivers(int level, const char *text, size_t len) {} --static size_t msg_print_text(const struct log *msg, bool syslog, -- char *buf, size_t size) { return 0; } -+static size_t msg_print_text(const struct log *msg, enum log_flags prev, -+ bool syslog, char *buf, size_t size) { return 0; } - static size_t cont_print_text(char *text, size_t size) { return 0; } - - #endif /* CONFIG_PRINTK */ -@@ -1892,6 +1920,7 @@ void wake_up_klogd(void) - /* the next printk record to write to the console */ - static u64 console_seq; - static u32 console_idx; -+static enum log_flags console_prev; - - /** - * console_unlock - unlock the console system -@@ -1952,6 +1981,7 @@ again: - /* messages are gone, move to first one */ - console_seq = log_first_seq; - console_idx = log_first_idx; -+ console_prev = 0; - } - skip: - if (console_seq == log_next_seq) -@@ -1975,10 +2005,11 @@ skip: - } - - level = msg->level; -- len = msg_print_text(msg, false, text, sizeof(text)); -- -+ len = msg_print_text(msg, console_prev, false, -+ text, sizeof(text)); - console_idx = log_next(console_idx); - console_seq++; -+ console_prev = msg->flags; - raw_spin_unlock(&logbuf_lock); - - stop_critical_timings(); /* don't trace print latency */ -@@ -2241,6 +2272,7 @@ void register_console(struct console *ne - raw_spin_lock_irqsave(&logbuf_lock, flags); - console_seq = syslog_seq; - console_idx = syslog_idx; -+ console_prev = syslog_prev; - raw_spin_unlock_irqrestore(&logbuf_lock, flags); - /* - * We're about to replay the log buffer. Only do this to the -@@ -2534,8 +2566,7 @@ bool kmsg_dump_get_line(struct kmsg_dump - } - - msg = log_from_idx(dumper->cur_idx); -- l = msg_print_text(msg, syslog, -- line, size); -+ l = msg_print_text(msg, 0, syslog, line, size); - - dumper->cur_idx = log_next(dumper->cur_idx); - dumper->cur_seq++; -@@ -2575,6 +2606,7 @@ bool kmsg_dump_get_buffer(struct kmsg_du - u32 idx; - u64 next_seq; - u32 next_idx; -+ enum log_flags prev; - size_t l = 0; - bool ret = false; - -@@ -2597,23 +2629,27 @@ bool kmsg_dump_get_buffer(struct kmsg_du - /* calculate length of entire buffer */ - seq = dumper->cur_seq; - idx = dumper->cur_idx; -+ prev = 0; - while (seq < dumper->next_seq) { - struct log *msg = log_from_idx(idx); - -- l += msg_print_text(msg, true, NULL, 0); -+ l += msg_print_text(msg, prev, true, NULL, 0); - idx = log_next(idx); - seq++; -+ prev = msg->flags; - } - - /* move first record forward until length fits into the buffer */ - seq = dumper->cur_seq; - idx = dumper->cur_idx; -+ prev = 0; - while (l > size && seq < dumper->next_seq) { - struct log *msg = log_from_idx(idx); - -- l -= msg_print_text(msg, true, NULL, 0); -+ l -= msg_print_text(msg, prev, true, NULL, 0); - idx = log_next(idx); - seq++; -+ prev = msg->flags; - } - - /* last message in next interation */ -@@ -2621,14 +2657,14 @@ bool kmsg_dump_get_buffer(struct kmsg_du - next_idx = idx; - - l = 0; -+ prev = 0; - while (seq < dumper->next_seq) { - struct log *msg = log_from_idx(idx); - -- l += msg_print_text(msg, syslog, -- buf + l, size - l); -- -+ l += msg_print_text(msg, prev, syslog, buf + l, size - l); - idx = log_next(idx); - seq++; -+ prev = msg->flags; - } - - dumper->next_seq = next_seq; diff --git a/kmsg-syslog-1-byte-read.patch b/kmsg-syslog-1-byte-read.patch deleted file mode 100644 index 73c4cef..0000000 --- a/kmsg-syslog-1-byte-read.patch +++ /dev/null @@ -1,101 +0,0 @@ -From: Kay Sievers <kay@vrfy.org> -Subject: kmsg: /proc/kmsg - support reading of partial log records - -Restore support for partial reads of any size on /proc/kmsg, in case the -supplied read buffer is smaller than the record size. - -Some people seem to think is is ia good idea to run: - $ dd if=/proc/kmsg bs=1 of=... -as a klog bridge. - -Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=44211 -Reported-by: Jukka Ollila <jiiksteri@gmail.com> -Signed-off-by: Kay Sievers <kay@vrfy.org> ---- - kernel/printk.c | 28 ++++++++++++++++++++-------- - 1 file changed, 20 insertions(+), 8 deletions(-) - ---- a/kernel/printk.c -+++ b/kernel/printk.c -@@ -217,6 +217,7 @@ static DEFINE_RAW_SPINLOCK(logbuf_lock); - /* the next printk record to read by syslog(READ) or /proc/kmsg */ - static u64 syslog_seq; - static u32 syslog_idx; -+static size_t syslog_partial; - - /* index and sequence number of the first record stored in the buffer */ - static u64 log_first_seq; -@@ -890,22 +891,33 @@ static int syslog_print(char __user *buf - - while (size > 0) { - size_t n; -+ size_t skip; - - raw_spin_lock_irq(&logbuf_lock); - if (syslog_seq < log_first_seq) { - /* messages are gone, move to first one */ - syslog_seq = log_first_seq; - syslog_idx = log_first_idx; -+ syslog_partial = 0; - } - if (syslog_seq == log_next_seq) { - raw_spin_unlock_irq(&logbuf_lock); - break; - } -+ -+ skip = syslog_partial; - msg = log_from_idx(syslog_idx); - n = msg_print_text(msg, true, text, LOG_LINE_MAX); -- if (n <= size) { -+ if (n - syslog_partial <= size) { -+ /* message fits into buffer, move forward */ - syslog_idx = log_next(syslog_idx); - syslog_seq++; -+ n -= syslog_partial; -+ syslog_partial = 0; -+ } else if (!len){ -+ /* partial read(), remember position */ -+ n = size; -+ syslog_partial += n; - } else - n = 0; - raw_spin_unlock_irq(&logbuf_lock); -@@ -913,17 +925,15 @@ static int syslog_print(char __user *buf - if (!n) - break; - -- len += n; -- size -= n; -- buf += n; -- n = copy_to_user(buf - n, text, n); -- -- if (n) { -- len -= n; -+ if (copy_to_user(buf, text + skip, n)) { - if (!len) - len = -EFAULT; - break; - } -+ -+ len += n; -+ size -= n; -+ buf += n; - } - - kfree(text); -@@ -1107,6 +1117,7 @@ int do_syslog(int type, char __user *buf - /* messages are gone, move to first one */ - syslog_seq = log_first_seq; - syslog_idx = log_first_idx; -+ syslog_partial = 0; - } - if (from_file) { - /* -@@ -1129,6 +1140,7 @@ int do_syslog(int type, char __user *buf - idx = log_next(idx); - seq++; - } -+ error -= syslog_partial; - } - raw_spin_unlock_irq(&logbuf_lock); - break; @@ -1,5 +1,2 @@ #test-modules.patch -#kmsg-test-console-blocked.patch -kmsg-syslog-1-byte-read.patch -kmsg-merge-cont.patch - +kmsg-export-flags.patch |