aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Korsgaard <jacmet@sunsite.dk>2013-01-06 00:07:19 +0100
committerMike Frysinger <vapier@gentoo.org>2013-01-06 13:30:50 -0500
commitcd776cf96735760311560495f3f0078ae72e98a0 (patch)
tree21aa8361ce965d00921923430f4773fcc060e6cd
parentd189b598b449f3a258354133180e7b770c04526c (diff)
downloadbusybox-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.src16
-rw-r--r--sysklogd/syslogd.c61
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
116config 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
116config KLOGD 129config 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
139comment "klogd should not be used together with syslog to kernel printk buffer"
140 depends on KLOGD && FEATURE_KMSG_SYSLOG
141
126config FEATURE_KLOGD_KLOGCTL 142config 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) \
141IF_FEATURE_SYSLOGD_CFG( \ 144IF_FEATURE_SYSLOGD_CFG( \
142 logRule_t *log_rules; \ 145 logRule_t *log_rules; \
146) \
147IF_FEATURE_KMSG_SYSLOG( \
148 int kmsgfd; \
149 int primask; \
143) 150)
144 151
145struct init_globals { 152struct 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);
523void log_to_shmem(const char *msg); 534void log_to_shmem(const char *msg);
524#endif /* FEATURE_IPC_SYSLOG */ 535#endif /* FEATURE_IPC_SYSLOG */
525 536
537#if ENABLE_FEATURE_KMSG_SYSLOG
538static 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
552static void kmsg_cleanup(void)
553{
554 if (ENABLE_FEATURE_CLEAN_UP)
555 close(G.kmsgfd);
556}
557
558/* Write message to /dev/kmsg */
559static 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
570void kmsg_init(void);
571void kmsg_cleanup(void);
572void 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. */
527static void log_locally(time_t now, char *msg, logFile_t *log_file) 576static 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}