diff options
-rw-r--r-- | sysklogd/Config.src | 16 | ||||
-rw-r--r-- | sysklogd/syslogd.c | 61 |
2 files changed, 76 insertions, 1 deletions
diff --git a/sysklogd/Config.src b/sysklogd/Config.src index b7a494e..fcf9930 100644 --- a/sysklogd/Config.src +++ b/sysklogd/Config.src @@ -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 diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 5854bcd..ad54e22 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -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 } |