summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-07-12 22:53:36 +0200
committerKay Sievers <kay@vrfy.org>2012-07-12 22:53:36 +0200
commit39ae2e4732dd7d9aa15d3fea3dccd3bbf3567379 (patch)
tree102ce1e5dab2c811a91bd434db61bbddd6129817
parent36a22a102108a94a3e3125cb6adb48baab47361b (diff)
downloadpatches-39ae2e4732dd7d9aa15d3fea3dccd3bbf3567379.tar.gz
add kmsg-fix-overlong-cont.patch
-rw-r--r--kmsg-fix-overlong-cont.patch129
-rw-r--r--pr_cat.patch117
-rw-r--r--series2
3 files changed, 248 insertions, 0 deletions
diff --git a/kmsg-fix-overlong-cont.patch b/kmsg-fix-overlong-cont.patch
new file mode 100644
index 0000000..a60f69e
--- /dev/null
+++ b/kmsg-fix-overlong-cont.patch
@@ -0,0 +1,129 @@
+---
+ kernel/printk.c | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -235,7 +235,8 @@ static u32 log_next_idx;
+ static u64 clear_seq;
+ static u32 clear_idx;
+
+-#define LOG_LINE_MAX 1024
++#define PREFIX_MAX 32
++#define LOG_LINE_MAX 1024 - PREFIX_MAX
+
+ /* record buffer */
+ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+@@ -876,7 +877,7 @@ static size_t msg_print_text(const struc
+
+ if (buf) {
+ if (print_prefix(msg, syslog, NULL) +
+- text_len + 1>= size - len)
++ text_len + 1 >= size - len)
+ break;
+
+ if (prefix)
+@@ -907,7 +908,7 @@ static int syslog_print(char __user *buf
+ struct log *msg;
+ int len = 0;
+
+- text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
++ text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ if (!text)
+ return -ENOMEM;
+
+@@ -930,7 +931,8 @@ static int syslog_print(char __user *buf
+
+ skip = syslog_partial;
+ msg = log_from_idx(syslog_idx);
+- n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
++ n = msg_print_text(msg, syslog_prev, true, text,
++ LOG_LINE_MAX + PREFIX_MAX);
+ if (n - syslog_partial <= size) {
+ /* message fits into buffer, move forward */
+ syslog_idx = log_next(syslog_idx);
+@@ -969,7 +971,7 @@ static int syslog_print_all(char __user
+ char *text;
+ int len = 0;
+
+- text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
++ text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
+ if (!text)
+ return -ENOMEM;
+
+@@ -1022,7 +1024,8 @@ static int syslog_print_all(char __user
+ struct log *msg = log_from_idx(idx);
+ int textlen;
+
+- textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
++ textlen = msg_print_text(msg, prev, true, text,
++ LOG_LINE_MAX + PREFIX_MAX);
+ if (textlen < 0) {
+ len = textlen;
+ break;
+@@ -1367,15 +1370,15 @@ static struct cont {
+ bool flushed:1; /* buffer sealed and committed */
+ } cont;
+
+-static void cont_flush(void)
++static void cont_flush(enum log_flags flags)
+ {
+ if (cont.flushed)
+ return;
+ if (cont.len == 0)
+ return;
+
+- log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
+- NULL, 0, cont.buf, cont.len);
++ log_store(cont.facility, cont.level, LOG_NOCONS | flags,
++ cont.ts_nsec, NULL, 0, cont.buf, cont.len);
+
+ cont.flushed = true;
+ }
+@@ -1386,7 +1389,8 @@ static bool cont_add(int facility, int l
+ return false;
+
+ if (cont.len + len > sizeof(cont.buf)) {
+- cont_flush();
++ /* the line gets too long, split it up in separate records */
++ cont_flush(LOG_CONT);
+ return false;
+ }
+
+@@ -1522,7 +1526,7 @@ asmlinkage int vprintk_emit(int facility
+ * or another task also prints continuation lines.
+ */
+ if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
+- cont_flush();
++ cont_flush(0);
+
+ /* buffer line if possible, otherwise store it right away */
+ if (!cont_add(facility, level, text, text_len))
+@@ -1540,7 +1544,7 @@ asmlinkage int vprintk_emit(int facility
+ if (cont.len && cont.owner == current) {
+ if (!(lflags & LOG_PREFIX))
+ stored = cont_add(facility, level, text, text_len);
+- cont_flush();
++ cont_flush(0);
+ }
+
+ if (!stored)
+@@ -1633,7 +1637,8 @@ EXPORT_SYMBOL(printk);
+
+ #else
+
+-#define LOG_LINE_MAX 0
++#define LOG_LINE_MAX 0
++#define PREFIX_MAX 0
+ static struct cont {
+ size_t len;
+ size_t cons;
+@@ -1938,7 +1943,7 @@ static enum log_flags console_prev;
+ */
+ void console_unlock(void)
+ {
+- static char text[LOG_LINE_MAX];
++ static char text[LOG_LINE_MAX + PREFIX_MAX];
+ static u64 seen_seq;
+ unsigned long flags;
+ bool wake_klogd = false;
diff --git a/pr_cat.patch b/pr_cat.patch
new file mode 100644
index 0000000..aea0193
--- /dev/null
+++ b/pr_cat.patch
@@ -0,0 +1,117 @@
+diff --git a/kernel/printk.c b/kernel/printk.c
+index 177fa49..0f4df08 100644
+--- a/kernel/printk.c
++++ b/kernel/printk.c
+@@ -48,6 +48,40 @@
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/printk.h>
+
++#define CATSTR_INIT(name) \
++ name##_len = 0
++
++#define CATSTR_DEFINE(name, max) \
++ char name[max]; \
++ size_t name##_len = 0; \
++ size_t name##_max = max
++
++#define pr_cat(name, fmt, ...) \
++ _pr_cat(name, &name##_len, name##_max, fmt, ##__VA_ARGS__)
++
++bool _pr_cat(char *s, size_t *len, size_t size, const char *fmt, ...)
++{
++ va_list args;
++ size_t r;
++
++ if (*len == size)
++ return false;
++
++ va_start(args, fmt);
++ r = vsnprintf(s + *len, size - *len, fmt, args);
++ va_end(args);
++
++ if (r + 1 >= size - *len) {
++ s[*len] = '\0';
++ *len = size;
++ return false;
++ }
++
++ *len += r;
++ s[*len] = '\0';
++ return true;
++}
++
+ /*
+ * Architectures can override it:
+ */
+@@ -587,6 +621,11 @@ static int devkmsg_open(struct inode *inode, struct file *file)
+ struct devkmsg_user *user;
+ int err;
+
++ console_lock();
++ print_modules();
++ print_modules();
++ console_unlock();
++
+ /* write-only does not need any file context */
+ if ((file->f_flags & O_ACCMODE) == O_WRONLY)
+ return 0;
+@@ -671,6 +710,59 @@ void __init setup_log_buf(int early)
+ unsigned long flags;
+ char *new_log_buf;
+ int free;
++ int i;
++
++ CATSTR_DEFINE(line, 64);
++ CATSTR_DEFINE(line2, 16);
++ CATSTR_DEFINE(line3, 12);
++
++ pr_cat(line, "1:");
++ pr_cat(line, "-%i ", 12);
++ pr_cat(line, "-%i ", 34);
++ pr_cat(line, "-%i ", 56);
++ pr_cat(line, "-%i ", 78);
++ pr_info("%s-%i\n", line, 90);
++
++ pr_cat(line2, "2:");
++ pr_cat(line2, "-%i ", 12);
++ pr_cat(line2, "-%i ", 34);
++ pr_cat(line2, "-%i ", 56);
++ pr_cat(line2, "-%i ", 78);
++ pr_info("%s-%i\n", line2, 90);
++
++ pr_cat(line3, "3:");
++ pr_cat(line3, "-%i ", 12);
++ pr_cat(line3, "-%i ", 34);
++ pr_cat(line3, "-%i ", 56);
++ pr_cat(line3, "-%i ", 78);
++ pr_info("%s-%i\n", line3, 90);
++
++ CATSTR_INIT(line3);
++ pr_cat(line3, "4:");
++ pr_cat(line3, "+%i ", 12);
++ pr_cat(line3, "+%i ", 34);
++ pr_cat(line3, "+%i ", 56);
++ pr_cat(line3, "+%i ", 78);
++ pr_info("%s-%i\n", line3, 90);
++
++ CATSTR_INIT(line3);
++ pr_cat(line3, "5:");
++ pr_cat(line3, "~%i ", 12);
++ pr_cat(line3, "~%i ", 34);
++ pr_cat(line3, "~%i ", 56);
++ pr_cat(line3, "~%i ", 78);
++ pr_info("%s-%i\n", line3, 90);
++
++ CATSTR_INIT(line);
++ pr_cat(line, "foo:");
++ for (i = 0; i < 50; i++) {
++ if (!pr_cat(line, " #%i", i)) {
++ pr_info("%s #%i\n", line, i);
++ CATSTR_INIT(line);
++ pr_cat(line, "foo+:");
++ }
++ }
++ pr_info("%s\n", line);
+
+ if (!new_log_buf_len)
+ return;
diff --git a/series b/series
index d6822ef..1683d3c 100644
--- a/series
+++ b/series
@@ -1,4 +1,6 @@
#test-modules.patch
#test-console-blocked.patch
+#pr_cat.patch
+kmsg-fix-overlong-cont.patch
kmsg-config-no-printk.patch
kmsg-export-flags.patch