diff options
-rw-r--r-- | plugins/imklog/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/imklog/solaris.c | 589 | ||||
-rw-r--r-- | plugins/imklog/solaris_cddl.c | 402 |
3 files changed, 389 insertions, 604 deletions
diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 85305ce3..06d4013c 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -12,7 +12,7 @@ imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c endif if ENABLE_IMKLOG_SOLARIS -imklog_la_SOURCES += solaris_cddl.c +imklog_la_SOURCES += solaris.c solaris_cddl.c endif imklog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) diff --git a/plugins/imklog/solaris.c b/plugins/imklog/solaris.c index 97aead22..294efa7c 100644 --- a/plugins/imklog/solaris.c +++ b/plugins/imklog/solaris.c @@ -27,507 +27,181 @@ * * A copy of the GPL can be found in the file "COPYING" in this distribution. */ -#include "config.h" -#include "rsyslog.h" -#include <stdlib.h> -#include <stdio.h> -#include <assert.h> -#include <signal.h> -#include <string.h> -#include <pthread.h> -#include "cfsysline.h" -#include "template.h" -#include "msg.h" -#include "module-template.h" -#include "imklog.h" -#include "unicode-helper.h" - - -/* Includes. */ -#include <unistd.h> -#include <errno.h> -#include <sys/fcntl.h> -#include <sys/stat.h> -#if HAVE_TIME_H -# include <time.h> +#ifdef HAVE_CONFIG_H +# include "config.h" #endif - -#include <stdarg.h> -#include <paths.h> -#include "ksyms.h" - -#define __LIBRARY__ +#include <stdlib.h> #include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> -#if !defined(__GLIBC__) -# define __NR_ksyslog __NR_syslog -_syscall3(int,ksyslog,int, type, char *, buf, int, len); -#else -#include <sys/klog.h> -#define ksyslog klogctl -#endif - +#include "rsyslog.h" +#include "imklog.h" +#include "unicode-helper.h" +#include "solaris_cddl.h" +/* globals */ +static int fklog; // TODO: remove #ifndef _PATH_KLOG -#define _PATH_KLOG "/proc/kmsg" +# define _PATH_KLOG "/dev/log" #endif -#define LOG_BUFFER_SIZE 4096 -#define LOG_LINE_LENGTH 1000 - -static int kmsg; -static char log_buffer[LOG_BUFFER_SIZE]; - -static enum LOGSRC {none, proc, kernel} logsrc; - - -/* Function prototypes. */ -extern int ksyslog(int type, char *buf, int len); - - -static uchar *GetPath(void) -{ - return pszPath ? pszPath : UCHAR_CONSTANT(_PATH_KLOG); -} - -static void CloseLogSrc(void) -{ - /* Turn on logging of messages to console, but only if a log level was speficied */ - if(console_log_level != -1) - ksyslog(7, NULL, 0); - - /* Shutdown the log sources. */ - switch(logsrc) { - case kernel: - ksyslog(0, NULL, 0); - imklogLogIntMsg(LOG_INFO, "Kernel logging (ksyslog) stopped."); - break; - case proc: - close(kmsg); - imklogLogIntMsg(LOG_INFO, "Kernel logging (proc) stopped."); - break; - case none: - break; - } - - return; -} - +// HELPER +/* handle some defines missing on more than one platform */ +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif -static enum LOGSRC GetKernelLogSrc(void) +int solaris_create_unix_socket(const char *path) { - auto struct stat sb; - - /* Set level of kernel console messaging.. */ - if ( (console_log_level != -1) && - (ksyslog(8, NULL, console_log_level) < 0) && - (errno == EINVAL) ) - { - /* - * An invalid arguement error probably indicates that - * a pre-0.14 kernel is being run. At this point we - * issue an error message and simply shut-off console - * logging completely. - */ - imklogLogIntMsg(LOG_WARNING, "Cannot set console log level - disabling " - "console output."); - } - - /* - * First do a stat to determine whether or not the proc based - * file system is available to get kernel messages from. - */ - if ( use_syscall || - ((stat((char*)GetPath(), &sb) < 0) && (errno == ENOENT)) ) - { - /* Initialize kernel logging. */ - ksyslog(1, NULL, 0); - imklogLogIntMsg(LOG_INFO, "imklog %s, log source = ksyslog " - "started.", VERSION); - return(kernel); - } - - if ( (kmsg = open((char*)GetPath(), O_RDONLY|O_CLOEXEC)) < 0 ) - { - imklogLogIntMsg(LOG_ERR, "imklog: Cannot open proc file system, %d.\n", errno); - ksyslog(7, NULL, 0); - return(none); + struct sockaddr_un sunx; + int fd; + +return; + if (path[0] == '\0') + return -1; + + unlink(path); + + memset(&sunx, 0, sizeof(sunx)); + sunx.sun_family = AF_UNIX; + (void) strncpy(sunx.sun_path, path, sizeof(sunx.sun_path)); + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd < 0 || bind(fd, (struct sockaddr *) &sunx, SUN_LEN(&sunx)) < 0 || + chmod(path, 0666) < 0) { + //errmsg.LogError(errno, NO_ERRCODE, "connot create '%s'", path); + dbgprintf("cannot create %s (%d).\n", path, errno); + close(fd); + return -1; } - - imklogLogIntMsg(LOG_INFO, "imklog %s, log source = %s started.", VERSION, GetPath()); - return(proc); + return fd; } +// END HELPER -/* Copy characters from ptr to line until a char in the delim - * string is encountered or until min( space, len ) chars have - * been copied. - * - * Returns the actual number of chars copied. - */ -static int copyin( uchar *line, int space, - const char *ptr, int len, - const char *delim ) +static uchar *GetPath(void) { - auto int i; - auto int count; - - count = len < space ? len : space; - - for(i=0; i<count && !strchr(delim, *ptr); i++ ) { - *line++ = *ptr++; - } - - return(i); + return pszPath ? pszPath : UCHAR_CONSTANT(_PATH_KLOG); } -/* - * Messages are separated by "\n". Messages longer than - * LOG_LINE_LENGTH are broken up. - * - * Kernel symbols show up in the input buffer as : "[<aaaaaa>]", - * where "aaaaaa" is the address. These are replaced with - * "[symbolname+offset/size]" in the output line - symbolname, - * offset, and size come from the kernel symbol table. - * - * If a kernel symbol happens to fall at the end of a message close - * in length to LOG_LINE_LENGTH, the symbol will not be expanded. - * (This should never happen, since the kernel should never generate - * messages that long. - * - * To preserve the original addresses, lines containing kernel symbols - * are output twice. Once with the symbols converted and again with the - * original text. Just in case somebody wants to run their own Oops - * analysis on the syslog, e.g. ksymoops. +/* open the kernel log - will be called inside the willRun() imklog + * entry point. -- rgerhards, 2008-04-09 */ -static void LogLine(char *ptr, int len) -{ - enum parse_state_enum { - PARSING_TEXT, - PARSING_SYMSTART, /* at < */ - PARSING_SYMBOL, - PARSING_SYMEND /* at ] */ - }; - - static uchar line_buff[LOG_LINE_LENGTH]; - - static uchar *line =line_buff; - static enum parse_state_enum parse_state = PARSING_TEXT; - static int space = sizeof(line_buff)-1; - - static uchar *sym_start; /* points at the '<' of a symbol */ - - auto int delta = 0; /* number of chars copied */ - auto int symbols_expanded = 0; /* 1 if symbols were expanded */ - auto int skip_symbol_lookup = 0; /* skip symbol lookup on this pass */ - auto char *save_ptr = ptr; /* save start of input line */ - auto int save_len = len; /* save length at start of input line */ - - while( len > 0 ) - { - if( space == 0 ) /* line buffer is full */ - { - /* - ** Line too long. Start a new line. - */ - *line = 0; /* force null terminator */ - - //dbgprintf("Line buffer full:\n"); - //dbgprintf("\tLine: %s\n", line); - - Syslog(LOG_INFO, line_buff); - line = line_buff; - space = sizeof(line_buff)-1; - parse_state = PARSING_TEXT; - symbols_expanded = 0; - skip_symbol_lookup = 0; - save_ptr = ptr; - save_len = len; - } - - switch( parse_state ) - { - case PARSING_TEXT: - delta = copyin(line, space, ptr, len, "\n[" ); - line += delta; - ptr += delta; - space -= delta; - len -= delta; - - if( space == 0 || len == 0 ) - { - break; /* full line_buff or end of input buffer */ - } - - if( *ptr == '\0' ) /* zero byte */ - { - ptr++; /* skip zero byte */ - space -= 1; - len -= 1; - - break; - } - - if( *ptr == '\n' ) /* newline */ - { - ptr++; /* skip newline */ - space -= 1; - len -= 1; - - *line = 0; /* force null terminator */ - Syslog(LOG_INFO, line_buff); - line = line_buff; - space = sizeof(line_buff)-1; - if (symbols_twice) { - if (symbols_expanded) { - /* reprint this line without symbol lookup */ - symbols_expanded = 0; - skip_symbol_lookup = 1; - ptr = save_ptr; - len = save_len; - } - else - { - skip_symbol_lookup = 0; - save_ptr = ptr; - save_len = len; - } - } - break; - } - if( *ptr == '[' ) /* possible kernel symbol */ - { - *line++ = *ptr++; - space -= 1; - len -= 1; - if (!skip_symbol_lookup) - parse_state = PARSING_SYMSTART; /* at < */ - break; - } - /* Now that line_buff is no longer fed to *printf as format - * string, '%'s are no longer "dangerous". - */ - break; - - case PARSING_SYMSTART: - if( *ptr != '<' ) - { - parse_state = PARSING_TEXT; /* not a symbol */ - break; - } - - /* - ** Save this character for now. If this turns out to - ** be a valid symbol, this char will be replaced later. - ** If not, we'll just leave it there. - */ - - sym_start = line; /* this will point at the '<' */ - - *line++ = *ptr++; - space -= 1; - len -= 1; - parse_state = PARSING_SYMBOL; /* symbol... */ - break; - - case PARSING_SYMBOL: - delta = copyin( line, space, ptr, len, ">\n[" ); - line += delta; - ptr += delta; - space -= delta; - len -= delta; - if( space == 0 || len == 0 ) - { - break; /* full line_buff or end of input buffer */ - } - if( *ptr != '>' ) - { - parse_state = PARSING_TEXT; - break; - } - - *line++ = *ptr++; /* copy the '>' */ - space -= 1; - len -= 1; - - parse_state = PARSING_SYMEND; - - break; - - case PARSING_SYMEND: - if( *ptr != ']' ) - { - parse_state = PARSING_TEXT; /* not a symbol */ - break; - } - - /* - ** It's really a symbol! Replace address with the - ** symbol text. - */ - { - auto int sym_space; - - unsigned long value; - auto struct symbol sym; - auto char *symbol; - - *(line-1) = 0; /* null terminate the address string */ - value = strtoul((char*)(sym_start+1), (char **) 0, 16); - *(line-1) = '>'; /* put back delim */ - - if ( !symbol_lookup || (symbol = LookupSymbol(value, &sym)) == (char *)0 ) - { - parse_state = PARSING_TEXT; - break; - } - - /* - ** verify there is room in the line buffer - */ - sym_space = space + ( line - sym_start ); - if( (unsigned) sym_space < strlen(symbol) + 30 ) /*(30 should be overkill)*/ - { - parse_state = PARSING_TEXT; /* not enough space */ - break; - } - - // TODO: sprintf!!!! - delta = sprintf( (char*) sym_start, "%s+%d/%d]", - symbol, sym.offset, sym.size ); - - space = sym_space + delta; - line = sym_start + delta; - symbols_expanded = 1; - } - ptr++; - len--; - parse_state = PARSING_TEXT; - break; - - default: /* Can't get here! */ - parse_state = PARSING_TEXT; - - } - } - - return; -} - - -static void LogKernelLine(void) +rsRetVal +klogWillRun(void) { - auto int rdcnt; - - /* - * Zero-fill the log buffer. This should cure a multitude of - * problems with klogd logging the tail end of the message buffer - * which will contain old messages. Then read the kernel log - * messages into this fresh buffer. - */ - memset(log_buffer, '\0', sizeof(log_buffer)); - if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer)-1)) < 0 ) - { - if(errno == EINTR) - return; - imklogLogIntMsg(LOG_ERR, "imklog Error return from sys_sycall: %d\n", errno); + DEFiRet; + + fklog = sun_openklog((char*) GetPath(), O_RDONLY); + if (fklog < 0) { + char errStr[1024]; + int err = errno; +perror("XXX"); + rs_strerror_r(err, errStr, sizeof(errStr)); + DBGPRINTF("error %d opening log socket %s: %s\n", + GetPath(), errStr); + iRet = RS_RET_ERR; // TODO: better error code } - else - LogLine(log_buffer, rdcnt); - return; + + RETiRet; } -static void LogProcLine(void) +/* Read /dev/klog while data are available, split into lines. + * Contrary to standard BSD syslogd, we do a blocking read. We can + * afford this as imklog is running on its own threads. So if we have + * a single file, it really doesn't matter if we wait inside a 1-file + * select or the read() directly. + */ +static void +readklog(void) { - auto int rdcnt; - - /* - * Zero-fill the log buffer. This should cure a multitude of - * problems with klogd logging the tail end of the message buffer - * which will contain old messages. Then read the kernel messages - * from the message pseudo-file into this fresh buffer. + char *p, *q; + int len, i; + int iMaxLine; + uchar bufRcv[4096+1]; + uchar *pRcv = NULL; /* receive buffer */ + + iMaxLine = klog_getMaxLine(); + + /* we optimize performance: if iMaxLine is below 4K (which it is in almost all + * cases, we use a fixed buffer on the stack. Only if it is higher, heap memory + * is used. We could use alloca() to achive a similar aspect, but there are so + * many issues with alloca() that I do not want to take that route. + * rgerhards, 2008-09-02 */ - memset(log_buffer, '\0', sizeof(log_buffer)); - if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 ) { - if ( errno == EINTR ) - return; - imklogLogIntMsg(LOG_ERR, "Cannot read proc file system: %d - %s.", errno, strerror(errno)); + if((size_t) iMaxLine < sizeof(bufRcv) - 1) { + pRcv = bufRcv; } else { - LogLine(log_buffer, rdcnt); - } + if((pRcv = (uchar*) malloc(sizeof(uchar) * (iMaxLine + 1))) == NULL) + iMaxLine = sizeof(bufRcv) - 1; /* better this than noting */ + } - return; -} + len = 0; + for (;;) { + dbgprintf("----------imklog(BSD) waiting for kernel log line\n"); + i = read(fklog, pRcv + len, iMaxLine - len); + if (i > 0) { + pRcv[i + len] = '\0'; + } else { + if (i < 0 && errno != EINTR && errno != EAGAIN) { + imklogLogIntMsg(LOG_ERR, + "imklog error %d reading kernel log - shutting down imklog", + errno); + fklog = -1; + } + break; + } + for (p = pRcv; (q = strchr(p, '\n')) != NULL; p = q + 1) { + *q = '\0'; + Syslog(LOG_INFO, (uchar*) p); + } + len = strlen(p); + if (len >= iMaxLine - 1) { + Syslog(LOG_INFO, (uchar*)p); + len = 0; + } + if (len > 0) + memmove(pRcv, p, len + 1); + } + if (len > 0) + Syslog(LOG_INFO, pRcv); -/* to be called in the module's WillRun entry point - * rgerhards, 2008-04-09 - */ -rsRetVal klogLogKMsg(void) -{ - DEFiRet; - switch(logsrc) { - case kernel: - LogKernelLine(); - break; - case proc: - LogProcLine(); - break; - case none: - /* TODO: We need to handle this case here somewhat more intelligent - * This is now at least partly done - code should never reach this point - * as willRun() already checked for the "none" status -- rgerhards, 2007-12-17 - */ - pause(); - break; - } - RETiRet; + if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) + free(pRcv); } -/* to be called in the module's WillRun entry point +/* to be called in the module's AfterRun entry point * rgerhards, 2008-04-09 */ -rsRetVal klogWillRun(void) +rsRetVal klogAfterRun(void) { DEFiRet; - /* Initialize this module. If that fails, we tell the engine we don't like to run */ - /* Determine where kernel logging information is to come from. */ - logsrc = GetKernelLogSrc(); - if(logsrc == none) { - iRet = RS_RET_NO_KERNEL_LOGSRC; - } else { - if (symbol_lookup) { - symbol_lookup = (InitKsyms(symfile) == 1); - symbol_lookup |= InitMsyms(); - if (symbol_lookup == 0) { - imklogLogIntMsg(LOG_WARNING, "cannot find any symbols, turning off symbol lookups"); - } - } - } - + if(fklog != -1) + close(fklog); RETiRet; } -/* to be called in the module's AfterRun entry point + +/* to be called in the module's WillRun entry point, this is the main + * "message pull" mechanism. * rgerhards, 2008-04-09 */ -rsRetVal klogAfterRun(void) +rsRetVal klogLogKMsg(void) { DEFiRet; - /* cleanup here */ - if(logsrc != none) - CloseLogSrc(); - - DeinitKsyms(); - DeinitMsyms(); - - RETiRet; + sun_sys_poll(); + //readklog(); + RETiRet; } @@ -537,9 +211,6 @@ rsRetVal klogAfterRun(void) int klogFacilIntMsg(void) { - return LOG_KERN; + return LOG_SYSLOG; } - -/* vi:set ai: - */ 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; - } -} |