]> git.wh0rd.org - patches.git/blame - linux-log_buf_read.patch
initial import
[patches.git] / linux-log_buf_read.patch
CommitLineData
5e993f12 1Add two new functions for reading the kernel log buffer. Their intention
2is to be used by recovery/dump/debug code so the kernel log can be easily
3retrieved/parsed in a crash scenario, but they are generic enough for other
4people to dream up other fun uses.
5
6Signed-off-by: Mike Frysinger <vapier@gentoo.org>
7---
8diff --git a/include/linux/kernel.h b/include/linux/kernel.h
9index 4300bb4..8d5b6c7 100644
10--- a/include/linux/kernel.h
11+++ b/include/linux/kernel.h
12@@ -156,6 +156,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
13 __attribute__ ((format (printf, 1, 0)));
14 asmlinkage int printk(const char * fmt, ...)
15 __attribute__ ((format (printf, 1, 2))) __cold;
16+extern int log_buf_get_len(void);
17+extern int log_buf_read(int idx);
18+extern int log_buf_copy(char *dest, int idx, int len);
19 #else
20 static inline int vprintk(const char *s, va_list args)
21 __attribute__ ((format (printf, 1, 0)));
22@@ -163,6 +166,9 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
23 static inline int printk(const char *s, ...)
24 __attribute__ ((format (printf, 1, 2)));
25 static inline int __cold printk(const char *s, ...) { return 0; }
26+static inline int log_buf_get_len(void) { return 0; }
27+static inline int log_buf_read(int idx); { return 0; }
28+static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
29 #endif
30
31 unsigned long int_sqrt(unsigned long);
32diff --git a/kernel/printk.c b/kernel/printk.c
33index 051d27e..35b231a 100644
34--- a/kernel/printk.c
35+++ b/kernel/printk.c
36@@ -163,6 +163,55 @@ out:
37 __setup("log_buf_len=", log_buf_len_setup);
38
39 /*
40+ * Return the number of unread characters in the log buffer.
41+ */
42+int log_buf_get_len(void)
43+{
44+ return log_end - log_start;
45+}
46+
47+/*
48+ * Copy a range of characters from the log buffer.
49+ */
50+int log_buf_copy(char *dest, int idx, int len)
51+{
52+ int ret, max;
53+
54+ if (!oops_in_progress)
55+ spin_lock_irq(&logbuf_lock);
56+
57+ max = log_buf_get_len();
58+ if (idx < 0 || idx >= max)
59+ ret = -1;
60+ else {
61+ if (len > max)
62+ len = max;
63+ ret = len;
64+ while (len-- > 0) {
65+ *dest = LOG_BUF(idx++);
66+ ++dest;
67+ }
68+ }
69+
70+ if (!oops_in_progress)
71+ spin_unlock_irq(&logbuf_lock);
72+
73+ return ret;
74+}
75+
76+/*
77+ * Extract a single character from the log buffer.
78+ */
79+int log_buf_read(int idx)
80+{
81+ char ret;
82+ if (log_buf_copy(&ret, idx, 1) == 1)
83+ return ret;
84+ else
85+ return -1;
86+}
87+
88+/*
89 * Commands to do_syslog:
90 *
91 * 0 -- Close the log. Currently a NOP.