initial import
[patches.git] / linux-log_buf_read.patch
1 Add two new functions for reading the kernel log buffer. Their intention
2 is to be used by recovery/dump/debug code so the kernel log can be easily
3 retrieved/parsed in a crash scenario, but they are generic enough for other
4 people to dream up other fun uses.
5
6 Signed-off-by: Mike Frysinger <vapier@gentoo.org>
7 ---
8 diff --git a/include/linux/kernel.h b/include/linux/kernel.h
9 index 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);
32 diff --git a/kernel/printk.c b/kernel/printk.c
33 index 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.