diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2013-01-06 00:07:19 +0100 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2013-01-06 13:30:50 -0500 |
commit | cd776cf96735760311560495f3f0078ae72e98a0 (patch) | |
tree | 21aa8361ce965d00921923430f4773fcc060e6cd | |
parent | d189b598b449f3a258354133180e7b770c04526c (diff) | |
download | busybox-w32-cd776cf96735760311560495f3f0078ae72e98a0.tar.gz busybox-w32-cd776cf96735760311560495f3f0078ae72e98a0.tar.bz2 busybox-w32-cd776cf96735760311560495f3f0078ae72e98a0.zip |
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>
-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 b7a494eff..fcf993054 100644 --- a/sysklogd/Config.src +++ b/sysklogd/Config.src | |||
@@ -113,6 +113,19 @@ config FEATURE_LOGREAD_REDUCED_LOCKING | |||
113 | from circular buffer, minimizing semaphore | 113 | from circular buffer, minimizing semaphore |
114 | contention at some minor memory expense. | 114 | contention at some minor memory expense. |
115 | 115 | ||
116 | config FEATURE_KMSG_SYSLOG | ||
117 | bool "Linux kernel printk buffer support" | ||
118 | default y | ||
119 | depends on SYSLOGD | ||
120 | select PLATFORM_LINUX | ||
121 | help | ||
122 | When you enable this feature, the syslogd utility will | ||
123 | write system log message to the Linux kernel's printk buffer. | ||
124 | This can be used as a smaller alternative to the syslogd IPC | ||
125 | support, as klogd and logread aren't needed. | ||
126 | |||
127 | NOTICE: Syslog facilities in log entries needs kernel 3.5+. | ||
128 | |||
116 | config KLOGD | 129 | config KLOGD |
117 | bool "klogd" | 130 | bool "klogd" |
118 | default y | 131 | default y |
@@ -123,6 +136,9 @@ config KLOGD | |||
123 | you wish to record the messages produced by the kernel, | 136 | you wish to record the messages produced by the kernel, |
124 | you should enable this option. | 137 | you should enable this option. |
125 | 138 | ||
139 | comment "klogd should not be used together with syslog to kernel printk buffer" | ||
140 | depends on KLOGD && FEATURE_KMSG_SYSLOG | ||
141 | |||
126 | config FEATURE_KLOGD_KLOGCTL | 142 | config FEATURE_KLOGD_KLOGCTL |
127 | bool "Use the klogctl() interface" | 143 | bool "Use the klogctl() interface" |
128 | default y | 144 | default y |
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 5854bcd0f..ad54e22dd 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -43,6 +43,9 @@ | |||
43 | //usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" | 43 | //usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" |
44 | //usage: ) | 44 | //usage: ) |
45 | /* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ | 45 | /* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ |
46 | //usage: IF_FEATURE_KMSG_SYSLOG( | ||
47 | //usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" | ||
48 | //usage: ) | ||
46 | //usage: | 49 | //usage: |
47 | //usage:#define syslogd_example_usage | 50 | //usage:#define syslogd_example_usage |
48 | //usage: "$ syslogd -R masterlog:514\n" | 51 | //usage: "$ syslogd -R masterlog:514\n" |
@@ -140,6 +143,10 @@ IF_FEATURE_IPC_SYSLOG( \ | |||
140 | ) \ | 143 | ) \ |
141 | IF_FEATURE_SYSLOGD_CFG( \ | 144 | IF_FEATURE_SYSLOGD_CFG( \ |
142 | logRule_t *log_rules; \ | 145 | logRule_t *log_rules; \ |
146 | ) \ | ||
147 | IF_FEATURE_KMSG_SYSLOG( \ | ||
148 | int kmsgfd; \ | ||
149 | int primask; \ | ||
143 | ) | 150 | ) |
144 | 151 | ||
145 | struct init_globals { | 152 | struct init_globals { |
@@ -212,6 +219,7 @@ enum { | |||
212 | IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C | 219 | IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C |
213 | IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D | 220 | IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D |
214 | IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f | 221 | IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f |
222 | IF_FEATURE_KMSG_SYSLOG( OPTBIT_kmsg ,) // -K | ||
215 | 223 | ||
216 | OPT_mark = 1 << OPTBIT_mark , | 224 | OPT_mark = 1 << OPTBIT_mark , |
217 | OPT_nofork = 1 << OPTBIT_nofork , | 225 | OPT_nofork = 1 << OPTBIT_nofork , |
@@ -225,6 +233,8 @@ enum { | |||
225 | OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, | 233 | OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, |
226 | OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, | 234 | OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, |
227 | OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0, | 235 | OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0, |
236 | OPT_kmsg = IF_FEATURE_KMSG_SYSLOG( (1 << OPTBIT_kmsg )) + 0, | ||
237 | |||
228 | }; | 238 | }; |
229 | #define OPTION_STR "m:nO:l:S" \ | 239 | #define OPTION_STR "m:nO:l:S" \ |
230 | IF_FEATURE_ROTATE_LOGFILE("s:" ) \ | 240 | IF_FEATURE_ROTATE_LOGFILE("s:" ) \ |
@@ -233,7 +243,8 @@ enum { | |||
233 | IF_FEATURE_REMOTE_LOG( "L" ) \ | 243 | IF_FEATURE_REMOTE_LOG( "L" ) \ |
234 | IF_FEATURE_IPC_SYSLOG( "C::") \ | 244 | IF_FEATURE_IPC_SYSLOG( "C::") \ |
235 | IF_FEATURE_SYSLOGD_DUP( "D" ) \ | 245 | IF_FEATURE_SYSLOGD_DUP( "D" ) \ |
236 | IF_FEATURE_SYSLOGD_CFG( "f:" ) | 246 | IF_FEATURE_SYSLOGD_CFG( "f:" ) \ |
247 | IF_FEATURE_KMSG_SYSLOG( "K" ) | ||
237 | #define OPTION_DECL *opt_m, *opt_l \ | 248 | #define OPTION_DECL *opt_m, *opt_l \ |
238 | IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ | 249 | IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ |
239 | IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ | 250 | IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ |
@@ -523,6 +534,44 @@ void ipcsyslog_init(void); | |||
523 | void log_to_shmem(const char *msg); | 534 | void log_to_shmem(const char *msg); |
524 | #endif /* FEATURE_IPC_SYSLOG */ | 535 | #endif /* FEATURE_IPC_SYSLOG */ |
525 | 536 | ||
537 | #if ENABLE_FEATURE_KMSG_SYSLOG | ||
538 | static void kmsg_init(void) | ||
539 | { | ||
540 | G.kmsgfd = xopen("/dev/kmsg", O_WRONLY); | ||
541 | |||
542 | /* | ||
543 | * kernel < 3.5 expects single char printk KERN_* priority prefix, | ||
544 | * from 3.5 onwards the full syslog facility/priority format is supported | ||
545 | */ | ||
546 | if (get_linux_version_code() < KERNEL_VERSION(3,5,0)) | ||
547 | G.primask = LOG_PRIMASK; | ||
548 | else | ||
549 | G.primask = -1; | ||
550 | } | ||
551 | |||
552 | static void kmsg_cleanup(void) | ||
553 | { | ||
554 | if (ENABLE_FEATURE_CLEAN_UP) | ||
555 | close(G.kmsgfd); | ||
556 | } | ||
557 | |||
558 | /* Write message to /dev/kmsg */ | ||
559 | static void log_to_kmsg(int pri, const char *msg) | ||
560 | { | ||
561 | /* | ||
562 | * kernel < 3.5 expects single char printk KERN_* priority prefix, | ||
563 | * from 3.5 onwards the full syslog facility/priority format is supported | ||
564 | */ | ||
565 | pri &= G.primask; | ||
566 | |||
567 | write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg)); | ||
568 | } | ||
569 | #else | ||
570 | void kmsg_init(void); | ||
571 | void kmsg_cleanup(void); | ||
572 | void log_to_kmsg(int pri, const char *msg); | ||
573 | #endif /* FEATURE_KMSG_SYSLOG */ | ||
574 | |||
526 | /* Print a message to the log file. */ | 575 | /* Print a message to the log file. */ |
527 | static void log_locally(time_t now, char *msg, logFile_t *log_file) | 576 | static void log_locally(time_t now, char *msg, logFile_t *log_file) |
528 | { | 577 | { |
@@ -657,6 +706,11 @@ static void timestamp_and_log(int pri, char *msg, int len) | |||
657 | } | 706 | } |
658 | timestamp[15] = '\0'; | 707 | timestamp[15] = '\0'; |
659 | 708 | ||
709 | if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg)) { | ||
710 | log_to_kmsg(pri, msg); | ||
711 | return; | ||
712 | } | ||
713 | |||
660 | if (option_mask32 & OPT_small) | 714 | if (option_mask32 & OPT_small) |
661 | sprintf(G.printbuf, "%s %s\n", timestamp, msg); | 715 | sprintf(G.printbuf, "%s %s\n", timestamp, msg); |
662 | else { | 716 | else { |
@@ -831,6 +885,9 @@ static void do_syslogd(void) | |||
831 | ipcsyslog_init(); | 885 | ipcsyslog_init(); |
832 | } | 886 | } |
833 | 887 | ||
888 | if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg)) | ||
889 | kmsg_init(); | ||
890 | |||
834 | timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); | 891 | timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); |
835 | 892 | ||
836 | while (!bb_got_signal) { | 893 | while (!bb_got_signal) { |
@@ -919,6 +976,8 @@ static void do_syslogd(void) | |||
919 | remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); | 976 | remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); |
920 | if (ENABLE_FEATURE_IPC_SYSLOG) | 977 | if (ENABLE_FEATURE_IPC_SYSLOG) |
921 | ipcsyslog_cleanup(); | 978 | ipcsyslog_cleanup(); |
979 | if (ENABLE_FEATURE_KMSG_SYSLOG && (option_mask32 & OPT_kmsg)) | ||
980 | kmsg_cleanup(); | ||
922 | kill_myself_with_sig(bb_got_signal); | 981 | kill_myself_with_sig(bb_got_signal); |
923 | #undef recvbuf | 982 | #undef recvbuf |
924 | } | 983 | } |