This patch correctly reads the kernel logs at startup time. The kernel then returns large blocks of data which must be cut in lines. Also, we need to ensure that we will never block on the kernel FD upon next reads. --- ./sysklogd/syslogd.c~ 2006-03-13 14:59:45.000000000 +0100 +++ ./sysklogd/syslogd.c 2006-03-13 22:35:44.000000000 +0100 @@ -707,16 +707,68 @@ #endif /* SYSLOG_LISTEN_UDP */ #ifdef CONFIG_FEATURE_SYSLOG_INCLUDE_KLOG if (doKernelLog && FD_ISSET(klog_fd, &fds)) { - int i; + int i, j, msgptr, msgend; + int save, remain; - 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) { + save = strlen("kernel: "); + remain = 0; + + + i = read(klog_fd, tmpbuf + save, TMP_BUF_SZ - save - 1); + if (i < 0 && errno != EINTR && errno != EAGAIN) { bb_perror_msg_and_die("/proc/kmsg read error"); } + + while (i > 0) { + fd_set rfd; + struct timeval tv; + + /* look for a line feed after remaining data */ + msgptr = save; + j = msgptr + remain; + msgend = j + i; + while (j < msgend) { + if (tmpbuf[j] != '\n') { + j++; + continue; + } + /* we have one complete message between msgptr and j */ + tmpbuf[j] = 0; + memcpy(tmpbuf + msgptr - save, + "kernel: ", save); + serveConnection(tmpbuf + msgptr - save, + j - msgptr + save); + msgptr = ++j; + } + remain = msgend - msgptr; + + if (!remain) + break; + + /* now we know there are some data left, so we'll try + * to read the next block. but we *MUST* check with + * select() that data is available before trying to + * read again, otherwise we willy block. + */ + + memmove(tmpbuf + save, tmpbuf + msgptr, remain); + + FD_ZERO(&rfd); FD_SET(klog_fd, &rfd); + tv.tv_sec = tv.tv_usec = 0; + i = 0; + if (select(klog_fd + 1, &rfd, NULL, NULL, &tv) <= 0 || + (i = read(klog_fd, tmpbuf + save + remain, + TMP_BUF_SZ - save - remain - 1)) <= 0) { + if (i < 0 && errno != EINTR && errno != EAGAIN) { + bb_perror_msg_and_die("/proc/kmsg read error"); + } + /* end of read : send last data and return */ + tmpbuf[save + remain] = 0; + memcpy(tmpbuf, "kernel: ", save); + serveConnection(tmpbuf, save + remain); + break; + } + } /* end of while(1) */ } #endif } /* for main loop */