summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/imklog/Makefile.am2
-rw-r--r--plugins/imklog/solaris.c589
-rw-r--r--plugins/imklog/solaris_cddl.c402
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;
- }
-}