diff options
Diffstat (limited to 'plugins/imklog/solaris_cddl.c')
-rw-r--r-- | plugins/imklog/solaris_cddl.c | 402 |
1 files changed, 258 insertions, 144 deletions
diff --git a/plugins/imklog/solaris_cddl.c b/plugins/imklog/solaris_cddl.c index df783c46..f45c5e62 100644 --- a/plugins/imklog/solaris_cddl.c +++ b/plugins/imklog/solaris_cddl.c @@ -1,3 +1,4 @@ +#define MAXLINE 4096 /* * CDDL HEADER START * @@ -41,28 +42,153 @@ */ #include "config.h" +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <pthread.h> +#include <sys/poll.h> + +//--------- +#include <note.h> +#include <errno.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <ctype.h> +#include <signal.h> +#include <string.h> +#include <strings.h> +#include <libscf.h> +#include <netconfig.h> +#include <netdir.h> +#include <pwd.h> +#include <utmpx.h> +#include <limits.h> +#include <pthread.h> +#include <fcntl.h> +#include <stropts.h> +#include <assert.h> +#include <sys/statvfs.h> + +#include <sys/param.h> +#include <sys/sysmacros.h> +#include <sys/syslog.h> +#include <sys/strlog.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/utsname.h> +#include <sys/poll.h> +#include <sys/wait.h> +#include <sys/resource.h> +#include <sys/mman.h> +#include <sys/note.h> +#include <door.h> +//-------- + + +#include "rsyslog.h" + +static struct pollfd Pfd; /* Pollfd for local the log device */ + /* - * Attempts to open the local log device - * and return a file descriptor. + * findnl_bkwd: + * Scans each character in buf until it finds the last newline in buf, + * or the scanned character becomes the last COMPLETE character in buf. + * Returns the number of scanned bytes. + * + * buf - pointer to a buffer containing the message string + * len - the length of the buffer */ -int -sun_oopenklog(char *name, int mode) +size_t +findnl_bkwd(const char *buf, const size_t len) { - int fd; - struct strioctl str; + const char *p; + size_t mb_cur_max; pthread_t mythreadno; if (Debug) { mythreadno = pthread_self(); } + if (len == 0) { + return (0); + } + + mb_cur_max = MB_CUR_MAX; + + if (mb_cur_max == 1) { + /* single-byte locale */ + for (p = buf + len - 1; p != buf; p--) { + if (*p == '\n') { + return ((size_t)(p - buf)); + } + } + return ((size_t)len); + } else { + /* multi-byte locale */ + int mlen; + const char *nl; + size_t rem; + + p = buf; + nl = NULL; + for (rem = len; rem >= mb_cur_max; ) { + mlen = mblen(p, mb_cur_max); + if (mlen == -1) { + /* + * Invalid character found. + */ + dbgprintf("findnl_bkwd(%u): Invalid MB " + "sequence\n", mythreadno); + /* + * handle as a single byte character. + */ + p++; + rem--; + } else { + /* + * It's guaranteed that *p points to + * the 1st byte of a multibyte character. + */ + if (*p == '\n') { + nl = p; + } + p += mlen; + rem -= mlen; + } + } + if (nl) { + return ((size_t)(nl - buf)); + } + /* + * no newline nor null byte found. + * Also it's guaranteed that *p points to + * the 1st byte of a (multibyte) character + * at this point. + */ + return (len - rem); + } +} +//___ end + +/* + * Attempts to open the local log device + * and return a file descriptor. + */ +int +sun_openklog(char *name, int mode) +{ + int fd; + struct strioctl str; + + solaris_create_unix_socket(name); if ((fd = open(name, mode)) < 0) { - logerror("cannot open %s", name); - DPRINT3(1, "openklog(%u): cannot create %s (%d)\n", - mythreadno, name, errno); + //logerror("cannot open %s", name); + dbgprintf("openklog: cannot open %s (%d)\n", + name, errno); return (-1); } str.ic_cmd = I_CONSLOG; @@ -70,16 +196,115 @@ sun_oopenklog(char *name, int mode) str.ic_len = 0; str.ic_dp = NULL; if (ioctl(fd, I_STR, &str) < 0) { - logerror("cannot register to log console messages"); - DPRINT2(1, "openklog(%u): cannot register to log " - "console messages (%d)\n", mythreadno, errno); + //logerror("cannot register to log console messages"); + dbgprintf("openklog: cannot register to log " + "console messages (%d)\n", errno); return (-1); } + Pfd.fd = fd; return (fd); } /* + * Pull up one message from log driver. + */ +void +sun_getkmsg(int timeout) +{ + int flags = 0, i; + char *lastline; + struct strbuf ctl, dat; + struct log_ctl hdr; + char buf[MAXLINE+1]; + size_t buflen; + size_t len; + char tmpbuf[MAXLINE+1]; + + dat.maxlen = MAXLINE; + dat.buf = buf; + ctl.maxlen = sizeof (struct log_ctl); + ctl.buf = (caddr_t)&hdr; + + while ((i = getmsg(Pfd.fd, &ctl, &dat, &flags)) == MOREDATA) { + lastline = &dat.buf[dat.len]; + *lastline = '\0'; + + dbgprintf("sys_poll: getmsg: dat.len = %d\n", dat.len); + buflen = strlen(buf); + len = findnl_bkwd(buf, buflen); + + (void) memcpy(tmpbuf, buf, len); + tmpbuf[len] = '\0'; + + /* Format sys will enqueue the log message. + * Set the sync flag if timeout != 0, which + * means that we're done handling all the + * initial messages ready during startup. + */ + Syslog(LOG_INFO, buf); + /*if (timeout == 0) { + formatsys(&hdr, tmpbuf, 0); + //sys_init_msg_count++; + } else { + formatsys(&hdr, tmpbuf, 1); + }*/ + + if (len != buflen) { + /* If anything remains in buf */ + size_t remlen; + + if (buf[len] == '\n') { + /* skip newline */ + len++; + } + + /* Move the remaining bytes to + * the beginnning of buf. + */ + + remlen = buflen - len; + (void) memcpy(buf, &buf[len], remlen); + dat.maxlen = MAXLINE - remlen; + dat.buf = &buf[remlen]; + } else { + dat.maxlen = MAXLINE; + dat.buf = buf; + } + } + + if (i == 0 && dat.len > 0) { + dat.buf[dat.len] = '\0'; + /* + * Format sys will enqueue the log message. + * Set the sync flag if timeout != 0, which + * means that we're done handling all the + * initial messages ready during startup. + */ + dbgprintf("getkmsg: getmsg: dat.maxlen = %d\n", dat.maxlen); + dbgprintf("getkmsg: getmsg: dat.len = %d\n", dat.len); + dbgprintf("getkmsg: getmsg: strlen(dat.buf) = %d\n", strlen(dat.buf)); + dbgprintf("getkmsg: getmsg: dat.buf = \"%s\"\n", dat.buf); + dbgprintf("getkmsg: buf len = %d\n", strlen(buf)); + //if (timeout == 0) { + //formatsys(&hdr, buf, 0); + //--sys_init_msg_count++; + //} else { + //formatsys(&hdr, buf, 1); + //} + Syslog(LOG_INFO, buf); + } else if (i < 0 && errno != EINTR) { + if(1){ // (!shutting_down) { + dbgprintf("kernel log driver read error"); + } + // TODO trigger retry logic + //(void) close(Pfd.fd); + //Pfd.fd = -1; + } +} + + +/* * Open the log device, and pull up all pending messages. */ void @@ -87,26 +312,30 @@ sun_prepare_sys_poll() { int nfds, funix; - if ((funix = openklog(LogName, O_RDONLY)) < 0) { +/* + if ((funix = sun_openklog(LogName, O_RDONLY)) < 0) { logerror("can't open kernel log device - fatal"); exit(1); } +*/ Pfd.fd = funix; Pfd.events = POLLIN; for (;;) { nfds = poll(&Pfd, 1, 0); + /* if (nfds <= 0) { if (sys_init_msg_count > 0) flushmsg(SYNC_FILE); break; - } + }*/ if (Pfd.revents & POLLIN) { - getkmsg(0); + sun_getkmsg(0); } else if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) { - logerror("kernel log driver poll error"); + //logerror("kernel log driver poll error"); + dbgprintf("kernel log driver poll error"); break; } } @@ -123,14 +352,8 @@ void * sun_sys_poll(void *ap) { int nfds; - static int klogerrs = 0; - pthread_t mythreadno; - - if (Debug) { - mythreadno = pthread_self(); - } - DPRINT1(1, "sys_poll(%u): sys_thread started\n", mythreadno); + dbgprintf("sys_poll: sys_thread started\n"); /* * Try to process as many messages as we can without blocking on poll. @@ -141,11 +364,8 @@ sun_sys_poll(void *ap) * the previously counted initial messages out to disk. */ - sys_init_msg_count = 0; - for (;;) { errno = 0; - t_errno = 0; nfds = poll(&Pfd, 1, INFTIM); @@ -154,139 +374,33 @@ sun_sys_poll(void *ap) if (nfds < 0) { if (errno != EINTR) - logerror("poll"); + dbgprintf("poll error");// logerror("poll"); continue; } if (Pfd.revents & POLLIN) { - getkmsg(INFTIM); + sun_getkmsg(INFTIM); } else { - if (shutting_down) { - pthread_exit(0); - } + // TODO: shutdown, the rsyslog way + //if (shutting_down) { + //pthread_exit(0); + //} if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) { - logerror("kernel log driver poll error"); + // TODO: trigger retry logic +/* logerror("kernel log driver poll error"); (void) close(Pfd.fd); Pfd.fd = -1; + */ } } - while (Pfd.fd == -1 && klogerrs++ < 10) { - Pfd.fd = openklog(LogName, O_RDONLY); +/* while (Pfd.fd == -1 && klogerrs++ < 10) { + Pfd.fd = sun_openklog(LogName, O_RDONLY); } if (klogerrs >= 10) { logerror("can't reopen kernel log device - fatal"); exit(1); - } + }*/ } /*NOTREACHED*/ return (NULL); } - -/* - * Pull up one message from log driver. - */ -void -sun_getkmsg(int timeout) -{ - int flags = 0, i; - char *lastline; - struct strbuf ctl, dat; - struct log_ctl hdr; - char buf[MAXLINE+1]; - size_t buflen; - size_t len; - char tmpbuf[MAXLINE+1]; - pthread_t mythreadno; - - if (Debug) { - mythreadno = pthread_self(); - } - - dat.maxlen = MAXLINE; - dat.buf = buf; - ctl.maxlen = sizeof (struct log_ctl); - ctl.buf = (caddr_t)&hdr; - - while ((i = getmsg(Pfd.fd, &ctl, &dat, &flags)) == MOREDATA) { - lastline = &dat.buf[dat.len]; - *lastline = '\0'; - - DPRINT2(5, "sys_poll:(%u): getmsg: dat.len = %d\n", - mythreadno, dat.len); - buflen = strlen(buf); - len = findnl_bkwd(buf, buflen); - - (void) memcpy(tmpbuf, buf, len); - tmpbuf[len] = '\0'; - - /* - * Format sys will enqueue the log message. - * Set the sync flag if timeout != 0, which - * means that we're done handling all the - * initial messages ready during startup. - */ - if (timeout == 0) { - formatsys(&hdr, tmpbuf, 0); - sys_init_msg_count++; - } else { - formatsys(&hdr, tmpbuf, 1); - } - sys_msg_count++; - - if (len != buflen) { - /* If anything remains in buf */ - size_t remlen; - - if (buf[len] == '\n') { - /* skip newline */ - len++; - } - - /* - * Move the remaining bytes to - * the beginnning of buf. - */ - - remlen = buflen - len; - (void) memcpy(buf, &buf[len], remlen); - dat.maxlen = MAXLINE - remlen; - dat.buf = &buf[remlen]; - } else { - dat.maxlen = MAXLINE; - dat.buf = buf; - } - } - - if (i == 0 && dat.len > 0) { - dat.buf[dat.len] = '\0'; - /* - * Format sys will enqueue the log message. - * Set the sync flag if timeout != 0, which - * means that we're done handling all the - * initial messages ready during startup. - */ - DPRINT2(5, "getkmsg(%u): getmsg: dat.maxlen = %d\n", - mythreadno, dat.maxlen); - DPRINT2(5, "getkmsg(%u): getmsg: dat.len = %d\n", - mythreadno, dat.len); - DPRINT2(5, "getkmsg(%u): getmsg: strlen(dat.buf) = %d\n", - mythreadno, strlen(dat.buf)); - DPRINT2(5, "getkmsg(%u): getmsg: dat.buf = \"%s\"\n", - mythreadno, dat.buf); - DPRINT2(5, "getkmsg(%u): buf len = %d\n", - mythreadno, strlen(buf)); - if (timeout == 0) { - formatsys(&hdr, buf, 0); - sys_init_msg_count++; - } else { - formatsys(&hdr, buf, 1); - } - sys_msg_count++; - } else if (i < 0 && errno != EINTR) { - if (!shutting_down) { - logerror("kernel log driver read error"); - } - (void) close(Pfd.fd); - Pfd.fd = -1; - } -} |