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:
Peter Korsgaard
2013-01-06 00:07:19 +01:00
committed by Mike Frysinger
parent d189b598b4
commit cd776cf967
2 changed files with 76 additions and 1 deletions

View File

@@ -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
}