forked from Minki/linux
printk: add interfaces for external access to the log buffer
Add two new functions for reading the kernel log buffer. The intention is for them to be used by recovery/dump/debug code so the kernel log can be easily retrieved/parsed in a crash scenario, but they are generic enough for other people to dream up other fun uses. [akpm@linux-foundation.org: buncha fixes] Signed-off-by: Mike Frysinger <vapier@gentoo.org> Cc: Robin Getz <rgetz@blackfin.uclinux.org> Cc: Greg Ungerer <gerg@snapgear.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Paul Mundt <lethal@linux-sh.org> Acked-by: Tim Bird <tim.bird@am.sony.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
d823e3e754
commit
0b15d04af3
|
@ -172,6 +172,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
|
||||||
__attribute__ ((format (printf, 1, 0)));
|
__attribute__ ((format (printf, 1, 0)));
|
||||||
asmlinkage int printk(const char * fmt, ...)
|
asmlinkage int printk(const char * fmt, ...)
|
||||||
__attribute__ ((format (printf, 1, 2))) __cold;
|
__attribute__ ((format (printf, 1, 2))) __cold;
|
||||||
|
extern int log_buf_get_len(void);
|
||||||
|
extern int log_buf_read(int idx);
|
||||||
|
extern int log_buf_copy(char *dest, int idx, int len);
|
||||||
#else
|
#else
|
||||||
static inline int vprintk(const char *s, va_list args)
|
static inline int vprintk(const char *s, va_list args)
|
||||||
__attribute__ ((format (printf, 1, 0)));
|
__attribute__ ((format (printf, 1, 0)));
|
||||||
|
@ -179,6 +182,9 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
|
||||||
static inline int printk(const char *s, ...)
|
static inline int printk(const char *s, ...)
|
||||||
__attribute__ ((format (printf, 1, 2)));
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
static inline int __cold printk(const char *s, ...) { return 0; }
|
static inline int __cold printk(const char *s, ...) { return 0; }
|
||||||
|
static inline int log_buf_get_len(void) { return 0; }
|
||||||
|
static inline int log_buf_read(int idx) { return 0; }
|
||||||
|
static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned long int_sqrt(unsigned long);
|
unsigned long int_sqrt(unsigned long);
|
||||||
|
|
|
@ -219,6 +219,58 @@ static inline void boot_delay_msec(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the number of unread characters in the log buffer.
|
||||||
|
*/
|
||||||
|
int log_buf_get_len(void)
|
||||||
|
{
|
||||||
|
return logged_chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy a range of characters from the log buffer.
|
||||||
|
*/
|
||||||
|
int log_buf_copy(char *dest, int idx, int len)
|
||||||
|
{
|
||||||
|
int ret, max;
|
||||||
|
bool took_lock = false;
|
||||||
|
|
||||||
|
if (!oops_in_progress) {
|
||||||
|
spin_lock_irq(&logbuf_lock);
|
||||||
|
took_lock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
max = log_buf_get_len();
|
||||||
|
if (idx < 0 || idx >= max) {
|
||||||
|
ret = -1;
|
||||||
|
} else {
|
||||||
|
if (len > max)
|
||||||
|
len = max;
|
||||||
|
ret = len;
|
||||||
|
idx += (log_end - max);
|
||||||
|
while (len-- > 0)
|
||||||
|
dest[len] = LOG_BUF(idx + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (took_lock)
|
||||||
|
spin_unlock_irq(&logbuf_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a single character from the log buffer.
|
||||||
|
*/
|
||||||
|
int log_buf_read(int idx)
|
||||||
|
{
|
||||||
|
char ret;
|
||||||
|
|
||||||
|
if (log_buf_copy(&ret, idx, 1) == 1)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commands to do_syslog:
|
* Commands to do_syslog:
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user