--- ./sysklogd/syslogd.c~ 2006-03-07 22:45:12.000000000 +0100 +++ ./sysklogd/syslogd.c 2006-03-09 21:03:57.000000000 +0100 @@ -104,6 +104,11 @@ static int doListenUDP = FALSE; #endif +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG +static int console_level; +static int klog_fd; +static int doKernelLog = FALSE; +#endif /* Make loging output smaller. */ static bool small = false; @@ -616,6 +621,19 @@ } #endif +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG + if (doKernelLog) { + klogctl(8, NULL, console_level); + klog_fd = open("/proc/kmsg", O_RDONLY); + if (klog_fd < 0) { + bb_perror_msg_and_die("Cannot open /proc/kmsg"); + } + if (fcntl(klog_fd, F_SETFL, O_NONBLOCK) < 0) { + bb_perror_msg_and_die("Couldn't make /proc/kmsg non-blocking"); + } + } +#endif + #ifdef CONFIG_FEATURE_IPC_SYSLOG if (circular_logging == TRUE) { ipcsyslog_init(); @@ -642,6 +660,13 @@ nbfd = listen_udp_fd + 1; } #endif +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG + if (doKernelLog) { + FD_SET(klog_fd, &fds); + if (klog_fd >= nbfd) + nbfd = klog_fd + 1; + } +#endif if (select(nbfd, &fds, NULL, NULL, NULL) < 0) { if (errno == EINTR) { /* alarm may have happened. */ @@ -680,6 +705,20 @@ } } /* FD_ISSET() */ #endif /* SYSLOG_LISTEN_UDP */ +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG + if (doKernelLog && FD_ISSET(klog_fd, &fds)) { + int i; + + if ((i = read(klog_fd, tmpbuf + 8, TMP_BUF_SZ)) > 0) { + memcpy(tmpbuf, "kernel: ", 8); + i += 8; + tmpbuf[i] = '\0'; + serveConnection(tmpbuf, i); + } else if (i < 0 && errno != EINTR && errno != EAGAIN) { + bb_perror_msg_and_die("/proc/kmsg read error"); + } + } +#endif } /* for main loop */ } @@ -692,7 +731,7 @@ char *p; /* do normal option parsing */ - while ((opt = getopt(argc, argv, "m:nO:s:Sb:R:Ll:C::")) > 0) { + while ((opt = getopt(argc, argv, "m:nO:s:Sb:R:Ll:k:C::")) > 0) { switch (opt) { case 'm': MarkInterval = atoi(optarg) * 60; @@ -735,6 +774,14 @@ doListenUDP = TRUE; break; #endif +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG + case 'k': + console_level = atoi(optarg); + if (console_level < 0) + console_level = 0; + doKernelLog = TRUE; + break; +#endif #ifdef CONFIG_FEATURE_IPC_SYSLOG case 'C': if (optarg) { --- ./sysklogd/Config.in~ 2006-03-07 22:45:12.000000000 +0100 +++ ./sysklogd/Config.in 2006-03-09 20:39:53.000000000 +0100 @@ -53,6 +53,18 @@ The real goal is not to provide a big local syslog server, but to use it as a centralized repeater. +config CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG + bool " Make syslogd collect kernel messages" + default n + depends on CONFIG_SYSLOGD + help + When you enable this feature, the syslogd utility will + be able to directly read kernel messages from /proc/kmsg + without the need for an external klogd daemon. Unless you + know that you really need this option, you'd better use + the more flexible klogd featured as a standalone daemon + which is provided in another option below. + config CONFIG_FEATURE_IPC_SYSLOG bool " Circular Buffer support" default n --- ./include/usage.h~ 2006-03-07 22:45:12.000000000 +0100 +++ ./include/usage.h 2006-03-09 21:08:32.000000000 +0100 @@ -2869,6 +2869,11 @@ #else # define USAGE_SYSLOG_LISTEN_UDP(a) #endif +#ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG +# define USAGE_SYSLOG_INCLUDE_KLOG(a) a +#else +# define USAGE_SYSLOG_INCLUDE_KLOG(a) +#endif #ifdef CONFIG_FEATURE_IPC_SYSLOG # define USAGE_IPC_LOG(a) a #else @@ -2910,6 +2915,8 @@ "\t-L\t\tLog locally and via network logging (default is network only)") \ USAGE_SYSLOG_LISTEN_UDP( \ "\n\t-l HOST[:PORT]\tAccept UDP packets on this local IP or hostname on PORT (default PORT=514/UDP)\n") \ + USAGE_SYSLOG_INCLUDE_KLOG( \ + "\n\t-k LEVEL\tCollect kernel logs and set console to display logs below LEVEL (1-8)\n") \ USAGE_IPC_LOG( \ "\n\t-C [size(KiB)]\tLog to a circular buffer (read the buffer using logread)") #define syslogd_example_usage \