[PATCH 3/3] syslogd: add option to log to Linux kernel printk buffer
Peter Korsgaard
jacmet at sunsite.dk
Tue Dec 18 19:49:20 UTC 2012
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
applet_nameofs 8 4 -4
static.stdout@@GLIBC_2 8 - -8
applet_names 29 15 -14
bb_msg_standard_output 16 - -16
applet_main 32 16 -16
init_sem 18 - -18
xatoull_range 19 - -19
overlapping_strcpy 21 - -21
error_exit 26 - -26
sem_up 32 - -32
init_data 56 24 -32
interrupted 35 - -35
fflush_stdout_and_exit 38 - -38
bb_signals_recursive_norestart 90 - -90
timestamp_and_log 651 546 -105
syslogd_main 798 555 -243
xstrtoull_range_sfx 267 - -267
.rodata 1898 1577 -321
logread_main 508 - -508
klogd_main 525 - -525
bb_common_bufsiz1 8193 - -8193
------------------------------------------------------------------------------
(add/remove: 2/17 grow/shrink: 0/7 up/down: 84/-10531) Total: -10447 bytes
Signed-off-by: Peter Korsgaard <jacmet at sunsite.dk>
---
sysklogd/Config.src | 16 ++++++++++++++++
sysklogd/syslogd.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletion(-)
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 fc380d9..f1d4136 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,9 @@ IF_FEATURE_IPC_SYSLOG( \
) \
IF_FEATURE_SYSLOGD_CFG( \
logRule_t *log_rules; \
+) \
+IF_FEATURE_KMSG_SYSLOG( \
+ int kmsgfd; \
)
struct init_globals {
@@ -212,6 +218,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 +232,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 +242,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 +533,23 @@ void ipcsyslog_init(void);
void log_to_shmem(const char *msg);
#endif /* FEATURE_IPC_SYSLOG */
+#if ENABLE_FEATURE_KMSG_SYSLOG
+/* 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
+ */
+ if (get_linux_version_code() < KERNEL_VERSION(3,5,0))
+ pri &= LOG_PRIMASK;
+
+ write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg));
+}
+#else
+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 +684,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 +863,11 @@ static void do_syslogd(void)
ipcsyslog_init();
}
+#if ENABLE_FEATURE_KMSG_SYSLOG
+ if (option_mask32 & OPT_kmsg)
+ G.kmsgfd = xopen("/dev/kmsg", O_WRONLY);
+#endif
+
timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER);
while (!bb_got_signal) {
--
1.7.10.4
More information about the busybox
mailing list