aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kernel.h6
-rw-r--r--kernel/printk.c52
2 files changed, 58 insertions, 0 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5fdbc814c2eb..c680e1e6e9a3 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -172,6 +172,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
172 __attribute__ ((format (printf, 1, 0))); 172 __attribute__ ((format (printf, 1, 0)));
173asmlinkage int printk(const char * fmt, ...) 173asmlinkage int printk(const char * fmt, ...)
174 __attribute__ ((format (printf, 1, 2))) __cold; 174 __attribute__ ((format (printf, 1, 2))) __cold;
175extern int log_buf_get_len(void);
176extern int log_buf_read(int idx);
177extern int log_buf_copy(char *dest, int idx, int len);
175#else 178#else
176static inline int vprintk(const char *s, va_list args) 179static inline int vprintk(const char *s, va_list args)
177 __attribute__ ((format (printf, 1, 0))); 180 __attribute__ ((format (printf, 1, 0)));
@@ -179,6 +182,9 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
179static inline int printk(const char *s, ...) 182static inline int printk(const char *s, ...)
180 __attribute__ ((format (printf, 1, 2))); 183 __attribute__ ((format (printf, 1, 2)));
181static inline int __cold printk(const char *s, ...) { return 0; } 184static inline int __cold printk(const char *s, ...) { return 0; }
185static inline int log_buf_get_len(void) { return 0; }
186static inline int log_buf_read(int idx) { return 0; }
187static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
182#endif 188#endif
183 189
184unsigned long int_sqrt(unsigned long); 190unsigned long int_sqrt(unsigned long);
diff --git a/kernel/printk.c b/kernel/printk.c
index b2b5c3a22a36..52493474f0ab 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -220,6 +220,58 @@ static inline void boot_delay_msec(void)
220#endif 220#endif
221 221
222/* 222/*
223 * Return the number of unread characters in the log buffer.
224 */
225int log_buf_get_len(void)
226{
227 return logged_chars;
228}
229
230/*
231 * Copy a range of characters from the log buffer.
232 */
233int log_buf_copy(char *dest, int idx, int len)
234{
235 int ret, max;
236 bool took_lock = false;
237
238 if (!oops_in_progress) {
239 spin_lock_irq(&logbuf_lock);
240 took_lock = true;
241 }
242
243 max = log_buf_get_len();
244 if (idx < 0 || idx >= max) {
245 ret = -1;
246 } else {
247 if (len > max)
248 len = max;
249 ret = len;
250 idx += (log_end - max);
251 while (len-- > 0)
252 dest[len] = LOG_BUF(idx + len);
253 }
254
255 if (took_lock)
256 spin_unlock_irq(&logbuf_lock);
257
258 return ret;
259}
260
261/*
262 * Extract a single character from the log buffer.
263 */
264int log_buf_read(int idx)
265{
266 char ret;
267
268 if (log_buf_copy(&ret, idx, 1) == 1)
269 return ret;
270 else
271 return -1;
272}
273
274/*
223 * Commands to do_syslog: 275 * Commands to do_syslog:
224 * 276 *
225 * 0 -- Close the log. Currently a NOP. 277 * 0 -- Close the log. Currently a NOP.