syslogd: add option to log to Linux kernel printk buffer
Why invent our own shared memory circular buffer when the kernel has a perfectly fine one already? This can be used as a smaller/simpler alternative to the syslogd IPC support (as IPC shmem/klogd/logread aren't needed), while also allowing centralised logging of everything (kernel messages, userspace bootup and syslog) when used together with ttyprintk. Notice that kernel 3.5+ is needed to store syslog facility in printk buffer, otherwise only the priority is stored. bloat-o-meter compared to IPC+klogd+logread: function old new delta get_linux_version_code - 84 +84 lbb_prepare 25 90 +65 applet_nameofs 6 - -6 static.stdout@@GLIBC_2 8 - -8 applet_names 23 9 -14 bb_msg_standard_output 16 - -16 init_sem 18 - -18 xatoull_range 19 - -19 overlapping_strcpy 21 - -21 init_data 56 32 -24 applet_main 24 - -24 main 124 99 -25 full_write2_str 26 - -26 error_exit 26 - -26 bb_basename 30 - -30 sem_up 32 - -32 interrupted 35 - -35 fflush_stdout_and_exit 38 - -38 bb_banner 46 - -46 find_applet_by_name 59 - -59 bb_signals_recursive_norestart 90 - -90 run_applet_no_and_exit 104 - -104 timestamp_and_log 651 523 -128 syslogd_main 798 581 -217 xstrtoull_range_sfx 267 - -267 run_applet_and_exit 432 - -432 klogd_main 490 - -490 logread_main 508 - -508 .rodata 1870 937 -933 bb_common_bufsiz1 8193 - -8193 ------------------------------------------------------------------------------ (add/remove: 2/26 grow/shrink: 1/6 up/down: 149/-11829) Total: -11680 bytes Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
This commit is contained in:
parent
d189b598b4
commit
cd776cf967
@ -113,6 +113,19 @@ config FEATURE_LOGREAD_REDUCED_LOCKING
|
||||
from circular buffer, minimizing semaphore
|
||||
contention at some minor memory expense.
|
||||
|
||||
config FEATURE_KMSG_SYSLOG
|
||||
bool "Linux kernel printk buffer support"
|
||||
default y
|
||||
depends on SYSLOGD
|
||||
select PLATFORM_LINUX
|
||||
help
|
||||
When you enable this feature, the syslogd utility will
|
||||
write system log message to the Linux kernel's printk buffer.
|
||||
This can be used as a smaller alternative to the syslogd IPC
|
||||
support, as klogd and logread aren't needed.
|
||||
|
||||
NOTICE: Syslog facilities in log entries needs kernel 3.5+.
|
||||
|
||||
config KLOGD
|
||||
bool "klogd"
|
||||
default y
|
||||
@ -123,6 +136,9 @@ config KLOGD
|
||||
you wish to record the messages produced by the kernel,
|
||||
you should enable this option.
|
||||
|
||||
comment "klogd should not be used together with syslog to kernel printk buffer"
|
||||
depends on KLOGD && FEATURE_KMSG_SYSLOG
|
||||
|
||||
config FEATURE_KLOGD_KLOGCTL
|
||||
bool "Use the klogctl() interface"
|
||||
default y
|
||||
|
@ -43,6 +43,9 @@
|
||||
//usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)"
|
||||
//usage: )
|
||||
/* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */
|
||||
//usage: IF_FEATURE_KMSG_SYSLOG(
|
||||
//usage: "\n -K Log to kernel printk buffer (use dmesg to read it)"
|
||||
//usage: )
|
||||
//usage:
|
||||
//usage:#define syslogd_example_usage
|
||||
//usage: "$ syslogd -R masterlog:514\n"
|
||||
@ -140,6 +143,10 @@ IF_FEATURE_IPC_SYSLOG( \
|
||||
) \
|
||||
IF_FEATURE_SYSLOGD_CFG( \
|
||||
logRule_t *log_rules; \
|
||||
) \
|
||||
IF_FEATURE_KMSG_SYSLOG( \
|
||||
int kmsgfd; \
|
||||
int primask; \
|
||||
)
|
||||
|
||||
struct init_globals {
|
||||
@ -212,6 +219,7 @@ enum {
|
||||
IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
|
||||
IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D
|
||||
IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f
|
||||
IF_FEATURE_KMSG_SYSLOG( OPTBIT_kmsg ,) // -K
|
||||
|
||||
OPT_mark = 1 << OPTBIT_mark ,
|
||||
OPT_nofork = 1 << OPTBIT_nofork ,
|
||||
@ -225,6 +233,8 @@ enum {
|
||||
OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
|
||||
OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0,
|
||||
OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0,
|
||||
OPT_kmsg = IF_FEATURE_KMSG_SYSLOG( (1 << OPTBIT_kmsg )) + 0,
|
||||
|
||||
};
|
||||
#define OPTION_STR "m:nO:l:S" \
|
||||
IF_FEATURE_ROTATE_LOGFILE("s:" ) \
|
||||
@ -233,7 +243,8 @@ enum {
|
||||
IF_FEATURE_REMOTE_LOG( "L" ) \
|
||||
IF_FEATURE_IPC_SYSLOG( "C::") \
|
||||
IF_FEATURE_SYSLOGD_DUP( "D" ) \
|
||||
IF_FEATURE_SYSLOGD_CFG( "f:" )
|
||||
IF_FEATURE_SYSLOGD_CFG( "f:" ) \
|
||||
IF_FEATURE_KMSG_SYSLOG( "K" )
|
||||
#define OPTION_DECL *opt_m, *opt_l \
|
||||
IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \
|
||||
IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \
|
||||
@ -523,6 +534,44 @@ void ipcsyslog_init(void);
|
||||
void log_to_shmem(const char *msg);
|
||||
#endif /* FEATURE_IPC_SYSLOG */
|
||||
|
||||
#if ENABLE_FEATURE_KMSG_SYSLOG
|
||||
static void kmsg_init(void)
|
||||
{
|
||||
G.kmsgfd = xopen("/dev/kmsg", O_WRONLY);
|
||||
|
||||
/*
|
||||
* kernel < 3.5 expects single char printk KERN_* priority prefix,
|
||||
* from 3.5 onwards the full syslog facility/priority format is supported
|
||||
*/
|
||||
if (get_linux_version_code() < KERNEL_VERSION(3,5,0))
|
||||
G.primask = LOG_PRIMASK;
|
||||
else
|
||||
G.primask = -1;
|
||||
}
|
||||
|
||||
static void kmsg_cleanup(void)
|
||||
{
|
||||
if (ENABLE_FEATURE_CLEAN_UP)
|
||||
close(G.kmsgfd);
|
||||
}
|
||||
|
||||
/* Write message to /dev/kmsg */
|
||||
static void log_to_kmsg(int pri, const char *msg)
|
||||
{
|
||||
/*
|
||||
* kernel < 3.5 expects single char printk KERN_* priority prefix,
|
||||
* from 3.5 onwards the full syslog facility/priority format is supported
|
||||
*/
|
||||
pri &= G.primask;
|
||||
|
||||
write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg));
|
||||
}
|
||||
#else
|
||||
void kmsg_init(void);
|
||||
void kmsg_cleanup(void);
|
||||
void log_to_kmsg(int pri, const char *msg);
|
||||
#endif /* FEATURE_KMSG_SYSLOG */
|
||||
|
||||
/* Print a message to the log file. */
|
||||
static void log_locally(time_t now, char *msg, logFile_t *log_file)
|
||||
{
|
||||
@ -657,6 +706,11 @@ static void timestamp_and_log(int pri, char *msg, int len)
|
||||
}
|
||||
timestamp[15] = '\0';
|
||||
|
||||
if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg)) {
|
||||
log_to_kmsg(pri, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (option_mask32 & OPT_small)
|
||||
sprintf(G.printbuf, "%s %s\n", timestamp, msg);
|
||||
else {
|
||||
@ -831,6 +885,9 @@ static void do_syslogd(void)
|
||||
ipcsyslog_init();
|
||||
}
|
||||
|
||||
if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg))
|
||||
kmsg_init();
|
||||
|
||||
timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER);
|
||||
|
||||
while (!bb_got_signal) {
|
||||
@ -919,6 +976,8 @@ static void do_syslogd(void)
|
||||
remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid");
|
||||
if (ENABLE_FEATURE_IPC_SYSLOG)
|
||||
ipcsyslog_cleanup();
|
||||
if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg))
|
||||
kmsg_cleanup();
|
||||
kill_myself_with_sig(bb_got_signal);
|
||||
#undef recvbuf
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user