From 838072a22f5a98e150dbab055eba28453238109f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 8 Apr 2008 23:34:14 +0200 Subject: changed imklog to a driver interface imklog now uses os-specific drivers. The initial "set" contains the linux driver. This is a prequisite for BSD klog, which can now be implemented on that driver interface. --- plugins/imklog/Makefile.am | 2 +- plugins/imklog/imklog.c | 499 +++--------------------------------------- plugins/imklog/imklog.h | 25 ++- plugins/imklog/ksym.c | 22 +- plugins/imklog/linux.c | 533 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 599 insertions(+), 482 deletions(-) create mode 100644 plugins/imklog/linux.c (limited to 'plugins') diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 11e00962..49bbbc70 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -1,6 +1,6 @@ pkglib_LTLIBRARIES = imklog.la -imklog_la_SOURCES = imklog.c imklog.h module.h ksym.c ksyms.h ksym_mod.c +imklog_la_SOURCES = imklog.c linux.c imklog.h module.h ksym.c ksyms.h ksym_mod.c imklog_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) imklog_la_LDFLAGS = -module -avoid-version imklog_la_LIBADD = diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index bfea8c6f..972e93db 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -1,14 +1,24 @@ -/* The kernel log input module for Linux. This file heavily - * borrows from the klogd daemon provided by the sysklogd project. - * Many thanks for this piece of software. +/* The kernel log module. + * + * This is an abstracted module. As Linux and BSD kernel log is conceptually the + * same, we do not do different input plugins for them but use + * imklog in both cases, just with different "backend drivers" for + * the different platforms. This also enables a rsyslog.conf to + * be used on multiple platforms without the need to take care of + * what the kernel log is coming from. + * + * See platform-specific files (e.g. linux.c, bsd.c) in the plugin's + * working directory. For other systems with similar kernel logging + * functionality, no new input plugin shall be written but rather a + * driver be developed for imklog. Please note that imklog itself is + * mostly concerned with handling the interface. Any real action happens + * in the drivers, as things may be pretty different on different + * platforms. * * Please note that this file replaces the klogd daemon that was * also present in pre-v3 versions of rsyslog. * - * I have begun to convert this to an input module on 2007-12-17. - * IMPORTANT: more than a single instance is currently not supported. This - * needs to be revisited once the config file and input module interface - * supports multiple instances! + * Copyright (C) 2008 by Rainer Gerhards and Adiscon GmbH * * This file is part of rsyslog. * @@ -49,17 +59,17 @@ DEF_IMOD_STATIC_DATA /* configuration settings TODO: move to instance data? */ int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */ -static int symbols_twice = 0; -static int use_syscall = 0; -static int symbol_lookup = 1; +int symbols_twice = 0; +int use_syscall = 0; +int symbol_lookup = 1; /* TODO: configuration for the following directives must be implemented. It * was not done yet because we either do not yet have a config handler for * that type or I thought it was acceptable to push it to a later stage when * I gained more handson experience with the input module interface (and the * changes resulting from that). -- rgerhards, 2007-12-20 */ -static char *symfile = NULL; -static int console_log_level = -1; +char *symfile = NULL; +int console_log_level = -1; /* Includes. */ @@ -74,39 +84,11 @@ static int console_log_level = -1; #include #include -#include "ksyms.h" #define __LIBRARY__ #include -#if !defined(__GLIBC__) -# define __NR_ksyslog __NR_syslog -_syscall3(int,ksyslog,int, type, char *, buf, int, len); -#else -#include -#define ksyslog klogctl -#endif - - - -#ifndef _PATH_KLOG -#define _PATH_KLOG "/proc/kmsg" -#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); - /* Write a message to the message queue. * returns -1 if it fails, something else otherwise @@ -161,7 +143,7 @@ rsRetVal Syslog(int priority, char *fmt, ...) char *argl; /* Output using syslog. */ - if (!strcmp(fmt, "%s")) { + if(!strcmp(fmt, "%s")) { va_start(ap, fmt); argl = va_arg(ap, char *); if (argl[0] == '<' && argl[1] && argl[2] == '>') { @@ -206,385 +188,6 @@ rsRetVal Syslog(int priority, char *fmt, ...) } -static void CloseLogSrc(void) -{ - /* Turn on logging of messages to console, but only if we had the -c - * option -- rgerhards, 2007-08-01 - */ - if (console_log_level != -1) - ksyslog(7, NULL, 0); - - /* Shutdown the log sources. */ - switch ( logsrc ) - { - case kernel: - ksyslog(0, 0, 0); - Syslog(LOG_INFO, "Kernel logging (ksyslog) stopped."); - break; - case proc: - close(kmsg); - Syslog(LOG_INFO, "Kernel logging (proc) stopped."); - break; - case none: - break; - } - - return; -} - - -static enum LOGSRC GetKernelLogSrc(void) -{ - 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. - */ - Syslog(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(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) ) - { - /* Initialize kernel logging. */ - ksyslog(1, NULL, 0); - Syslog(LOG_INFO, "imklogd %s, log source = ksyslog " - "started.", VERSION); - return(kernel); - } - - if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) - { - char sz[512]; - snprintf(sz, sizeof(sz), "imklog: Cannot open proc file system, %d - %s.\n", errno, strerror(errno)); - logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE); - ksyslog(7, NULL, 0); /* TODO: check this, implement more */ - return(none); - } - - Syslog(LOG_INFO, "imklog %s, log source = %s started.", \ - VERSION, _PATH_KLOG); - return(proc); -} - - -/* 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( char *line, int space, - const char *ptr, int len, - const char *delim ) -{ - auto int i; - auto int count; - - count = len < space ? len : space; - - for(i=0; i]", - * 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. - */ -static void LogLine(char *ptr, int len) -{ - enum parse_state_enum { - PARSING_TEXT, - PARSING_SYMSTART, /* at < */ - PARSING_SYMBOL, - PARSING_SYMEND /* at ] */ - }; - - static char line_buff[LOG_LINE_LENGTH]; - - static char *line =line_buff; - static enum parse_state_enum parse_state = PARSING_TEXT; - static int space = sizeof(line_buff)-1; - - static char *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, "%s", 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, "%s", 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(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; - } - - delta = sprintf( 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) -{ - 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 ) - { - char sz[512]; - if(errno == EINTR) - return; - snprintf(sz, sizeof(sz), "imklog: Error return from sys_sycall: %d - %s\n", errno, strerror(errno)); - logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE); - } - else - LogLine(log_buffer, rdcnt); - return; -} - - -static void LogProcLine(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. - */ - memset(log_buffer, '\0', sizeof(log_buffer)); - if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 ) - { - if ( errno == EINTR ) - return; - Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", errno, strerror(errno)); - } - else - LogLine(log_buffer, rdcnt); - - return; -} - - BEGINrunInput CODESTARTrunInput /* this is an endless loop - it is terminated when the thread is @@ -592,59 +195,25 @@ CODESTARTrunInput * right into the sleep below. */ while(!pThrd->bShallStop) { - /* we do not need to handle the RS_RET_TERMINATE_NOW case any - * special because we just need to terminate. This may be different - * if a cleanup is needed. But for now, we can just use CHKiRet(). - * rgerhards, 2007-12-17 + /* klogLogKMsg() waits for the next kernel message, obtains it + * and then submits it to the rsyslog main queue. + * rgerhards, 2008-04-09 */ - 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; - } + CHKiRet(klogLogKMsg()); } - RETiRet; +finalize_it: ENDrunInput BEGINwillRun - /* 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) { - Syslog(LOG_WARNING, "cannot find any symbols, turning off symbol lookups\n"); - } - } - } CODESTARTwillRun + iRet = klogWillRun(); ENDwillRun BEGINafterRun CODESTARTafterRun - /* cleanup here */ - if(logsrc != none) - CloseLogSrc(); - - DeinitKsyms(); - DeinitMsyms(); + iRet = klogAfterRun(); ENDafterRun @@ -678,11 +247,5 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary, NULL, &use_syscall, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit -/* - * Local variables: - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - * vi:set ai: +/* vim:set ai: */ diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h index 71525a79..0ac25d6c 100644 --- a/plugins/imklog/imklog.h +++ b/plugins/imklog/imklog.h @@ -2,8 +2,10 @@ * These are the definitions for the klog message generation module. * * File begun on 2007-12-17 by RGerhards + * Major change: 2008-04-09: switched to a driver interface for + * several platforms * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2008 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -28,7 +30,26 @@ #include "rsyslog.h" #include "syslogd.h" -/* global variables */ +/* interface to "drivers" + * the platform specific drivers must implement these entry points. Only one + * driver may be active at any given time, thus we simply rely on the linker + * to resolve the addresses. + * rgerhards, 2008-04-09 + */ +rsRetVal klogLogKMsg(void); +rsRetVal klogWillRun(void); +rsRetVal klogAfterRun(void); + +/* the following data members may be accessed by the "drivers" + * I admit this is not the cleanest way to doing things, but I honestly + * believe it is appropriate for the job that needs to be done. + * rgerhards, 2008-04-09 + */ +extern int symbols_twice; +extern int use_syscall; +extern int symbol_lookup; +extern char *symfile; +extern int console_log_level; extern int dbgPrintSymbols; /* prototypes */ diff --git a/plugins/imklog/ksym.c b/plugins/imklog/ksym.c index b7d5903e..716ad926 100644 --- a/plugins/imklog/ksym.c +++ b/plugins/imklog/ksym.c @@ -296,7 +296,7 @@ static char *FindSymbolFile(void) **mf = system_maps; auto struct utsname utsname; - static char symfile[100]; + static char mysymfile[100]; auto FILE *sym_file = (FILE *) 0; @@ -309,19 +309,19 @@ static char *FindSymbolFile(void) for(mf = system_maps; *mf != (char *) 0 && file == (char *) 0; ++mf) { - snprintf(symfile, sizeof(symfile), "%s-%s", *mf, utsname.release); - dbgprintf("Trying %s.\n", symfile); - if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) { - if (CheckMapVersion(symfile) == 1) - file = symfile; + snprintf(mysymfile, sizeof(mysymfile), "%s-%s", *mf, utsname.release); + dbgprintf("Trying %s.\n", mysymfile); + if ( (sym_file = fopen(mysymfile, "r")) != (FILE *) 0 ) { + if (CheckMapVersion(mysymfile) == 1) + file = mysymfile; fclose(sym_file); } if (sym_file == (FILE *) 0 || file == (char *) 0) { - sprintf (symfile, "%s", *mf); - dbgprintf("Trying %s.\n", symfile); - if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) { - if (CheckMapVersion(symfile) == 1) - file = symfile; + sprintf (mysymfile, "%s", *mf); + dbgprintf("Trying %s.\n", mysymfile); + if ( (sym_file = fopen(mysymfile, "r")) != (FILE *) 0 ) { + if (CheckMapVersion(mysymfile) == 1) + file = mysymfile; fclose(sym_file); } } diff --git a/plugins/imklog/linux.c b/plugins/imklog/linux.c new file mode 100644 index 00000000..ce2ef4eb --- /dev/null +++ b/plugins/imklog/linux.c @@ -0,0 +1,533 @@ +/* klog for linux, based on the FreeBSD syslogd implementation. + * + * This contains OS-specific functionality to read the BSD + * kernel log. For a general overview, see head comment in + * imklog.c. + * + * This file heavily borrows from the klogd daemon provided by + * the sysklogd project. Many thanks for this piece of software. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. +*/ +#include "config.h" +#include "rsyslog.h" +#include +#include +#include +#include +#include +#include +#include "syslogd.h" +#include "cfsysline.h" +#include "template.h" +#include "msg.h" +#include "module-template.h" +#include "imklog.h" + + +/* Includes. */ +#include +#include +#include +#include + +#if HAVE_TIME_H +# include +#endif + +#include +#include +#include "ksyms.h" + +#define __LIBRARY__ +#include + + +#if !defined(__GLIBC__) +# define __NR_ksyslog __NR_syslog +_syscall3(int,ksyslog,int, type, char *, buf, int, len); +#else +#include +#define ksyslog klogctl +#endif + + + +#ifndef _PATH_KLOG +#define _PATH_KLOG "/proc/kmsg" +#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 void CloseLogSrc(void) +{ + /* Turn on logging of messages to console, but only if we had the -c + * option -- rgerhards, 2007-08-01 + */ + if (console_log_level != -1) + ksyslog(7, NULL, 0); + + /* Shutdown the log sources. */ + switch ( logsrc ) + { + case kernel: + ksyslog(0, 0, 0); + Syslog(LOG_INFO, "Kernel logging (ksyslog) stopped."); + break; + case proc: + close(kmsg); + Syslog(LOG_INFO, "Kernel logging (proc) stopped."); + break; + case none: + break; + } + + return; +} + + +static enum LOGSRC GetKernelLogSrc(void) +{ + 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. + */ + Syslog(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(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) ) + { + /* Initialize kernel logging. */ + ksyslog(1, NULL, 0); + Syslog(LOG_INFO, "imklogd %s, log source = ksyslog " + "started.", VERSION); + return(kernel); + } + + if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 ) + { + char sz[512]; + snprintf(sz, sizeof(sz), "imklog: Cannot open proc file system, %d - %s.\n", errno, strerror(errno)); + logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE); + ksyslog(7, NULL, 0); /* TODO: check this, implement more */ + return(none); + } + + Syslog(LOG_INFO, "imklog %s, log source = %s started.", \ + VERSION, _PATH_KLOG); + return(proc); +} + + +/* 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( char *line, int space, + const char *ptr, int len, + const char *delim ) +{ + auto int i; + auto int count; + + count = len < space ? len : space; + + for(i=0; i]", + * 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. + */ +static void LogLine(char *ptr, int len) +{ + enum parse_state_enum { + PARSING_TEXT, + PARSING_SYMSTART, /* at < */ + PARSING_SYMBOL, + PARSING_SYMEND /* at ] */ + }; + + static char line_buff[LOG_LINE_LENGTH]; + + static char *line =line_buff; + static enum parse_state_enum parse_state = PARSING_TEXT; + static int space = sizeof(line_buff)-1; + + static char *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, "%s", 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, "%s", 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(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; + } + + delta = sprintf( 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) +{ + 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 ) + { + char sz[512]; + if(errno == EINTR) + return; + snprintf(sz, sizeof(sz), "imklog: Error return from sys_sycall: %d - %s\n", errno, strerror(errno)); + logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE); + } + else + LogLine(log_buffer, rdcnt); + return; +} + + +static void LogProcLine(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. + */ + memset(log_buffer, '\0', sizeof(log_buffer)); + if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 ) { + if ( errno == EINTR ) + return; + Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", errno, strerror(errno)); + } else { + LogLine(log_buffer, rdcnt); + } + + return; +} + + +/* 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; +} + + +/* to be called in the module's WillRun entry point + * rgerhards, 2008-04-09 + */ +rsRetVal klogWillRun(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) { + Syslog(LOG_WARNING, "cannot find any symbols, turning off symbol lookups\n"); + } + } + } + + RETiRet; +} + + +/* to be called in the module's AfterRun entry point + * rgerhards, 2008-04-09 + */ +rsRetVal klogAfterRun(void) +{ + DEFiRet; + /* cleanup here */ + if(logsrc != none) + CloseLogSrc(); + + DeinitKsyms(); + DeinitMsyms(); + + RETiRet; +} + +/* vi:set ai: + */ -- cgit From d15985bc4065b4c65f491e6a829379687b2f52f1 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Apr 2008 12:36:09 +0200 Subject: pulled FreeBSD's klog functionality as a base --- plugins/imklog/bsd.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 plugins/imklog/bsd.c (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c new file mode 100644 index 00000000..25391980 --- /dev/null +++ b/plugins/imklog/bsd.c @@ -0,0 +1,151 @@ +/* klog for BSD, based on the FreeBSD syslogd implementation. + * + * This contains OS-specific functionality to read the BSD + * kernel log. For a general overview, see head comment in + * imklog.c. + * + * Copyright (C) 2008 by Rainer Gerhards for the modifications of + * the original FreeBSD sources. + * + * I would like to express my gratitude to those folks which + * layed an important foundation for rsyslog to build on. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see . + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + * + * This file is based on earlier work included in the FreeBSD sources. We + * integrated it into the rsyslog project. The copyright below applies, and + * I also reproduce the original license under which we aquired the code: + * + * Copyright (c) 1983, 1988, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * If you would like to use the code under the BSD license, you should + * aquire your own copy of BSD's syslogd, from which we have taken it. The + * code in this file is modified and may only be used under the terms of + * the GPLv3+ as specified above. + */ + + +/* open the kernel log -- rger */ +static void openKLog(void) +{ + if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) >= 0) + if (fcntl(fklog, F_SETFL, O_NONBLOCK) < 0) + fklog = -1; + if (fklog < 0) + dprintf("can't open %s (%d)\n", _PATH_KLOG, errno); +} + + +static int fklog = -1; /* /dev/klog */ +/* + * Read /dev/klog while data are available, split into lines. + */ +static void +readklog(void) +{ + char *p, *q, line[MAXLINE + 1]; + int len, i; + + len = 0; + for (;;) { + i = read(fklog, line + len, MAXLINE - 1 - len); + if (i > 0) { + line[i + len] = '\0'; + } else { + if (i < 0 && errno != EINTR && errno != EAGAIN) { + logerror("klog"); + fklog = -1; + } + break; + } + + for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) { + *q = '\0'; + printsys(p); + } + len = strlen(p); + if (len >= MAXLINE - 1) { + printsys(p); + len = 0; + } + if (len > 0) + memmove(line, p, len + 1); + } + if (len > 0) + printsys(line); +} + +/* + * Take a raw input line from /dev/klog, format similar to syslog(). + */ +static void +printsys(char *msg) +{ + char *p, *q; + long n; + int flags, isprintf, pri; + + flags = ISKERNEL | SYNC_FILE | ADDDATE; /* fsync after write */ + p = msg; + pri = DEFSPRI; + isprintf = 1; + if (*p == '<') { + errno = 0; + n = strtol(p + 1, &q, 10); + if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { + p = q + 1; + pri = n; + isprintf = 0; + } + } + /* + * Kernel printf's and LOG_CONSOLE messages have been displayed + * on the console already. + */ + if (isprintf || (pri & LOG_FACMASK) == LOG_CONSOLE) + flags |= IGN_CONS; + if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) + pri = DEFSPRI; + logmsg(pri, p, LocalHostName, flags); +} + -- cgit From c565a7e847aeb58ddcd1bdbd006597953a4dea31 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Apr 2008 12:46:57 +0200 Subject: updated build system to detect correct klog driver --- plugins/imklog/Makefile.am | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 49bbbc70..946576fe 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -1,6 +1,15 @@ pkglib_LTLIBRARIES = imklog.la -imklog_la_SOURCES = imklog.c linux.c imklog.h module.h ksym.c ksyms.h ksym_mod.c +imklog_la_SOURCES = imklog.c imklog.h module.h ksym.c ksyms.h ksym_mod.c + +# select klog "driver" +if ENABLE_IMKLOG_LINUX +imklog_la_SOURCES += linux.c +endif +if ENABLE_IMKLOG_BSD +imklog_la_SOURCES += bsd.c +endif + imklog_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) imklog_la_LDFLAGS = -module -avoid-version imklog_la_LIBADD = -- cgit From b0a4df43e4434a1eeb3f23c2c5a4b0cdd2fbddda Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Apr 2008 09:00:13 +0200 Subject: fixed build system for BSD It's a hack, but at least it works now - on BSD. Will check later if it is fine on Linux, too. Any better method of doing things is happily accepted ;) --- plugins/imklog/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 946576fe..511cd9be 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -1,13 +1,13 @@ pkglib_LTLIBRARIES = imklog.la -imklog_la_SOURCES = imklog.c imklog.h module.h ksym.c ksyms.h ksym_mod.c +imklog_la_SOURCES = imklog.c imklog.h # select klog "driver" -if ENABLE_IMKLOG_LINUX -imklog_la_SOURCES += linux.c -endif if ENABLE_IMKLOG_BSD imklog_la_SOURCES += bsd.c +else +# we assume this now is Linux (yes, some help with the build system is appreciated ;)) +imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c endif imklog_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) -- cgit From 0b447f310ac057ba59f0238f5bd663c993a823c2 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Apr 2008 09:06:40 +0200 Subject: implemented klog driver for BSD --- plugins/imklog/bsd.c | 107 ++++++++++++++++++++++++++++-------------------- plugins/imklog/imklog.c | 7 ++-- plugins/imklog/imklog.h | 2 +- plugins/imklog/linux.c | 3 +- 4 files changed, 68 insertions(+), 51 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index 25391980..c1595669 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -64,21 +64,47 @@ * the GPLv3+ as specified above. */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include -/* open the kernel log -- rger */ -static void openKLog(void) +#include "rsyslog.h" +#include "imklog.h" + +/* globals */ +static int fklog = -1; /* /dev/klog */ + +#ifndef _PATH_KLOG +# define _PATH_KLOG "/dev/klog" +#endif + +/* open the kernel log - will be called inside the willRun() imklog + * entry point. -- rgerhards, 20080-04-09 + */ +rsRetVal +klogWillRun(void) { - if ((fklog = open(_PATH_KLOG, O_RDONLY, 0)) >= 0) - if (fcntl(fklog, F_SETFL, O_NONBLOCK) < 0) - fklog = -1; - if (fklog < 0) - dprintf("can't open %s (%d)\n", _PATH_KLOG, errno); + DEFiRet; + + fklog = open(_PATH_KLOG, O_RDONLY, 0); + if (fklog < 0) { + dbgprintf("can't open %s (%d)\n", _PATH_KLOG, errno); + iRet = RS_RET_ERR; // TODO: better error code + } + + RETiRet; } -static int fklog = -1; /* /dev/klog */ -/* - * Read /dev/klog while data are available, split into lines. +/* 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) @@ -88,12 +114,15 @@ readklog(void) len = 0; for (;;) { + dbgprintf("----------imklog waiting for kernel log line\n"); i = read(fklog, line + len, MAXLINE - 1 - len); if (i > 0) { line[i + len] = '\0'; } else { if (i < 0 && errno != EINTR && errno != EAGAIN) { - logerror("klog"); + Syslog(LOG_ERR, + "imklog error %d reading kernel log - shutting down imklog", + errno); fklog = -1; } break; @@ -101,51 +130,41 @@ readklog(void) for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) { *q = '\0'; - printsys(p); + Syslog(LOG_INFO, "%s", p); } len = strlen(p); if (len >= MAXLINE - 1) { - printsys(p); + Syslog(LOG_INFO, "%s", p); len = 0; } if (len > 0) memmove(line, p, len + 1); } if (len > 0) - printsys(line); + Syslog(LOG_INFO, "%s", line); } -/* - * Take a raw input line from /dev/klog, format similar to syslog(). + +/* to be called in the module's AfterRun entry point + * rgerhards, 2008-04-09 */ -static void -printsys(char *msg) +rsRetVal klogAfterRun(void) { - char *p, *q; - long n; - int flags, isprintf, pri; - - flags = ISKERNEL | SYNC_FILE | ADDDATE; /* fsync after write */ - p = msg; - pri = DEFSPRI; - isprintf = 1; - if (*p == '<') { - errno = 0; - n = strtol(p + 1, &q, 10); - if (*q == '>' && n >= 0 && n < INT_MAX && errno == 0) { - p = q + 1; - pri = n; - isprintf = 0; - } - } - /* - * Kernel printf's and LOG_CONSOLE messages have been displayed - * on the console already. - */ - if (isprintf || (pri & LOG_FACMASK) == LOG_CONSOLE) - flags |= IGN_CONS; - if (pri &~ (LOG_FACMASK|LOG_PRIMASK)) - pri = DEFSPRI; - logmsg(pri, p, LocalHostName, flags); + DEFiRet; + if(fklog != -1) + close(fklog); + RETiRet; } + + +/* to be called in the module's WillRun entry point, this is the main + * "message pull" mechanism. + * rgerhards, 2008-04-09 + */ +rsRetVal klogLogKMsg(void) +{ + DEFiRet; + readklog(); + RETiRet; +} diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 972e93db..7f5c3cec 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -142,13 +142,12 @@ rsRetVal Syslog(int priority, char *fmt, ...) va_list ap; char *argl; - /* Output using syslog. */ + /* Output using syslog */ if(!strcmp(fmt, "%s")) { va_start(ap, fmt); argl = va_arg(ap, char *); - if (argl[0] == '<' && argl[1] && argl[2] == '>') { - switch ( argl[1] ) - { + if(argl[0] == '<' && argl[1] && argl[2] == '>') { + switch(argl[1]) { case '0': priority = LOG_EMERG; break; diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h index 0ac25d6c..2fea879f 100644 --- a/plugins/imklog/imklog.h +++ b/plugins/imklog/imklog.h @@ -59,7 +59,7 @@ extern int InitMsyms(void); extern void DeinitMsyms(void); extern char * ExpandKadds(char *, char *); extern void SetParanoiaLevel(int); -extern void vsyslog(int pri, const char *fmt, va_list ap); +//TODO: remove? extern void vsyslog(int pri, const char *fmt, va_list ap); rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); #endif /* #ifndef IMKLOG_H_INCLUDED */ diff --git a/plugins/imklog/linux.c b/plugins/imklog/linux.c index ce2ef4eb..dc669b15 100644 --- a/plugins/imklog/linux.c +++ b/plugins/imklog/linux.c @@ -154,8 +154,7 @@ static enum LOGSRC GetKernelLogSrc(void) return(none); } - Syslog(LOG_INFO, "imklog %s, log source = %s started.", \ - VERSION, _PATH_KLOG); + Syslog(LOG_INFO, "imklog %s, log source = %s started.", VERSION, _PATH_KLOG); return(proc); } -- cgit From cac432e7cb65ea4694a183823267cbcd67e97ad6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 10 Apr 2008 09:52:37 +0200 Subject: Add missing include bsd.c uses strchr, strlen and memmove, so include string.h Signed-off-by: Rainer Gerhards --- plugins/imklog/bsd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index c1595669..9989d5fb 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -71,6 +71,7 @@ #include #include #include +#include #include "rsyslog.h" #include "imklog.h" -- cgit From f786054cdc128f69fcf5deea191c01de77bd1342 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 10 Apr 2008 09:56:19 +0200 Subject: Add ENABLE_IMKLOG_LINUX Signed-off-by: Rainer Gerhards --- plugins/imklog/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 511cd9be..f4cd771b 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -5,8 +5,9 @@ imklog_la_SOURCES = imklog.c imklog.h # select klog "driver" if ENABLE_IMKLOG_BSD imklog_la_SOURCES += bsd.c -else -# we assume this now is Linux (yes, some help with the build system is appreciated ;)) +endif + +if ENABLE_IMKLOG_LINUX imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c endif -- cgit From d041cdd05007593624b83df85c4fe0357d330c10 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 10 Apr 2008 12:16:05 +0200 Subject: removed trailing whitespace --- plugins/imklog/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index f4cd771b..246b3306 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -7,7 +7,7 @@ if ENABLE_IMKLOG_BSD imklog_la_SOURCES += bsd.c endif -if ENABLE_IMKLOG_LINUX +if ENABLE_IMKLOG_LINUX imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c endif -- cgit From 9030b96c7b0b1b44915ff13384bc2ccbeeaf0626 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sat, 12 Apr 2008 16:55:04 +0200 Subject: implemented high precision timestamps for the kernel log. Thanks to Michael Biebl for pointing out that the kernel log did not have them. --- plugins/imfile/imfile.c | 3 ++ plugins/imklog/imklog.c | 77 ++++++++++++++++++++++--------------------------- 2 files changed, 38 insertions(+), 42 deletions(-) (limited to 'plugins') diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c index 162cab9f..54669641 100644 --- a/plugins/imfile/imfile.c +++ b/plugins/imfile/imfile.c @@ -379,6 +379,9 @@ ENDafterRun */ BEGINmodExit CODESTARTmodExit + /* release objects we used */ + objRelease(datetime, CORE_COMPONENT); + objRelease(errmsg, CORE_COMPONENT); ENDmodExit diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 7f5c3cec..754d655d 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -45,17 +45,23 @@ #include #include #include +#include +#include + #include "syslogd.h" #include "cfsysline.h" #include "template.h" +#include "obj.h" #include "msg.h" #include "module-template.h" +#include "datetime.h" #include "imklog.h" MODULE_TYPE_INPUT /* Module static data */ DEF_IMOD_STATIC_DATA +DEFobjCurrIf(datetime) /* configuration settings TODO: move to instance data? */ int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */ @@ -82,58 +88,39 @@ int console_log_level = -1; # include #endif -#include -#include - #define __LIBRARY__ #include - -/* Write a message to the message queue. - * returns -1 if it fails, something else otherwise +/* enqueue the the kernel message into the message queue. + * The provided msg string is not freed - thus must be done + * by the caller. + * rgerhards, 2008-04-12 */ -static rsRetVal writeSyslogV(int iPRI, const char *szFmt, va_list va) +static rsRetVal enqMsg(uchar *msg, int iFacility, int iSeverity) { DEFiRet; - int iChars; - int iLen; - time_t tNow; - char msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ - - assert(szFmt != NULL); - - /* build the message */ - time(&tNow); - /* we can use sprintf safely below, because we know the size of the constants. - * By doing so, we save some cpu cycles and code complexity (for unnecessary - * error checking). - */ - iLen = sprintf(msgBuf, "<%d>%.15s kernel: ", iPRI, ctime(&tNow) + 4); - - iChars = vsnprintf(msgBuf + iLen, sizeof(msgBuf) / sizeof(char) - iLen, szFmt, va); - - /* here we must create our message object and supply it to the message queue - */ - CHKiRet(parseAndSubmitMessage(LocalHostName, msgBuf, strlen(msgBuf), MSG_DONT_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_LIGHT_DELAY)); + msg_t *pMsg; + + assert(msg != NULL); + + CHKiRet(msgConstruct(&pMsg)); + MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); + MsgSetUxTradMsg(pMsg, (char*)msg); + MsgSetRawMsg(pMsg, (char*)msg); + MsgSetMSG(pMsg, (char*)msg); + MsgSetHOSTNAME(pMsg, LocalHostName); + MsgSetTAG(pMsg, "kernel:"); + pMsg->iFacility = LOG_FAC(iFacility); + pMsg->iSeverity = LOG_PRI(iSeverity); + pMsg->bParseHOSTNAME = 0; + datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */ + CHKiRet(submitMsg(pMsg)); finalize_it: RETiRet; } -/* And now the same with variable arguments */ -static int writeSyslog(int iPRI, const char *szFmt, ...) -{ - int iRet; - va_list va; - - assert(szFmt != NULL); - va_start(va, szFmt); - iRet = writeSyslogV(iPRI, szFmt, va); - va_end(va); - - return(iRet); -} rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); rsRetVal Syslog(int priority, char *fmt, ...) @@ -141,6 +128,7 @@ rsRetVal Syslog(int priority, char *fmt, ...) DEFiRet; va_list ap; char *argl; + char msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ /* Output using syslog */ if(!strcmp(fmt, "%s")) { @@ -175,12 +163,13 @@ rsRetVal Syslog(int priority, char *fmt, ...) } argl += 3; } - iRet = writeSyslog(priority, fmt, argl); + iRet = enqMsg((uchar*)argl, LOG_KERN, priority); va_end(ap); } else { va_start(ap, fmt); - iRet = writeSyslogV(priority, fmt, ap); + vsnprintf(msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap); va_end(ap); + iRet = enqMsg((uchar*)msgBuf, LOG_KERN, priority); } RETiRet; @@ -218,6 +207,8 @@ ENDafterRun BEGINmodExit CODESTARTmodExit + /* release objects we used */ + objRelease(datetime, CORE_COMPONENT); ENDmodExit @@ -240,6 +231,8 @@ BEGINmodInit() CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(datetime, CORE_COMPONENT)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrBinary, NULL, &dbgPrintSymbols, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary, NULL, &symbol_lookup, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary, NULL, &symbols_twice, STD_LOADABLE_MODULE_ID)); -- cgit From 3669057997e7665735626fd29a40bd10e160c88f Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 14 Apr 2008 12:10:00 +0200 Subject: provided ability to discard non-kernel messages present in the kernel msg buffer This obviously happens on BSD (<118> markers seen). We now have the ability to allow or prevent it, with the default being not permitted. Should not at all affect other drivers, but it is implemented on a common code basis, not on the driver layer. --- plugins/imklog/bsd.c | 2 +- plugins/imklog/imklog.c | 95 ++++++++++++++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 37 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index 9989d5fb..c12103f3 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -84,7 +84,7 @@ static int fklog = -1; /* /dev/klog */ #endif /* open the kernel log - will be called inside the willRun() imklog - * entry point. -- rgerhards, 20080-04-09 + * entry point. -- rgerhards, 2008-04-09 */ rsRetVal klogWillRun(void) diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 754d655d..a5832658 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "syslogd.h" #include "cfsysline.h" @@ -68,6 +69,7 @@ int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */ int symbols_twice = 0; int use_syscall = 0; int symbol_lookup = 1; +int bPermitNonKernel = 0; /* permit logging of messages not having LOG_KERN facility */ /* TODO: configuration for the following directives must be implemented. It * was not done yet because we either do not yet have a config handler for * that type or I thought it was acceptable to push it to a later stage when @@ -121,57 +123,77 @@ finalize_it: RETiRet; } +/* parse the PRI from a kernel message. At least BSD seems to have + * non-kernel messages inside the kernel log... + * Expected format: "". piPri is only valid if the function + * successfully returns. If there was a proper pri ppSz is advanced to the + * position right after ">". + * rgerhards, 2008-04-14 + */ +static rsRetVal +parsePRI(uchar **ppSz, int *piPri) +{ + DEFiRet; + int i; + uchar *pSz; + + assert(ppSz != NULL); + pSz = *ppSz; + assert(pSz != NULL); + assert(piPri != NULL); + + if(*pSz != '<' || !isdigit(*(pSz+1))) + ABORT_FINALIZE(RS_RET_INVALID_PRI); + + ++pSz; + i = 0; + while(isdigit(*pSz)) { + i = i * 10 + *pSz - '0'; + } + + if(*pSz != '>') + ABORT_FINALIZE(RS_RET_INVALID_PRI); + + /* OK, we have a valid PRI */ + *piPri = i; + +finalize_it: + RETiRet; +} + rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); rsRetVal Syslog(int priority, char *fmt, ...) { DEFiRet; va_list ap; - char *argl; - char msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ + uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ + uchar *pLogMsg; + rsRetVal localRet; /* Output using syslog */ if(!strcmp(fmt, "%s")) { va_start(ap, fmt); - argl = va_arg(ap, char *); - if(argl[0] == '<' && argl[1] && argl[2] == '>') { - switch(argl[1]) { - case '0': - priority = LOG_EMERG; - break; - case '1': - priority = LOG_ALERT; - break; - case '2': - priority = LOG_CRIT; - break; - case '3': - priority = LOG_ERR; - break; - case '4': - priority = LOG_WARNING; - break; - case '5': - priority = LOG_NOTICE; - break; - case '6': - priority = LOG_INFO; - break; - case '7': - default: - priority = LOG_DEBUG; - } - argl += 3; - } - iRet = enqMsg((uchar*)argl, LOG_KERN, priority); + pLogMsg = va_arg(ap, uchar *); + localRet = parsePRI(&pLogMsg, &priority); + if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK) + FINALIZE; + /* if we don't get the pri, we use whatever we were supplied */ va_end(ap); - } else { + } else { /* TODO: I think we can remove this once we pull in the errmsg object -- rgerhards, 2008-04-14 */ va_start(ap, fmt); - vsnprintf(msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap); + vsnprintf((char*)msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap); + pLogMsg = msgBuf; va_end(ap); - iRet = enqMsg((uchar*)msgBuf, LOG_KERN, priority); } + /* ignore non-kernel messages if not permitted */ + if(bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN) + FINALIZE; /* silently ignore */ + + iRet = enqMsg((uchar*)pLogMsg, LOG_FAC(priority), LOG_PRI(priority)); + +finalize_it: RETiRet; } @@ -237,6 +259,7 @@ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary, NULL, &symbol_lookup, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary, NULL, &symbols_twice, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary, NULL, &use_syscall, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary, NULL, &bPermitNonKernel, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vim:set ai: -- cgit From f8dff16a4a1d606f41d738f7381649282c74ca25 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 14 Apr 2008 14:44:32 +0200 Subject: cleanup of imklog + addtl. config directives - implemented $KLogInternalMsgFacility config directive - implemented $KLogPermitNonKernelFacility config directive - modified internal interfaces --- plugins/imklog/bsd.c | 18 ++++++++--- plugins/imklog/imklog.c | 76 +++++++++++++++++++++++------------------------ plugins/imklog/imklog.h | 7 +++-- plugins/imklog/ksym.c | 32 ++++++++++---------- plugins/imklog/ksym_mod.c | 12 ++++---- plugins/imklog/linux.c | 46 +++++++++++++++++----------- 6 files changed, 108 insertions(+), 83 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index c12103f3..c5b79541 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -121,7 +121,7 @@ readklog(void) line[i + len] = '\0'; } else { if (i < 0 && errno != EINTR && errno != EAGAIN) { - Syslog(LOG_ERR, + imklogLogIntMsg(LOG_ERR, "imklog error %d reading kernel log - shutting down imklog", errno); fklog = -1; @@ -131,18 +131,18 @@ readklog(void) for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) { *q = '\0'; - Syslog(LOG_INFO, "%s", p); + Syslog(LOG_INFO, p); } len = strlen(p); if (len >= MAXLINE - 1) { - Syslog(LOG_INFO, "%s", p); + Syslog(LOG_INFO, p); len = 0; } if (len > 0) memmove(line, p, len + 1); } if (len > 0) - Syslog(LOG_INFO, "%s", line); + Syslog(LOG_INFO, line); } @@ -169,3 +169,13 @@ rsRetVal klogLogKMsg(void) readklog(); RETiRet; } + + +/* provide the (system-specific) default facility for internal messages + * rgerhards, 2008-04-14 + */ +int +klogFacilIntMsg(void) +{ + return LOG_SYSLOG; +} diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index a5832658..e6bd2326 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -39,19 +39,14 @@ */ #include "config.h" #include "rsyslog.h" -#include #include #include -#include #include -#include #include -#include #include #include "syslogd.h" #include "cfsysline.h" -#include "template.h" #include "obj.h" #include "msg.h" #include "module-template.h" @@ -70,6 +65,7 @@ int symbols_twice = 0; int use_syscall = 0; int symbol_lookup = 1; int bPermitNonKernel = 0; /* permit logging of messages not having LOG_KERN facility */ +int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ /* TODO: configuration for the following directives must be implemented. It * was not done yet because we either do not yet have a config handler for * that type or I thought it was acceptable to push it to a later stage when @@ -80,31 +76,19 @@ char *symfile = NULL; int console_log_level = -1; -/* Includes. */ -#include -#include -#include -#include - -#if HAVE_TIME_H -# include -#endif - -#define __LIBRARY__ -#include - - /* enqueue the the kernel message into the message queue. * The provided msg string is not freed - thus must be done * by the caller. * rgerhards, 2008-04-12 */ -static rsRetVal enqMsg(uchar *msg, int iFacility, int iSeverity) +static rsRetVal +enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity) { DEFiRet; msg_t *pMsg; assert(msg != NULL); + assert(pszTag != NULL); CHKiRet(msgConstruct(&pMsg)); MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY); @@ -112,7 +96,7 @@ static rsRetVal enqMsg(uchar *msg, int iFacility, int iSeverity) MsgSetRawMsg(pMsg, (char*)msg); MsgSetMSG(pMsg, (char*)msg); MsgSetHOSTNAME(pMsg, LocalHostName); - MsgSetTAG(pMsg, "kernel:"); + MsgSetTAG(pMsg, (char*)pszTag); pMsg->iFacility = LOG_FAC(iFacility); pMsg->iSeverity = LOG_PRI(iSeverity); pMsg->bParseHOSTNAME = 0; @@ -162,36 +146,47 @@ finalize_it: } -rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); -rsRetVal Syslog(int priority, char *fmt, ...) +/* log an imklog-internal message + * rgerhards, 2008-04-14 + */ +rsRetVal imklogLogIntMsg(int priority, char *fmt, ...) { DEFiRet; va_list ap; uchar msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */ uchar *pLogMsg; + + va_start(ap, fmt); + vsnprintf((char*)msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap); + pLogMsg = msgBuf; + va_end(ap); + + iRet = enqMsg((uchar*)pLogMsg, (uchar*) ((iFacilIntMsg == LOG_KERN) ? "kernel:" : "imklog:"), + iFacilIntMsg, LOG_PRI(priority)); + + RETiRet; +} + + +/* log a kernel message + * rgerhards, 2008-04-14 + */ +rsRetVal Syslog(int priority, uchar *pMsg) +{ + DEFiRet; rsRetVal localRet; /* Output using syslog */ - if(!strcmp(fmt, "%s")) { - va_start(ap, fmt); - pLogMsg = va_arg(ap, uchar *); - localRet = parsePRI(&pLogMsg, &priority); - if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK) - FINALIZE; - /* if we don't get the pri, we use whatever we were supplied */ - va_end(ap); - } else { /* TODO: I think we can remove this once we pull in the errmsg object -- rgerhards, 2008-04-14 */ - va_start(ap, fmt); - vsnprintf((char*)msgBuf, sizeof(msgBuf) / sizeof(char), fmt, ap); - pLogMsg = msgBuf; - va_end(ap); - } + localRet = parsePRI(&pMsg, &priority); + if(localRet != RS_RET_INVALID_PRI && localRet != RS_RET_OK) + FINALIZE; + /* if we don't get the pri, we use whatever we were supplied */ /* ignore non-kernel messages if not permitted */ if(bPermitNonKernel == 0 && LOG_FAC(priority) != LOG_KERN) FINALIZE; /* silently ignore */ - iRet = enqMsg((uchar*)pLogMsg, LOG_FAC(priority), LOG_PRI(priority)); + iRet = enqMsg((uchar*)pMsg, (uchar*) "kernel:", LOG_FAC(priority), LOG_PRI(priority)); finalize_it: RETiRet; @@ -246,6 +241,8 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a use_syscall = 0; symfile = NULL; symbol_lookup = 1; + bPermitNonKernel = 0; + iFacilIntMsg = klogFacilIntMsg(); return RS_RET_OK; } @@ -255,11 +252,14 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(datetime, CORE_COMPONENT)); + iFacilIntMsg = klogFacilIntMsg(); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"debugprintkernelsymbols", 0, eCmdHdlrBinary, NULL, &dbgPrintSymbols, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbollookup", 0, eCmdHdlrBinary, NULL, &symbol_lookup, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogsymbolstwice", 0, eCmdHdlrBinary, NULL, &symbols_twice, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogusesyscallinterface", 0, eCmdHdlrBinary, NULL, &use_syscall, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"klogpermitnonkernelfacility", 0, eCmdHdlrBinary, NULL, &bPermitNonKernel, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility, NULL, &iFacilIntMsg, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit /* vim:set ai: diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h index 2fea879f..a37ecc9e 100644 --- a/plugins/imklog/imklog.h +++ b/plugins/imklog/imklog.h @@ -39,6 +39,7 @@ rsRetVal klogLogKMsg(void); rsRetVal klogWillRun(void); rsRetVal klogAfterRun(void); +int klogFacilIntMsg(void); /* the following data members may be accessed by the "drivers" * I admit this is not the cleanest way to doing things, but I honestly @@ -52,6 +53,10 @@ extern char *symfile; extern int console_log_level; extern int dbgPrintSymbols; +/* the functions below may be called by the drivers */ +rsRetVal imklogLogIntMsg(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); +rsRetVal Syslog(int priority, uchar *msg); + /* prototypes */ extern int InitKsyms(char *); extern void DeinitKsyms(void); @@ -59,8 +64,6 @@ extern int InitMsyms(void); extern void DeinitMsyms(void); extern char * ExpandKadds(char *, char *); extern void SetParanoiaLevel(int); -//TODO: remove? extern void vsyslog(int pri, const char *fmt, va_list ap); -rsRetVal Syslog(int priority, char *fmt, ...) __attribute__((format(printf,2, 3))); #endif /* #ifndef IMKLOG_H_INCLUDED */ /* vi:set ai: diff --git a/plugins/imklog/ksym.c b/plugins/imklog/ksym.c index 716ad926..1c2af124 100644 --- a/plugins/imklog/ksym.c +++ b/plugins/imklog/ksym.c @@ -185,18 +185,18 @@ extern int InitKsyms(char *mapfile) if ( mapfile != (char *) 0 ) { if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 ) { - Syslog(LOG_WARNING, "Cannot open map file: %s.", mapfile); + imklogLogIntMsg(LOG_WARNING, "Cannot open map file: %s.", mapfile); return(0); } } else { if ( (mapfile = FindSymbolFile()) == (char *) 0 ) { - Syslog(LOG_WARNING, "Cannot find map file."); + imklogLogIntMsg(LOG_WARNING, "Cannot find map file."); dbgprintf("Cannot find map file.\n"); return(0); } if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 ) { - Syslog(LOG_WARNING, "Cannot open map file."); + imklogLogIntMsg(LOG_WARNING, "Cannot open map file."); dbgprintf("Cannot open map file.\n"); return(0); } @@ -213,7 +213,7 @@ extern int InitKsyms(char *mapfile) */ while ( !feof(sym_file) ) { if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym) != 3 ) { - Syslog(LOG_ERR, "Error in symbol table input (#1)."); + imklogLogIntMsg(LOG_ERR, "Error in symbol table input (#1)."); fclose(sym_file); return(0); } @@ -221,7 +221,7 @@ extern int InitKsyms(char *mapfile) dbgprintf("Address: %lx, Type: %c, Symbol: %s\n", address, type, sym); if ( AddSymbol(address, sym) == 0 ) { - Syslog(LOG_ERR, "Error adding symbol - %s.", sym); + imklogLogIntMsg(LOG_ERR, "Error adding symbol - %s.", sym); fclose(sym_file); return(0); } @@ -231,19 +231,19 @@ extern int InitKsyms(char *mapfile) } - Syslog(LOG_INFO, "Loaded %d symbols from %s.", num_syms, mapfile); + imklogLogIntMsg(LOG_INFO, "Loaded %d symbols from %s.", num_syms, mapfile); switch(version) { case -1: - Syslog(LOG_WARNING, "Symbols do not match kernel version."); + imklogLogIntMsg(LOG_WARNING, "Symbols do not match kernel version."); num_syms = 0; break; case 0: - Syslog(LOG_WARNING, "Cannot verify that symbols match kernel version."); + imklogLogIntMsg(LOG_WARNING, "Cannot verify that symbols match kernel version."); break; case 1: - Syslog(LOG_INFO, "Symbols match kernel version %s.", vstring); + imklogLogIntMsg(LOG_INFO, "Symbols match kernel version %s.", vstring); break; } @@ -301,7 +301,7 @@ static char *FindSymbolFile(void) auto FILE *sym_file = (FILE *) 0; if ( uname(&utsname) < 0 ) { - Syslog(LOG_ERR, "Cannot get kernel version information."); + imklogLogIntMsg(LOG_ERR, "Cannot get kernel version information."); return(0); } @@ -410,13 +410,13 @@ static int CheckVersion(char *version) * version level. */ if ( uname(&utsname) < 0 ) { - Syslog(LOG_ERR, "Cannot get kernel version information."); + imklogLogIntMsg(LOG_ERR, "Cannot get kernel version information."); return(0); } dbgprintf("Comparing kernel %s with symbol table %s.\n", utsname.release, vstring); if ( sscanf (utsname.release, "%d.%d.%d", &major, &minor, &patch) < 3 ) { - Syslog(LOG_ERR, "Kernel send bogus release string `%s'.", utsname.release); + imklogLogIntMsg(LOG_ERR, "Kernel send bogus release string `%s'.", utsname.release); return(0); } @@ -470,12 +470,12 @@ static int CheckMapVersion(char *fname) * now need to search this file and look for version * information. */ - Syslog(LOG_INFO, "Inspecting %s", fname); + imklogLogIntMsg(LOG_INFO, "Inspecting %s", fname); version = 0; while ( !feof(sym_file) && (version == 0) ) { if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym) != 3 ) { - Syslog(LOG_ERR, "Error in symbol table input (#2)."); + imklogLogIntMsg(LOG_ERR, "Error in symbol table input (#2)."); fclose(sym_file); return(0); } @@ -487,7 +487,7 @@ static int CheckMapVersion(char *fname) switch ( version ) { case -1: - Syslog(LOG_ERR, "Symbol table has incorrect version number.\n"); + imklogLogIntMsg(LOG_ERR, "Symbol table has incorrect version number.\n"); break; case 0: dbgprintf("No version information found.\n"); @@ -684,7 +684,7 @@ extern char *ExpandKadds(char *line, char *el) */ if ( i_am_paranoid && (strstr(line, "Oops:") != (char *) 0) && !InitMsyms() ) - Syslog(LOG_WARNING, "Cannot load kernel module symbols.\n"); + imklogLogIntMsg(LOG_WARNING, "Cannot load kernel module symbols.\n"); /* diff --git a/plugins/imklog/ksym_mod.c b/plugins/imklog/ksym_mod.c index 11535a5f..bef810b4 100644 --- a/plugins/imklog/ksym_mod.c +++ b/plugins/imklog/ksym_mod.c @@ -158,10 +158,10 @@ extern int InitMsyms(void) if ( ksyms == NULL ) { if ( errno == ENOENT ) - Syslog(LOG_INFO, "No module symbols loaded - " + imklogLogIntMsg(LOG_INFO, "No module symbols loaded - " "kernel modules not enabled.\n"); else - Syslog(LOG_ERR, "Error loading kernel symbols " \ + imklogLogIntMsg(LOG_ERR, "Error loading kernel symbols " \ "- %s\n", strerror(errno)); fclose(ksyms); return(0); @@ -201,9 +201,9 @@ extern int InitMsyms(void) } if ( rtn == 0 ) - Syslog(LOG_INFO, "No module symbols loaded."); + imklogLogIntMsg(LOG_INFO, "No module symbols loaded."); else - Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \ + imklogLogIntMsg(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \ (rtn == 1) ? "symbol" : "symbols", \ num_modules, (num_modules == 1) ? "." : "s."); @@ -296,7 +296,7 @@ struct Module *AddModule(module) if ( sym_array_modules == NULL ) { - Syslog(LOG_WARNING, "Cannot allocate Module array.\n"); + imklogLogIntMsg(LOG_WARNING, "Cannot allocate Module array.\n"); return NULL; } mp = sym_array_modules; @@ -308,7 +308,7 @@ struct Module *AddModule(module) if ( mp == NULL ) { - Syslog(LOG_WARNING, "Cannot allocate Module array.\n"); + imklogLogIntMsg(LOG_WARNING, "Cannot allocate Module array.\n"); return NULL; } diff --git a/plugins/imklog/linux.c b/plugins/imklog/linux.c index dc669b15..a742a456 100644 --- a/plugins/imklog/linux.c +++ b/plugins/imklog/linux.c @@ -98,11 +98,11 @@ static void CloseLogSrc(void) { case kernel: ksyslog(0, 0, 0); - Syslog(LOG_INFO, "Kernel logging (ksyslog) stopped."); + imklogLogIntMsg(LOG_INFO, "Kernel logging (ksyslog) stopped."); break; case proc: close(kmsg); - Syslog(LOG_INFO, "Kernel logging (proc) stopped."); + imklogLogIntMsg(LOG_INFO, "Kernel logging (proc) stopped."); break; case none: break; @@ -127,7 +127,7 @@ static enum LOGSRC GetKernelLogSrc(void) * issue an error message and simply shut-off console * logging completely. */ - Syslog(LOG_WARNING, "Cannot set console log level - disabling " + imklogLogIntMsg(LOG_WARNING, "Cannot set console log level - disabling " "console output."); } @@ -140,7 +140,7 @@ static enum LOGSRC GetKernelLogSrc(void) { /* Initialize kernel logging. */ ksyslog(1, NULL, 0); - Syslog(LOG_INFO, "imklogd %s, log source = ksyslog " + imklogLogIntMsg(LOG_INFO, "imklogd %s, log source = ksyslog " "started.", VERSION); return(kernel); } @@ -154,7 +154,7 @@ static enum LOGSRC GetKernelLogSrc(void) return(none); } - Syslog(LOG_INFO, "imklog %s, log source = %s started.", VERSION, _PATH_KLOG); + imklogLogIntMsg(LOG_INFO, "imklog %s, log source = %s started.", VERSION, _PATH_KLOG); return(proc); } @@ -165,7 +165,7 @@ static enum LOGSRC GetKernelLogSrc(void) * * Returns the actual number of chars copied. */ -static int copyin( char *line, int space, +static int copyin( uchar *line, int space, const char *ptr, int len, const char *delim ) { @@ -209,13 +209,13 @@ static void LogLine(char *ptr, int len) PARSING_SYMEND /* at ] */ }; - static char line_buff[LOG_LINE_LENGTH]; + static uchar line_buff[LOG_LINE_LENGTH]; - static char *line =line_buff; + static uchar *line =line_buff; static enum parse_state_enum parse_state = PARSING_TEXT; - static int space = sizeof(line_buff)-1; + static int space = sizeof(line_buff)-1; - static char *sym_start; /* points at the '<' of a symbol */ + 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 */ @@ -235,7 +235,7 @@ static void LogLine(char *ptr, int len) dbgprintf("Line buffer full:\n"); dbgprintf("\tLine: %s\n", line); - Syslog( LOG_INFO, "%s", line_buff ); + Syslog(LOG_INFO, line_buff); line = line_buff; space = sizeof(line_buff)-1; parse_state = PARSING_TEXT; @@ -248,7 +248,7 @@ static void LogLine(char *ptr, int len) switch( parse_state ) { case PARSING_TEXT: - delta = copyin( line, space, ptr, len, "\n[" ); + delta = copyin(line, space, ptr, len, "\n[" ); line += delta; ptr += delta; space -= delta; @@ -275,7 +275,7 @@ static void LogLine(char *ptr, int len) len -= 1; *line = 0; /* force null terminator */ - Syslog( LOG_INFO, "%s", line_buff ); + Syslog(LOG_INFO, line_buff); line = line_buff; space = sizeof(line_buff)-1; if (symbols_twice) { @@ -373,7 +373,7 @@ static void LogLine(char *ptr, int len) auto char *symbol; *(line-1) = 0; /* null terminate the address string */ - value = strtoul(sym_start+1, (char **) 0, 16); + value = strtoul((char*)(sym_start+1), (char **) 0, 16); *(line-1) = '>'; /* put back delim */ if ( !symbol_lookup || (symbol = LookupSymbol(value, &sym)) == (char *)0 ) @@ -392,7 +392,8 @@ static void LogLine(char *ptr, int len) break; } - delta = sprintf( sym_start, "%s+%d/%d]", + // TODO: sprintf!!!! + delta = sprintf( (char*) sym_start, "%s+%d/%d]", symbol, sym.offset, sym.size ); space = sym_space + delta; @@ -453,7 +454,7 @@ static void LogProcLine(void) if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 ) { if ( errno == EINTR ) return; - Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", errno, strerror(errno)); + imklogLogIntMsg(LOG_ERR, "Cannot read proc file system: %d - %s.", errno, strerror(errno)); } else { LogLine(log_buffer, rdcnt); } @@ -503,7 +504,7 @@ rsRetVal klogWillRun(void) symbol_lookup = (InitKsyms(symfile) == 1); symbol_lookup |= InitMsyms(); if (symbol_lookup == 0) { - Syslog(LOG_WARNING, "cannot find any symbols, turning off symbol lookups\n"); + imklogLogIntMsg(LOG_WARNING, "cannot find any symbols, turning off symbol lookups\n"); } } } @@ -528,5 +529,16 @@ rsRetVal klogAfterRun(void) RETiRet; } + +/* provide the (system-specific) default facility for internal messages + * rgerhards, 2008-04-14 + */ +int +klogFacilIntMsg(void) +{ + return LOG_KERN; +} + + /* vi:set ai: */ -- cgit From 318be337dd7f3ce1c1a308712e308f5b56ce9027 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Mon, 14 Apr 2008 13:35:19 +0200 Subject: fix compiler warning on char/uchar --- plugins/imklog/bsd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index c5b79541..39b644c0 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -131,18 +131,18 @@ readklog(void) for (p = line; (q = strchr(p, '\n')) != NULL; p = q + 1) { *q = '\0'; - Syslog(LOG_INFO, p); + Syslog(LOG_INFO, (uchar*) p); } len = strlen(p); if (len >= MAXLINE - 1) { - Syslog(LOG_INFO, p); + Syslog(LOG_INFO, (uchar*)p); len = 0; } if (len > 0) memmove(line, p, len + 1); } if (len > 0) - Syslog(LOG_INFO, line); + Syslog(LOG_INFO, (uchar*)line); } -- cgit