diff options
37 files changed, 426 insertions, 307 deletions
@@ -1,4 +1,46 @@ ---------------------------------------------------------------------------- +Version 7.2.4 [v7-stable] 2012-12-07 +- enhance: permit RFC3339 timestamp in local log socket messages + Thanks to Sebastien Ponce for the patch. +- imklog: added ParseKernelTimestamp parameter (import from 5.10.2) + Thanks to Marius Tomaschewski for the patch. +- fix missing functionality: ruleset(){} could not specify ruleset queue + The "queue.xxx" parameter set was not supported, and legacy ruleset + config statements did not work (by intention). The fix introduces the + "queue.xxx" parameter set. It has some regression potential, but only + for the new functionality. Note that using that interface it is possible + to specify duplicate queue file names, which will cause trouble. This + will be solved in v7.3, because there is a too-large regression + potential for the v7.2 stable branch. +- imklog: added KeepKernelTimestamp parameter (import from 5.10.2) + Thanks to Marius Tomaschewski for the patch. +- bugfix: imklog mistakenly took kernel timestamp subseconds as nanoseconds + ... actually, they are microseconds. So the fractional part of the + timestamp was not properly formatted. (import from 5.10.2) + Thanks to Marius Tomaschewski for the bug report and the patch idea. +- bugfix: supportoctetcountedframing parameter did not work in imptcp +- bugfix: modules not (yet) supporting new conf format were not properly + registered. This lead to a "module not found" error message instead of + the to-be-expected "module does not support new style" error message. + That invalid error message could be quite misleading and actually stop + people from addressing the real problem (aka "go nuts" ;)) +- bugfix: template "type" parameter is mandatory (but was not) +- bugfix: some message properties could be garbled due to race condition + This happened only on very high volume systems, if the same message was + being processed by two different actions. This was a regression caused + by the new config processor, which did no longer properly enable msg + locking in multithreaded cases. The bugfix is actually a refactoring of + the msg locking code - we no longer do unlocked operations, as the use + case for it has mostly gone away. It is potentially possible only at + very low-end systems, and there the small additional overhead of doing + the locking does not really hurt. Instead, the removal of that + capability can actually slightly improve performance in common cases, + as the code path is smaller and requires slightly less memory writes. + That probably outperforms the extra locking overhead (which in the + low-end case always happens in user space, without need for kernel + support as we can always directly aquire the lock - there is no + contention at all). +---------------------------------------------------------------------------- Version 7.2.3 [v7-stable] 2012-10-21 - regression fix: rsyslogd terminated when wild-card $IncludeConfig did not find actual include files. For example, if this directive is present: @@ -90,12 +132,12 @@ Version 7.1.12 [beta] 2012-10-18 Thanks to Michael Biebl for reporting & suggestions - bugfix: imklog truncated head of received message This happened only under some circumstances. Thanks to Marius - Tomaschwesky and Florian Piekert for their help in solving this issue. + Tomaschewski and Florian Piekert for their help in solving this issue. ---------------------------------------------------------------------------- Version 7.1.11 [beta] 2012-10-16 - bugfix: imuxsock truncated head of received message This happened only under some circumstances. Thanks to Marius - Tomaschwesky, Florian Piekert and Milan Bartos for their help in + Tomaschewski, Florian Piekert and Milan Bartos for their help in solving this issue. - bugfix: do not crash if set statement is used with date field Thanks to Miloslav Trmač for the patch. @@ -227,6 +269,41 @@ Version 6.6.1 [v6-stable] 2012-10-?? closes: http://bugzilla.adiscon.com/show_bug.cgi?id=376 The testbench was also enhanced to check for these cases. Thanks to Georgi Georgiev for the bug report. +- bugfix: spurios error messages from imuxsock about (non-error) EAGAIN + Thanks to Marius Tomaschewski for the patch. +- imklog: added $klogParseKernelTimestamp option + When enabled, kernel message [timestamp] is converted for message time. + Default is to use receive time as in 5.8.x and before, because the clock + used to create the timestamp is not supposed to be as accurate as the + monotonic clock (depends on hardware and kernel) resulting in differences + between kernel and system messages which occurred at same time. + Thanks to Marius Tomaschewski for the patch. +- imklog: added $klogKeepKernelTimestamp option + When enabled, the kernel [timestamp] remains at begin of + each message, even it is used for the message time too. + Thanks to Marius Tomaschewski for the patch. +- bugfix: imklog mistakenly took kernel timestamp subseconds as nanoseconds + ... actually, they are microseconds. So the fractional part of the + timestamp was not properly formatted. + Thanks to Marius Tomaschewski for the bug report and the patch idea. +- bugfix: hostname set in rsyslog.conf was not picked up until HUP + which could also mean "never" or "not for a very long time". + Thanks to oxpa for providing analysis and a patch +- bugfix: some message properties could be garbled due to race condition + This happened only on very high volume systems, if the same message was + being processed by two different actions. This was a regression caused + by the new config processor, which did no longer properly enable msg + locking in multithreaded cases. The bugfix is actually a refactoring of + the msg locking code - we no longer do unlocked operations, as the use + case for it has mostly gone away. It is potentially possible only at + very low-end systems, and there the small additional overhead of doing + the locking does not really hurt. Instead, the removal of that + capability can actually slightly improve performance in common cases, + as the code path is smaller and requires slightly less memory writes. + That probably outperforms the extra locking overhead (which in the + low-end case always happens in user space, without need for kernel + support as we can always directly aquire the lock - there is no + contention at all). --------------------------------------------------------------------------- Version 6.6.0 [v6-stable] 2012-10-22 This starts a new stable branch, based on the 6.5.x series, plus: @@ -291,7 +368,7 @@ all these patches here are present in 6.6.0. Thanks to Michael Biebl for reporting & suggestions - bugfix: imuxsock and imklog truncated head of received message This happened only under some circumstances. Thanks to Marius - Tomaschwesky, Florian Piekert and Milan Bartos for their help in + Tomaschewski, Florian Piekert and Milan Bartos for their help in solving this issue. - change lumberjack cookie to "@cee:" from "@cee: " CEE originally specified the cookie with SP, whereas other lumberjack @@ -782,7 +859,7 @@ Version 6.1.4 [DEVEL] (rgerhards), 2011-02-18 has been changed so this can no longer happen. - added pmsnare parser module (written by David Lang) - enhanced imfile to support non-cancel input termination -- improved systemd socket activation thanks to Marius Tomaschweski +- improved systemd socket activation thanks to Marius Tomaschewski - improved error reporting for $WorkDirectory non-existance and other detectable problems are now reported, and the work directory is NOT set in this case @@ -876,12 +953,35 @@ expected that interfaces, even new ones, break during the initial --------------------------------------------------------------------------- Version 5.10.2 [V5-STABLE], 201?-??-?? - bugfix: spurios error messages from imuxsock about (non-error) EAGAIN - Thanks to Marius Tomaschwesky for the patch. + Thanks to Marius Tomaschewski for the patch. +- imklog: added $klogParseKernelTimestamp option + When enabled, kernel message [timestamp] is converted for message time. + Default is to use receive time as in 5.8.x and before, because the clock + used to create the timestamp is not supposed to be as accurate as the + monotonic clock (depends on hardware and kernel) resulting in differences + between kernel and system messages which occurred at same time. + Thanks to Marius Tomaschewski for the patch. +- imklog: added $klogKeepKernelTimestamp option + When enabled, the kernel [timestamp] remains at begin of + each message, even it is used for the message time too. + Thanks to Marius Tomaschewski for the patch. +- bugfix: imklog mistakenly took kernel timestamp subseconds as nanoseconds + ... actually, they are microseconds. So the fractional part of the + timestamp was not properly formatted. + Thanks to Marius Tomaschewski for the bug report and the patch idea. +- imklog: added $klogKeepKernelTimestamp option + When enabled, the kernel [timestamp] remains at begin of + each message, even it is used for the message time too. + Thanks to Marius Tomaschewski for the patch. +- bugfix: imklog mistakenly took kernel timestamp subseconds as nanoseconds + ... actually, they are microseconds. So the fractional part of the + timestamp was not properly formatted. + Thanks to Marius Tomaschewski for the bug report and the patch idea. --------------------------------------------------------------------------- Version 5.10.1 [V5-STABLE], 2012-10-17 - bugfix: imuxsock and imklog truncated head of received message This happened only under some circumstances. Thanks to Marius - Tomaschwesky, Florian Piekert and Milan Bartos for their help in + Tomaschewski, Florian Piekert and Milan Bartos for their help in solving this issue. - enable DNS resolution in imrelp Thanks to Apollon Oikonomopoulos for the patch @@ -1418,7 +1518,7 @@ Version 5.7.5 [V5-BETA] (rgerhards), 2011-02-23 Version 5.7.4 [V5-BETA] (rgerhards), 2011-02-17 - added pmsnare parser module (written by David Lang) - enhanced imfile to support non-cancel input termination -- improved systemd socket activation thanks to Marius Tomaschweski +- improved systemd socket activation thanks to Marius Tomaschewski - improved error reporting for $WorkDirectory non-existance and other detectable problems are now reported, and the work directory is NOT set in this case @@ -429,14 +429,6 @@ actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams) pThis->submitToActQ = doSubmitToActionQBatch; } - /* we need to make a safety check: if the queue is NOT in direct mode, a single - * message object may be accessed by multiple threads. As such, we need to enable - * msg object thread safety in this case (this costs a bit performance and thus - * is not enabled by default. -- rgerhards, 2008-02-20 - */ - if(cs.ActionQueType != QUEUETYPE_DIRECT) - MsgEnableThreadSafety(); - /* create queue */ /* action queues always (for now) have just one worker. This may change when * we begin to implement an interface the enable output modules to request @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for rsyslog 7.2.3. +# Generated by GNU Autoconf 2.67 for rsyslog 7.2.4. # # Report bugs to <rsyslog@lists.adiscon.com>. # @@ -701,8 +701,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rsyslog' PACKAGE_TARNAME='rsyslog' -PACKAGE_VERSION='7.2.3' -PACKAGE_STRING='rsyslog 7.2.3' +PACKAGE_VERSION='7.2.4' +PACKAGE_STRING='rsyslog 7.2.4' PACKAGE_BUGREPORT='rsyslog@lists.adiscon.com' PACKAGE_URL='' @@ -1684,7 +1684,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rsyslog 7.2.3 to adapt to many kinds of systems. +\`configure' configures rsyslog 7.2.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1754,7 +1754,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rsyslog 7.2.3:";; + short | recursive ) echo "Configuration of rsyslog 7.2.4:";; esac cat <<\_ACEOF @@ -1974,7 +1974,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rsyslog configure 7.2.3 +rsyslog configure 7.2.4 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2553,7 +2553,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rsyslog $as_me 7.2.3, which was +It was created by rsyslog $as_me 7.2.4, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -3368,7 +3368,7 @@ fi # Define the identity of the package. PACKAGE='rsyslog' - VERSION='7.2.3' + VERSION='7.2.4' cat >>confdefs.h <<_ACEOF @@ -18806,7 +18806,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rsyslog $as_me 7.2.3, which was +This file was extended by rsyslog $as_me 7.2.4, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18872,7 +18872,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -rsyslog config.status 7.2.3 +rsyslog config.status 7.2.4 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4e6827e..e1f7b37 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[7.2.3],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[7.2.4],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -32,7 +32,7 @@ rsRetVal submitMsg(msg_t *pMsg); rsRetVal logmsgInternal(int iErr, int pri, uchar *msg, int flags); rsRetVal parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int flags, flowControl_t flowCtlTypeu, prop_t *pInputName, struct syslogTime *stTime, time_t ttGenTime, ruleset_t *pRuleset); rsRetVal diagGetMainMsgQSize(int *piSize); /* for imdiag */ -rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName); +rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams); /* Intervals at which we flush out "message repeated" messages, * in seconds after previous message is logged. After each flush, diff --git a/doc/imklog.html b/doc/imklog.html index 2e3b3bc..05292dd 100644 --- a/doc/imklog.html +++ b/doc/imklog.html @@ -65,6 +65,19 @@ Linux only, ignored on other platforms (but may be specified)</li> former klogd -2 option<br> Linux only, ignored on other platforms (but may be specified)<br style="font-weight: bold;"> </li> +<li><b>$klogParseKernelTimestamp</b> [on/<b>off</b>] +If enabled and the kernel creates a timestamp for its log messages, this timestamp will be +parsed and converted into regular message time instead to use the receive time of the kernel +message (as in 5.8.x and before). Default is to not parse the kernel timestamp, because the +clock used by the kernel to create the timestamps is not supposed to be as accurate as the +monotonic clock required to convert it. Depending on the hardware and kernel, it can result +in message time differences between kernel and system messages which occurred at same time. +</li> +<li><b>$klogKeepKernelTimestamp</b> [on/<b>off</b>] +If enabled, this option causes to keep the [timestamp] provided by the kernel at the begin +of in each message rather than to remove it, when it could be parsed and converted into +local time for use as regular message time. Only used, when $klogParseKernelTimestamp is on. +</li> </ul> <b>Caveats/Known Bugs:</b> <p>This is obviously platform specific and requires platform diff --git a/doc/imptcp.html b/doc/imptcp.html index 7e712af..107dd30 100644 --- a/doc/imptcp.html +++ b/doc/imptcp.html @@ -25,7 +25,9 @@ specifying $InputPTCPServerRun multiple times. their name instead of just TCP. Note that only a subset of the parameters are supported. <ul> -<p><b>Global Directives</b>:</p> +<p><b>Module Parameters</b>:</p> +<p>These paramters can be used with the "module()" statement. They apply +globaly to all inputs defined by the module. <ul> <li>Threads <number><br> Number of helper worker threads to process incoming messages. These @@ -33,9 +35,11 @@ threads are utilized to pull data off the network. On a busy system, additional helper threads (but not more than there are CPUs/Cores) can help improving performance. The default value is two. </ul> -<p><b>Action Directives</b>:</p> +<p><b>Input Parameters</b>:</p> +<p>These parameters can be used with the "input()" statement. They apply to the +input they are specified with. <ul> -<li><b>AddTLFrameDelimiter</b> <Delimiter><br> +<li><b>AddtlFrameDelimiter</b> <Delimiter><br> This directive permits to specify an additional frame delimiter for plain tcp syslog. The industry-standard specifies using the LF character as frame delimiter. Some vendors, notable Juniper in their NetScreen products, use an invalid frame delimiter, in Juniper's @@ -99,13 +103,11 @@ On multi-homed machines, specifies to which local address the listerner should b <p><b>Sample:</b></p> <p>This sets up a TCP server on port 514:<br> </p> -<textarea rows="15" cols="60">module(load="/folder/to/rsyslog/plugins/imptcp/.libs/imptcp") # needs to be done just once +<textarea rows="4" cols="60">module(load="/folder/to/rsyslog/plugins/imptcp/.libs/imptcp") # needs to be done just once input(type="imptcp" port="514") </textarea> <p><b>Legacy Configuration Directives</b>:</p> -<p>This plugin has config directives similar named as imtcp, but they all have <b>P</b>TCP in -their name instead of just TCP. Note that only a subset of the parameters are supported. <ul> <li>$InputPTCPServerAddtlFrameDelimiter <Delimiter><br> Equivalent to: AddTLFrameDelimiter</li> @@ -143,7 +145,7 @@ Equivalent to: Address </li> <p><b>Sample:</b></p> <p>This sets up a TCP server on port 514:<br> </p> -<textarea rows="15" cols="60">$ModLoad imptcp # +<textarea rows="3" cols="60">$ModLoad imptcp # needs to be done just once $InputPTCPServerRun 514 </textarea> @@ -152,7 +154,7 @@ $InputPTCPServerRun 514 <p><font size="2">This documentation is part of the <a href="http://www.rsyslog.com/">rsyslog</a> project.<br> -Copyright © 2010 by <a href="http://www.gerhards.net/rainer">Rainer +Copyright © 2010-2012 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and <a href="http://www.adiscon.com/">Adiscon</a>. Released under the GNU GPL version 3 or higher.</font></p> diff --git a/doc/manual.html b/doc/manual.html index f15557d..bddac9c 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p> <p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a> to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the project goals.</p> -<p><b>This documentation is for version 7.2.3 (v7-stable branch) of rsyslog.</b> +<p><b>This documentation is for version 7.2.4 (v7-stable branch) of rsyslog.</b> Visit the <i><a href="http://www.rsyslog.com/status">rsyslog status page</a></i></b> to obtain current version information and project status. </p><p><b>If you like rsyslog, you might diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index 0dc505a..6b21bc9 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -802,6 +802,30 @@ nvlstGetParams(struct nvlst *lst, struct cnfparamblk *params, } +/* check if at least one cnfparamval is actually set + * returns 1 if so, 0 otherwise + */ +int +cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals) +{ + int i; + + if(vals == NULL) + return 0; + if(params->version != CNFPARAMBLK_VERSION) { + dbgprintf("nvlstGetParams: invalid param block version " + "%d, expected %d\n", + params->version, CNFPARAMBLK_VERSION); + return 0; + } + for(i = 0 ; i < params->nParams ; ++i) { + if(vals[i].bUsed) + return 1; + } + return 0; +} + + void cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals) { @@ -2794,7 +2818,8 @@ cnfDoInclude(char *name) if(result == GLOB_NOSPACE || result == GLOB_ABORTED) { char errStr[1024]; rs_strerror_r(errno, errStr, sizeof(errStr)); - getcwd(cwdBuf, sizeof(cwdBuf)); + if(getcwd(cwdBuf, sizeof(cwdBuf)) == NULL) + strcpy(cwdBuf, "??getcwd() failed??"); parser_errmsg("error accessing config file or directory '%s' [cwd:%s]: %s", finalName, cwdBuf, errStr); return 1; @@ -2805,7 +2830,8 @@ cnfDoInclude(char *name) if(stat(cfgFile, &fileInfo) != 0) { char errStr[1024]; rs_strerror_r(errno, errStr, sizeof(errStr)); - getcwd(cwdBuf, sizeof(cwdBuf)); + if(getcwd(cwdBuf, sizeof(cwdBuf)) == NULL) + strcpy(cwdBuf, "??getcwd() failed??"); parser_errmsg("error accessing config file or directory '%s' " "[cwd: %s]: %s", cfgFile, cwdBuf, errStr); return 1; diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 5cfce79..59ce53f 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -313,6 +313,7 @@ int cnfparamGetIdx(struct cnfparamblk *params, char *name); struct cnfparamvals* nvlstGetParams(struct nvlst *lst, struct cnfparamblk *params, struct cnfparamvals *vals); void cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals); +int cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals); void varDelete(struct var *v); void cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk); struct cnfstmt * cnfstmtNew(unsigned s_type); diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c index 0974253..640c9e1 100644 --- a/plugins/imdiag/imdiag.c +++ b/plugins/imdiag/imdiag.c @@ -57,7 +57,6 @@ MODULE_TYPE_INPUT MODULE_TYPE_NOKEEP -MODULE_CNFNAME("imdiag") /* static data */ DEF_IMOD_STATIC_DATA diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index d4f9f77..cddc673 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -73,18 +73,21 @@ static int fklog = -1; /* kernel log fd */ * rgerhards, 2011-06-24 */ static void -submitSyslog(int pri, uchar *buf) +submitSyslog(modConfData_t *pModConf, int pri, uchar *buf) { long secs; - long nsecs; + long usecs; long secOffs; - long nsecOffs; + long usecOffs; unsigned i; unsigned bufsize; struct timespec monotonic, realtime; struct timeval tv; struct timeval *tp = NULL; + if(!pModConf->bParseKernelStamp) + goto done; + if(buf[3] != '[') goto done; DBGPRINTF("imklog: kernel timestamp detected, extracting it\n"); @@ -106,9 +109,9 @@ submitSyslog(int pri, uchar *buf) } ++i; /* skip dot */ - nsecs = 0; + usecs = 0; while(buf[i] && isdigit(buf[i])) { - nsecs = nsecs * 10 + buf[i] - '0'; + usecs = usecs * 10 + buf[i] - '0'; ++i; } if(buf[i] != ']') { @@ -118,27 +121,29 @@ submitSyslog(int pri, uchar *buf) ++i; /* skip ']' */ /* we have a timestamp */ - DBGPRINTF("kernel timestamp is %ld %ld\n", secs, nsecs); - bufsize= strlen((char*)buf); - memmove(buf+3, buf+i, bufsize - i + 1); + DBGPRINTF("kernel timestamp is %ld %ld\n", secs, usecs); + if(!pModConf->bKeepKernelStamp) { + bufsize= strlen((char*)buf); + memmove(buf+3, buf+i, bufsize - i + 1); + } clock_gettime(CLOCK_MONOTONIC, &monotonic); clock_gettime(CLOCK_REALTIME, &realtime); secOffs = realtime.tv_sec - monotonic.tv_sec; - nsecOffs = realtime.tv_nsec - monotonic.tv_nsec; - if(nsecOffs < 0) { + usecOffs = (realtime.tv_nsec - monotonic.tv_nsec) / 1000; + if(usecOffs < 0) { secOffs--; - nsecOffs += 1000000000l; + usecOffs += 1000000l; } - nsecs +=nsecOffs; - if(nsecs > 999999999l) { + usecs += usecOffs; + if(usecs > 999999l) { secs++; - nsecs -= 1000000000l; + usecs -= 1000000l; } secs += secOffs; tv.tv_sec = secs; - tv.tv_usec = nsecs / 1000; + tv.tv_usec = usecs; tp = &tv; done: @@ -146,7 +151,7 @@ done: } #else /* now comes the BSD "code" (just a shim) */ static void -submitSyslog(int pri, uchar *buf) +submitSyslog(modConfData_t *pModConf, int pri, uchar *buf) { Syslog(pri, buf, NULL); } @@ -196,7 +201,7 @@ finalize_it: /* Read kernel log while data are available, split into lines. */ static void -readklog(void) +readklog(modConfData_t *pModConf) { char *p, *q; int len, i; @@ -238,18 +243,18 @@ readklog(void) for (p = (char*)pRcv; (q = strchr(p, '\n')) != NULL; p = q + 1) { *q = '\0'; - submitSyslog(LOG_INFO, (uchar*) p); + submitSyslog(pModConf, LOG_INFO, (uchar*) p); } len = strlen(p); if (len >= iMaxLine - 1) { - submitSyslog(LOG_INFO, (uchar*)p); + submitSyslog(pModConf, LOG_INFO, (uchar*)p); len = 0; } if(len > 0) memmove(pRcv, p, len + 1); } if (len > 0) - submitSyslog(LOG_INFO, pRcv); + submitSyslog(pModConf, LOG_INFO, pRcv); if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) free(pRcv); @@ -278,10 +283,10 @@ rsRetVal klogAfterRun(modConfData_t *pModConf) * "message pull" mechanism. * rgerhards, 2008-04-09 */ -rsRetVal klogLogKMsg(modConfData_t __attribute__((unused)) *pModConf) +rsRetVal klogLogKMsg(modConfData_t *pModConf) { DEFiRet; - readklog(); + readklog(pModConf); RETiRet; } diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 9332370..a24fc63 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -77,6 +77,8 @@ DEFobjCurrIf(errmsg) /* config settings */ typedef struct configSettings_s { int bPermitNonKernel; /* permit logging of messages not having LOG_KERN facility */ + int bParseKernelStamp; /* if try to parse kernel timestamps for message time */ + int bKeepKernelStamp; /* keep the kernel timestamp in the message */ int iFacilIntMsg; /* the facility to use for internal messages (set by driver) */ uchar *pszPath; int console_log_level; /* still used for BSD */ @@ -92,6 +94,8 @@ static struct cnfparamdescr modpdescr[] = { { "logpath", eCmdHdlrGetWord, 0 }, { "permitnonkernelfacility", eCmdHdlrBinary, 0 }, { "consoleloglevel", eCmdHdlrInt, 0 }, + { "parsekerneltimestamp", eCmdHdlrBinary, 0 }, + { "keepkerneltimestamp", eCmdHdlrBinary, 0 }, { "internalmsgfacility", eCmdHdlrFacility, 0 } }; static struct cnfparamblk modpblk = @@ -100,16 +104,15 @@ static struct cnfparamblk modpblk = modpdescr }; - - static prop_t *pInputName = NULL; /* there is only one global inputName for all messages generated by this module */ static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 */ - static inline void initConfigSettings(void) { cs.bPermitNonKernel = 0; + cs.bParseKernelStamp = 0; + cs.bKeepKernelStamp = 0; cs.console_log_level = -1; cs.pszPath = NULL; cs.iFacilIntMsg = klogFacilIntMsg(); @@ -288,6 +291,8 @@ CODESTARTbeginCnfLoad /* init our settings */ pModConf->pszPath = NULL; pModConf->bPermitNonKernel = 0; + pModConf->bParseKernelStamp = 0; + pModConf->bKeepKernelStamp = 0; pModConf->console_log_level = -1; pModConf->iFacilIntMsg = klogFacilIntMsg(); loadModConf->configSetViaV2Method = 0; @@ -320,6 +325,10 @@ CODESTARTsetModCnf loadModConf->pszPath = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(modpblk.descr[i].name, "permitnonkernelfacility")) { loadModConf->bPermitNonKernel = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "parsekerneltimestamp")) { + loadModConf->bParseKernelStamp = (int) pvals[i].val.d.n; + } else if(!strcmp(modpblk.descr[i].name, "keepkerneltimestamp")) { + loadModConf->bKeepKernelStamp = (int) pvals[i].val.d.n; } else if(!strcmp(modpblk.descr[i].name, "consoleloglevel")) { loadModConf->console_log_level= (int) pvals[i].val.d.n; } else if(!strcmp(modpblk.descr[i].name, "internalmsgfacility")) { @@ -345,6 +354,8 @@ CODESTARTendCnfLoad if(!loadModConf->configSetViaV2Method) { /* persist module-specific settings from legacy config system */ loadModConf->bPermitNonKernel = cs.bPermitNonKernel; + loadModConf->bParseKernelStamp = cs.bParseKernelStamp; + loadModConf->bKeepKernelStamp = cs.bKeepKernelStamp; loadModConf->iFacilIntMsg = cs.iFacilIntMsg; loadModConf->console_log_level = cs.console_log_level; if((cs.pszPath == NULL) || (cs.pszPath[0] == '\0')) { @@ -421,6 +432,8 @@ ENDqueryEtryPt static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { cs.bPermitNonKernel = 0; + cs.bParseKernelStamp = 0; + cs.bKeepKernelStamp = 0; if(cs.pszPath != NULL) { free(cs.pszPath); cs.pszPath = NULL; @@ -462,6 +475,10 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &cs.console_log_level, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); CHKiRet(regCfSysLineHdlr2((uchar *)"kloginternalmsgfacility", 0, eCmdHdlrFacility, NULL, &cs.iFacilIntMsg, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2((uchar *)"klogparsekerneltimestamp", 0, eCmdHdlrBinary, + NULL, &cs.bParseKernelStamp, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); + CHKiRet(regCfSysLineHdlr2((uchar *)"klogkeepkerneltimestamp", 0, eCmdHdlrBinary, + NULL, &cs.bKeepKernelStamp, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h index acfb50a..fa517cc 100644 --- a/plugins/imklog/imklog.h +++ b/plugins/imklog/imklog.h @@ -36,6 +36,8 @@ struct modConfData_s { uchar *pszPath; int console_log_level; sbool bPermitNonKernel; + sbool bParseKernelStamp; + sbool bKeepKernelStamp; sbool configSetViaV2Method; }; diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 8150fc3..9888086 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -1444,7 +1444,7 @@ CODESTARTnewInpInst inst->pszInputName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); } else if(!strcmp(inppblk.descr[i].name, "ruleset")) { inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL); - } else if(!strcmp(inppblk.descr[i].name, "supportOctetCountedFraming")) { + } else if(!strcmp(inppblk.descr[i].name, "supportoctetcountedframing")) { inst->bSuppOctetFram = (int) pvals[i].val.d.n; } else if(!strcmp(inppblk.descr[i].name, "keepalive")) { inst->bKeepAlive = (int) pvals[i].val.d.n; diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index e0ba7dd..871a1fa 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -937,15 +937,19 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred, struct tim /* in this case, we still need to find out if we have a valid * datestamp or not .. and advance the parse pointer accordingly. */ - datetime.ParseTIMESTAMP3164(&dummyTS, &parse, &lenMsg); + if (datetime.ParseTIMESTAMP3339(&dummyTS, &parse, &lenMsg) != RS_RET_OK) { + datetime.ParseTIMESTAMP3164(&dummyTS, &parse, &lenMsg); + } } else { - if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &parse, &lenMsg) != RS_RET_OK) { + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &parse, &lenMsg) != RS_RET_OK && + datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), &parse, &lenMsg) != RS_RET_OK) { DBGPRINTF("we have a problem, invalid timestamp in msg!\n"); } } } else { /* if we pulled the time from the system, we need to update the message text */ uchar *tmpParse = parse; /* just to check correctness of TS */ - if(datetime.ParseTIMESTAMP3164(&dummyTS, &tmpParse, &lenMsg) == RS_RET_OK) { + if(datetime.ParseTIMESTAMP3339(&dummyTS, &tmpParse, &lenMsg) == RS_RET_OK || + datetime.ParseTIMESTAMP3164(&dummyTS, &tmpParse, &lenMsg) == RS_RET_OK) { /* We modify the message only if it contained a valid timestamp, * otherwise we do not touch it at all. */ datetime.formatTimestamp3164(&st, (char*)parse, 0); diff --git a/plugins/mmjsonparse/mmjsonparse.c b/plugins/mmjsonparse/mmjsonparse.c index da5cfb5..40cfa91 100644 --- a/plugins/mmjsonparse/mmjsonparse.c +++ b/plugins/mmjsonparse/mmjsonparse.c @@ -217,6 +217,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt @@ -240,6 +241,7 @@ INITLegCnfVars *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmjsonparse: module compiled with rsyslog version %s.\n", VERSION); /* check if the rsyslog core supports parameter passing code */ bMsgPassingSupported = 0; localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", diff --git a/plugins/mmnormalize/mmnormalize.c b/plugins/mmnormalize/mmnormalize.c index b5f4ce1..d3fba39 100644 --- a/plugins/mmnormalize/mmnormalize.c +++ b/plugins/mmnormalize/mmnormalize.c @@ -222,6 +222,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt @@ -256,6 +257,7 @@ INITLegCnfVars *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + DBGPRINTF("mmnormalize: module compiled with rsyslog version %s.\n", VERSION); /* check if the rsyslog core supports parameter passing code */ bMsgPassingSupported = 0; localRet = pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", diff --git a/plugins/mmsnmptrapd/mmsnmptrapd.c b/plugins/mmsnmptrapd/mmsnmptrapd.c index b1ac2f6..b79a311 100644 --- a/plugins/mmsnmptrapd/mmsnmptrapd.c +++ b/plugins/mmsnmptrapd/mmsnmptrapd.c @@ -362,6 +362,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/plugins/ommail/ommail.c b/plugins/ommail/ommail.c index d70fa30..6044d2e 100644 --- a/plugins/ommail/ommail.c +++ b/plugins/ommail/ommail.c @@ -689,6 +689,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/plugins/omprog/omprog.c b/plugins/omprog/omprog.c index 6978a9d..e425b42 100644 --- a/plugins/omprog/omprog.c +++ b/plugins/omprog/omprog.c @@ -128,7 +128,12 @@ static void execBinary(instanceData *pData, int fdStdin) assert(pData != NULL); fclose(stdin); - dup(fdStdin); + if(dup(fdStdin) == -1) { + DBGPRINTF("omprog: dup() failed\n"); + /* do some more error handling here? Maybe if the module + * gets some more widespread use... + */ + } //fclose(stdout); /* we close all file handles as we fork soon diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c index 39ffe7f..e55836c 100644 --- a/plugins/omrelp/omrelp.c +++ b/plugins/omrelp/omrelp.c @@ -341,6 +341,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/plugins/omruleset/omruleset.c b/plugins/omruleset/omruleset.c index d1d6eb0..4c7e25d 100644 --- a/plugins/omruleset/omruleset.c +++ b/plugins/omruleset/omruleset.c @@ -199,6 +199,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c index fb95e95..59f9c8b 100644 --- a/plugins/omstdout/omstdout.c +++ b/plugins/omstdout/omstdout.c @@ -136,9 +136,13 @@ CODESTARTdoAction toWrite = (char*) ppString[0]; } len = strlen(toWrite); - write(1, toWrite, len); /* 1 is stdout! */ + /* the following if's are just to silence compiler warnings. If someone + * actually intends to use this module in production (why???), this code + * needs to be more solid. -- rgerhards, 2012-11-28 + */ + if(write(1, toWrite, len)) {}; /* 1 is stdout! */ if(pData->bEnsureLFEnding && toWrite[len-1] != '\n') { - write(1, "\n", 1); /* write missing LF */ + if(write(1, "\n", 1)) {}; /* write missing LF */ } ENDdoAction @@ -175,6 +179,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/plugins/omtesting/omtesting.c b/plugins/omtesting/omtesting.c index ff290c9..c9f1e06 100644 --- a/plugins/omtesting/omtesting.c +++ b/plugins/omtesting/omtesting.c @@ -313,6 +313,7 @@ ENDmodExit BEGINqueryEtryPt CODESTARTqueryEtryPt CODEqueryEtryPt_STD_OMOD_QUERIES +CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES ENDqueryEtryPt diff --git a/runtime/datetime.c b/runtime/datetime.c index 10ab3c6..53bc165 100644 --- a/runtime/datetime.c +++ b/runtime/datetime.c @@ -900,6 +900,11 @@ time_t syslogTime2time_t(struct syslogTime *ts) case 12: MonthInDays = 334; //until 01 of December break; + default: /* this cannot happen (and would be a program error) + * but we need the code to keep the compiler silent. + */ + MonthInDays = 0; /* any value fits ;) */ + break; } diff --git a/runtime/debug.c b/runtime/debug.c index 307a8bb..1d306db 100644 --- a/runtime/debug.c +++ b/runtime/debug.c @@ -902,8 +902,12 @@ do_dbgprint(uchar *pszObjName, char *pszMsg, size_t lenMsg) lenCopy = lenMsg; memcpy(pszWriteBuf + offsWriteBuf, pszMsg, lenCopy); offsWriteBuf += lenCopy; - if(stddbg != -1) write(stddbg, pszWriteBuf, offsWriteBuf); - if(altdbg != -1) write(altdbg, pszWriteBuf, offsWriteBuf); + /* the write is included in an "if" just to silence compiler + * warnings. Here, we really don't care if the write fails, we + * have no good response to that in any case... -- rgerhards, 2012-11-28 + */ + if(stddbg != -1) if(write(stddbg, pszWriteBuf, offsWriteBuf)){}; + if(altdbg != -1) if(write(altdbg, pszWriteBuf, offsWriteBuf)){}; bWasNL = (pszMsg[lenMsg - 1] == '\n') ? 1 : 0; } diff --git a/runtime/module-template.h b/runtime/module-template.h index 72a139c..fe74bac 100644 --- a/runtime/module-template.h +++ b/runtime/module-template.h @@ -113,7 +113,7 @@ static rsRetVal modGetID(void **pID) \ /* macro to provide the v6 config system module name */ #define MODULE_CNFNAME(name) \ -static __attribute__((unused)) rsRetVal modGetCnfName(uchar **cnfName) \ +static rsRetVal modGetCnfName(uchar **cnfName) \ { \ *cnfName = (uchar*) name; \ return RS_RET_OK;\ diff --git a/runtime/msg.c b/runtime/msg.c index b627cd5..09f6d64 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -300,120 +300,20 @@ static uchar * jsonPathGetLeaf(uchar *name, int lenName); static struct json_object *jsonDeepCopy(struct json_object *src); -/* The following functions will support advanced output module - * multithreading, once this is implemented. Currently, we - * include them as hooks only. The idea is that we need to guard - * some msg objects data fields against concurrent access if - * we run on multiple threads. Please note that in any case this - * is not necessary for calls from INPUT modules, because they - * construct the message object and do this serially. Only when - * the message is in the processing queue, multiple threads may - * access a single object. Consequently, there are no guard functions - * for "set" methods, as these are called during input. Only "get" - * functions that modify important structures have them. - * rgerhards, 2007-07-20 - * We now support locked and non-locked operations, depending on - * the configuration of rsyslog. To support this, we use function - * pointers. Initially, we start in non-locked mode. There, all - * locking operations call into dummy functions. When locking is - * enabled, the function pointers are changed to functions doing - * actual work. We also introduced another MsgPrepareEnqueue() function - * which initializes the locking structures, if needed. This is - * necessary because internal messages during config file startup - * processing are always created in non-locking mode. So we can - * not initialize locking structures during constructions. We now - * postpone this until when the message is fully constructed and - * enqueued. Then we know the status of locking. This has a nice - * side effect, and that is that during the initial creation of - * the Msg object no locking needs to be done, which results in better - * performance. -- rgerhards, 2008-01-05 - */ -static void (*funcLock)(msg_t *pMsg); -static void (*funcUnlock)(msg_t *pMsg); -static void (*funcDeleteMutex)(msg_t *pMsg); -void (*funcMsgPrepareEnqueue)(msg_t *pMsg); -#if 1 /* This is a debug aid */ -#define MsgLock(pMsg) funcLock(pMsg) -#define MsgUnlock(pMsg) funcUnlock(pMsg) -#else -#define MsgLock(pMsg) {dbgprintf("MsgLock line %d\n - ", __LINE__); funcLock(pMsg);; } -#define MsgUnlock(pMsg) {dbgprintf("MsgUnlock line %d - ", __LINE__); funcUnlock(pMsg); } -#endif - -/* the next function is a dummy to be used by the looking functions - * when the class is not yet running in an environment where locking - * is necessary. Please note that the need to lock can (and will) change - * during a single run. Typically, this is depending on the operation mode - * of the message queues (which is operator-configurable). -- rgerhards, 2008-01-05 - */ -static void MsgLockingDummy(msg_t __attribute__((unused)) *pMsg) -{ - /* empty be design */ -} - - -/* The following function prepares a message for enqueue into the queue. This is - * where a message may be accessed by multiple threads. This implementation here - * is the version for multiple concurrent acces. It initializes the locking - * structures. - * TODO: change to an iRet interface! -- rgerhards, 2008-07-14 - */ -static void MsgPrepareEnqueueLockingCase(msg_t *pThis) -{ - BEGINfunc - assert(pThis != NULL); - pthread_mutex_init(&pThis->mut, NULL); - pThis->bDoLock = 1; - ENDfunc -} - - -/* ... and now the locking and unlocking implementations: */ -static void MsgLockLockingCase(msg_t *pThis) +/* the locking and unlocking implementations: */ +static inline void +MsgLock(msg_t *pThis) { /* DEV debug only! dbgprintf("MsgLock(0x%lx)\n", (unsigned long) pThis); */ - assert(pThis != NULL); - if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */ - pthread_mutex_lock(&pThis->mut); + pthread_mutex_lock(&pThis->mut); } - -static void MsgUnlockLockingCase(msg_t *pThis) +static inline void +MsgUnlock(msg_t *pThis) { /* DEV debug only! dbgprintf("MsgUnlock(0x%lx)\n", (unsigned long) pThis); */ - assert(pThis != NULL); - if(pThis->bDoLock == 1) /* TODO: this is a testing hack, we should find a way with better performance! -- rgerhards, 2009-01-27 */ - pthread_mutex_unlock(&pThis->mut); + pthread_mutex_unlock(&pThis->mut); } -/* delete the mutex object on message destruction (locking case) - */ -static void MsgDeleteMutexLockingCase(msg_t *pThis) -{ - assert(pThis != NULL); - pthread_mutex_destroy(&pThis->mut); -} - -/* enable multiple concurrent access on the message object - * This works on a class-wide basis and can bot be undone. - * That is, if it is once enabled, it can not be disabled during - * the same run. When this function is called, no other thread - * must manipulate message objects. Then we would have race conditions, - * but guarding against this is counter-productive because it - * would cost additional time. Plus, it would be a programming error. - * rgerhards, 2008-01-05 - */ -rsRetVal MsgEnableThreadSafety(void) -{ - DEFiRet; - funcLock = MsgLockLockingCase; - funcUnlock = MsgUnlockLockingCase; - funcMsgPrepareEnqueue = MsgPrepareEnqueueLockingCase; - funcDeleteMutex = MsgDeleteMutexLockingCase; - RETiRet; -} - -/* end locking functions */ - static inline int getProtocolVersion(msg_t *pM) { @@ -716,8 +616,6 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis) /* initialize members in ORDER they appear in structure (think "cache line"!) */ pM->flowCtlType = 0; - pM->bDoLock = 0; - pM->bAlreadyFreed = 0; pM->bParseSuccess = 0; pM->iRefCount = 1; pM->iSeverity = -1; @@ -760,6 +658,7 @@ static inline rsRetVal msgBaseConstruct(msg_t **ppThis) pM->pszTIMESTAMP_Unix[0] = '\0'; pM->pszRcvdAt_Unix[0] = '\0'; pM->pszUUID = NULL; + pthread_mutex_init(&pM->mut, NULL); /* DEV debugging only! dbgprintf("msgConstruct\t0x%x, ref 1\n", (int)pM);*/ @@ -849,15 +748,6 @@ CODESTARTobjDestruct(msg) if(currRefCount == 0) { /* DEV Debugging Only! dbgprintf("msgDestruct\t0x%lx, RefCount now 0, doing DESTROY\n", (unsigned long)pThis); */ - /* The if below is included to try to nail down a well-hidden bug causing - * segfaults. I hope that do to the test code the problem is sooner detected and - * thus we get better data for debugging and resolving it. -- rgerhards, 2011-02-23. - * TODO: remove when no longer needed. - */ - if(pThis->bAlreadyFreed) - abort(); - pThis->bAlreadyFreed = 1; - /* end debug code */ if(pThis->pszRawMsg != pThis->szRawMsg) free(pThis->pszRawMsg); freeTAG(pThis); @@ -895,7 +785,7 @@ CODESTARTobjDestruct(msg) # ifndef HAVE_ATOMIC_BUILTINS MsgUnlock(pThis); # endif - funcDeleteMutex(pThis); + pthread_mutex_destroy(&pThis->mut); /* now we need to do our own optimization. Testing has shown that at least the glibc * malloc() subsystem returns memory to the OS far too late in our case. So we need * to help it a bit, by calling malloc_trim(), which will tell the alloc subsystem @@ -3656,18 +3546,6 @@ finalize_it: #undef isProp -/* This is a construction finalizer that must be called after all properties - * have been set. It does some final work on the message object. After this - * is done, the object is considered ready for full processing. - * rgerhards, 2008-07-08 - */ -static rsRetVal msgConstructFinalizer(msg_t *pThis) -{ - MsgPrepareEnqueue(pThis); - return RS_RET_OK; -} - - /* get the severity - this is an entry point that * satisfies the base object class getSeverity semantics. * rgerhards, 2008-01-14 @@ -3977,13 +3855,7 @@ BEGINObjClassInit(msg, 1, OBJ_IS_CORE_MODULE) /* set our own handlers */ OBJSetMethodHandler(objMethod_SERIALIZE, MsgSerialize); OBJSetMethodHandler(objMethod_SETPROPERTY, MsgSetProperty); - OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, msgConstructFinalizer); OBJSetMethodHandler(objMethod_GETSEVERITY, MsgGetSeverity); - /* initially, we have no need to lock message objects */ - funcLock = MsgLockingDummy; - funcUnlock = MsgLockingDummy; - funcDeleteMutex = MsgLockingDummy; - funcMsgPrepareEnqueue = MsgLockingDummy; /* some more inits */ # if HAVE_MALLOC_TRIM INIT_ATOMIC_HELPER_MUT(mutTrimCtr); diff --git a/runtime/msg.h b/runtime/msg.h index 396e861..ab47900 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -64,7 +64,6 @@ struct msg { once data has entered the queue, this property is no longer needed. */ pthread_mutex_t mut; int iRefCount; /* reference counter (0 = unused) */ - sbool bDoLock; /* use the mutex? */ sbool bAlreadyFreed; /* aid to help detect a well-hidden bad bug -- TODO: remove when no longer needed */ sbool bParseSuccess; /* set to reflect state of last executed higher level parser */ short iSeverity; /* the severity 0..7 */ @@ -177,7 +176,6 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, char *textpri(char *pRes, size_t pResLen, int pri); rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar); es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name); -rsRetVal MsgEnableThreadSafety(void); uchar *getRcvFrom(msg_t *pM); void getTAG(msg_t *pM, uchar **ppBuf, int *piLen); char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt); @@ -213,16 +211,6 @@ msgUnsetJSON(msg_t *pMsg, uchar *varname) { } -/* The MsgPrepareEnqueue() function is a macro for performance reasons. - * It needs one global variable to work. This is acceptable, as it gains - * us quite some performance and is fully abstracted using this header file. - * The important thing is that no other module is permitted to actually - * access that global variable! -- rgerhards, 2008-01-05 - */ -extern void (*funcMsgPrepareEnqueue)(msg_t *pMsg); -#define MsgPrepareEnqueue(pMsg) funcMsgPrepareEnqueue(pMsg) - - /* ------------------------------ some inline functions ------------------------------ */ /* set raw message size. This is needed in some cases where a trunctation is necessary diff --git a/runtime/queue.c b/runtime/queue.c index fbf7710..bb40e54 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -242,6 +242,9 @@ getQueueTypeName(queueType_t t) case QUEUETYPE_DIRECT: r = "Direct"; break; + default: + r = "unknown queue type"; + break; } return r; } @@ -1379,7 +1382,7 @@ finalize_it: } -/* set default inisde queue object suitable for action queues. +/* set default inside queue object suitable for action queues. * This shall be called directly after queue construction. This functions has * been added in support of the new v6 config system. It expect properly pre-initialized * objects, but we need to differentiate between ruleset main and action queues. @@ -1413,6 +1416,36 @@ qqueueSetDefaultsActionQueue(qqueue_t *pThis) } +/* set defaults inside queue object suitable for main/ruleset queues. + * See queueSetDefaultsActionQueue() for more details and background. + */ +void +qqueueSetDefaultsRulesetQueue(qqueue_t *pThis) +{ + pThis->qType = QUEUETYPE_FIXED_ARRAY; /* type of the main message queue above */ + pThis->iMaxQueueSize = 50000; /* size of the main message queue above */ + pThis->iDeqBatchSize = 1024; /* default batch size */ + pThis->iHighWtrMrk = 45000; /* high water mark for disk-assisted queues */ + pThis->iLowWtrMrk = 20000; /* low water mark for disk-assisted queues */ + pThis->iDiscardMrk = 49500; /* begin to discard messages */ + pThis->iDiscardSeverity = 8; /* turn off */ + pThis->iNumWorkerThreads = 1; /* number of worker threads for the mm queue above */ + pThis->iMaxFileSize = 16*1024*1024; + pThis->iPersistUpdCnt = 0; /* persist queue info every n updates */ + pThis->bSyncQueueFiles = 0; + pThis->toQShutdown = 1500; /* queue shutdown */ + pThis->toActShutdown = 1000; /* action shutdown (in phase 2) */ + pThis->toEnq = 2000; /* timeout for queue enque */ + pThis->toWrkShutdown = 60000; /* timeout for worker thread shutdown */ + pThis->iMinMsgsPerWrkr = 1000; /* minimum messages per worker needed to start a new one */ + pThis->bSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ + pThis->sizeOnDiskMax = 0; /* unlimited */ + pThis->iDeqSlowdown = 0; + pThis->iDeqtWinFromHr = 0; + pThis->iDeqtWinToHr = 25; /* disable time-windowed dequeuing by default */ +} + + /* This function checks if the provided message shall be discarded and does so, if needed. * In DA mode, we do not discard any messages as we assume the disk subsystem is fast enough to * provide real-time creation of spool files. @@ -2675,6 +2708,15 @@ qqueueDoCnfParams(struct nvlst *lst, struct cnfparamvals **ppvals) return RS_RET_OK; } + +/* are any queue params set at all? 1 - yes, 0 - no */ +int +queueCnfParamsSet(struct cnfparamvals *pvals) +{ + return cnfparamvalsIsSet(&pblk, pvals); +} + + /* apply all params from param block to queue. Must be called before * finalizing. This supports the v6 config system. Defaults were already * set during queue creation. The pvals object is destructed by this diff --git a/runtime/queue.h b/runtime/queue.h index edb770c..91c100e 100644 --- a/runtime/queue.h +++ b/runtime/queue.h @@ -193,7 +193,9 @@ rsRetVal qqueueConstruct(qqueue_t **ppThis, queueType_t qType, int iWorkerThread int iMaxQueueSize, rsRetVal (*pConsumer)(void*,batch_t*, int*)); rsRetVal qqueueEnqObjDirectBatch(qqueue_t *pThis, batch_t *pBatch); rsRetVal qqueueDoCnfParams(struct nvlst *lst, struct cnfparamvals **ppvals); +int queueCnfParamsSet(struct cnfparamvals *pvals); rsRetVal qqueueApplyCnfParam(qqueue_t *pThis, struct cnfparamvals *pvals); +void qqueueSetDefaultsRulesetQueue(qqueue_t *pThis); void qqueueSetDefaultsActionQueue(qqueue_t *pThis); void qqueueDbgPrint(qqueue_t *pThis); diff --git a/runtime/rsconf.c b/runtime/rsconf.c index dcaa1ad..ac9cd80 100644 --- a/runtime/rsconf.c +++ b/runtime/rsconf.c @@ -292,6 +292,9 @@ getNOW(eNOWType eNow, es_str_t **estr) case NOW_MINUTE: len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "%2.2d", t.minute); break; + default: + len = snprintf((char*) szBuf, sizeof(szBuf)/sizeof(uchar), "*invld eNow*"); + break; } /* now create a string object out of it and hand that over to the var */ @@ -476,6 +479,9 @@ cnfGetVar(char *name, void *usrptr) estr = msgGetCEEVarNew((msg_t*) usrptr, name+2); else estr = msgGetMsgVarNew((msg_t*) usrptr, (uchar*)name+1); + } else { /* if this happens, we have a program logic error */ + estr = es_newStrFromCStr("err: var must start with $", + strlen("err: var must start with $")); } if(Debug) { char *s; @@ -752,7 +758,7 @@ activateMainQueue() { DEFiRet; /* create message queue */ - CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"))) { + CHKiRet_Hdlr(createMainQueue(&pMsgQueue, UCHAR_CONSTANT("main Q"), NULL)) { /* no queue is fatal, we need to give up in that case... */ fprintf(stderr, "fatal error %d: could not create message queue - rsyslogd can not run!\n", iRet); FINALIZE; diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 8d2bb92..3459f54 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -844,7 +844,7 @@ doRulesetCreateQueue(rsconf_t *conf, int *pNewVal) rsname = (conf->rulesets.pCurr->pszName == NULL) ? (uchar*) "[ruleset]" : conf->rulesets.pCurr->pszName; DBGPRINTF("adding a ruleset-specific \"main\" queue for ruleset '%s'\n", rsname); - CHKiRet(createMainQueue(&conf->rulesets.pCurr->pQueue, rsname)); + CHKiRet(createMainQueue(&conf->rulesets.pCurr->pQueue, rsname, NULL)); finalize_it: RETiRet; @@ -904,6 +904,7 @@ rsRetVal rulesetProcessCnf(struct cnfobj *o) { struct cnfparamvals *pvals; + struct cnfparamvals *queueParams; rsRetVal localRet; uchar *rsName = NULL; uchar *parserName; @@ -911,6 +912,7 @@ rulesetProcessCnf(struct cnfobj *o) ruleset_t *pRuleset; struct cnfarray *ar; int i; + uchar *rsname; DEFiRet; pvals = nvlstGetParams(o->nvlst, &rspblk, NULL); @@ -938,14 +940,21 @@ rulesetProcessCnf(struct cnfobj *o) /* we have only two params, so we do NOT do the usual param loop */ parserIdx = cnfparamGetIdx(&rspblk, "parser"); - if(parserIdx == -1 || !pvals[parserIdx].bUsed) - FINALIZE; + if(parserIdx != -1 && pvals[parserIdx].bUsed) { + ar = pvals[parserIdx].val.d.ar; + for(i = 0 ; i < ar->nmemb ; ++i) { + parserName = (uchar*)es_str2cstr(ar->arr[i], NULL); + doRulesetAddParser(pRuleset, parserName); + free(parserName); + } + } - ar = pvals[parserIdx].val.d.ar; - for(i = 0 ; i < ar->nmemb ; ++i) { - parserName = (uchar*)es_str2cstr(ar->arr[i], NULL); - doRulesetAddParser(pRuleset, parserName); - free(parserName); + /* pick up ruleset queue parameters */ + qqueueDoCnfParams(o->nvlst, &queueParams); + if(queueCnfParamsSet(queueParams)) { + rsname = (pRuleset->pszName == NULL) ? (uchar*) "[ruleset]" : pRuleset->pszName; + DBGPRINTF("adding a ruleset-specific \"main\" queue for ruleset '%s'\n", rsname); + CHKiRet(createMainQueue(&pRuleset->pQueue, rsname, queueParams)); } finalize_it: @@ -55,7 +55,7 @@ DEFobjCurrIf(strgen) /* tables for interfacing with the v6 config system */ static struct cnfparamdescr cnfparamdescr[] = { { "name", eCmdHdlrString, 1 }, - { "type", eCmdHdlrString, 0 }, + { "type", eCmdHdlrString, 1 }, { "string", eCmdHdlrString, 0 }, { "plugin", eCmdHdlrString, 0 }, { "subtree", eCmdHdlrString, 0 }, @@ -1300,7 +1300,7 @@ static rsRetVal createConstantTpe(struct template *pTpl, struct cnfobj *o) { struct templateEntry *pTpe; - es_str_t *value; + es_str_t *value = NULL; /* init just to keep compiler happy - mandatory parameter */ int i; struct cnfparamvals *pvals = NULL; uchar *outname = NULL; @@ -1669,13 +1669,14 @@ tplProcessCnf(struct cnfobj *o) { struct template *pTpl = NULL; struct cnfparamvals *pvals = NULL; - int lenName; + int lenName = 0; /* init just to keep compiler happy: mandatory parameter */ char *name = NULL; uchar *tplStr = NULL; uchar *plugin = NULL; es_str_t *subtree = NULL; uchar *p; - enum { T_STRING, T_PLUGIN, T_LIST, T_SUBTREE } tplType; + enum { T_STRING, T_PLUGIN, T_LIST, T_SUBTREE } + tplType = T_STRING; /* init just to keep compiler happy: mandatory parameter */ int i; int o_sql=0, o_stdsql=0, o_json=0; /* options */ int numopts; @@ -2066,8 +2067,14 @@ void tplPrintList(rsconf_t *conf) case tplFmtUnixDate: dbgprintf("[Format as Unix timestamp] "); break; + case tplFmtSecFrac: + dbgprintf("[fractional seconds, only] "); + break; + case tplFmtRFC3164BuggyDate: + dbgprintf("[Format as buggy RFC3164-Date] "); + break; default: - dbgprintf("[INVALID eDateFormat %d] ", pTpe->data.field.eDateFormat); + dbgprintf("[UNKNOWN eDateFormat %d] ", pTpe->data.field.eDateFormat); } switch(pTpe->data.field.eCaseConv) { case tplCaseConvNo: diff --git a/tools/pidfile.c b/tools/pidfile.c index e960123..8298b94 100644 --- a/tools/pidfile.c +++ b/tools/pidfile.c @@ -55,7 +55,8 @@ int read_pid (char *pidfile) if (!(f=fopen(pidfile,"r"))) return 0; - fscanf(f,"%d", &pid); + if(fscanf(f,"%d", &pid) != 1) + pid = 0; fclose(f); return pid; } @@ -113,7 +114,8 @@ int write_pid (char *pidfile) #if HAVE_FLOCK if (flock(fd, LOCK_EX|LOCK_NB) == -1) { - fscanf(f, "%d", &pid); + if(fscanf(f, "%d", &pid) != 1) + pid = 0; fclose(f); printf("Can't lock, lock is held by pid %d.\n", pid); return 0; diff --git a/tools/syslogd.c b/tools/syslogd.c index a3cbc79..62c18e7 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -638,7 +638,6 @@ submitMsg(msg_t *pMsg) FINALIZE; } - MsgPrepareEnqueue(pMsg); qqueueEnqObj(pQueue, pMsg->flowCtlType, (void*) pMsg); finalize_it: @@ -672,10 +671,6 @@ multiSubmitMsg(multi_submit_t *pMultiSub) FINALIZE; } - for(i = 0 ; i < pMultiSub->nElem ; ++i) { - MsgPrepareEnqueue(pMultiSub->ppMsgs[i]); - } - iRet = pQueue->MultiEnq(pQueue, pMultiSub); pMultiSub->nElem = 0; @@ -779,8 +774,11 @@ static void debug_switch() * a minimal delay, but it is much cleaner than the approach of doing everything * inside the signal handler. * rgerhards, 2005-10-26 - * Note: we do not call DBGPRINTF() as this may cause us to block in case something - * with the threading is wrong. + * Note: + * - we do not call DBGPRINTF() as this may cause us to block in case something + * with the threading is wrong. + * - we do not really care about the return state of write(), but we need this + * strange check we do to silence compiler warnings (thanks, Ubuntu!) */ static void doDie(int sig) { @@ -788,11 +786,13 @@ static void doDie(int sig) # define MSG2 "DoDie called 5 times - unconditional exit\n" static int iRetries = 0; /* debug aid */ dbgprintf(MSG1); - if(Debug == DEBUG_FULL) - write(1, MSG1, sizeof(MSG1) - 1); + if(Debug == DEBUG_FULL) { + if(write(1, MSG1, sizeof(MSG1) - 1)) {} + } if(iRetries++ == 4) { - if(Debug == DEBUG_FULL) - write(1, MSG2, sizeof(MSG2) - 1); + if(Debug == DEBUG_FULL) { + if(write(1, MSG2, sizeof(MSG2) - 1)) {} + } abort(); } bFinished = sig; @@ -1111,7 +1111,7 @@ finalize_it: * the time being (remember that we want to restructure config processing at large!). * rgerhards, 2009-10-27 */ -rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) +rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName, struct cnfparamvals *queueParams) { struct queuefilenames_s *qfn; uchar *qfname = NULL; @@ -1119,11 +1119,6 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) uchar qfrenamebuf[1024]; DEFiRet; - /* switch the message object to threaded operation, if necessary */ - if(ourConf->globals.mainQ.MainMsgQueType == QUEUETYPE_DIRECT || ourConf->globals.mainQ.iMainMsgQueueNumWorkers > 1) { - MsgEnableThreadSafety(); - } - /* create message queue */ CHKiRet_Hdlr(qqueueConstruct(ppQueue, ourConf->globals.mainQ.MainMsgQueType, ourConf->globals.mainQ.iMainMsgQueueNumWorkers, ourConf->globals.mainQ.iMainMsgQueueSize, msgConsumer)) { /* no queue is fatal, we need to give up in that case... */ @@ -1132,60 +1127,65 @@ rsRetVal createMainQueue(qqueue_t **ppQueue, uchar *pszQueueName) /* name our main queue object (it's not fatal if it fails...) */ obj.SetName((obj_t*) (*ppQueue), pszQueueName); - /* ... set some properties ... */ -# define setQPROP(func, directive, data) \ - CHKiRet_Hdlr(func(*ppQueue, data)) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } -# define setQPROPstr(func, directive, data) \ - CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ - errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ - } + if(queueParams == NULL) { /* use legacy parameters? */ + /* ... set some properties ... */ + # define setQPROP(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data)) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } + # define setQPROPstr(func, directive, data) \ + CHKiRet_Hdlr(func(*ppQueue, data, (data == NULL)? 0 : strlen((char*) data))) { \ + errmsg.LogError(0, NO_ERRCODE, "Invalid " #directive ", error %d. Ignored, running with default setting", iRet); \ + } - if(ourConf->globals.mainQ.pszMainMsgQFName != NULL) { - /* check if the queue file name is unique, else emit an error */ - for(qfn = queuefilenames ; qfn != NULL ; qfn = qfn->next) { - dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, ourConf->globals.mainQ.pszMainMsgQFName ); - if(!ustrcmp(qfn->name, ourConf->globals.mainQ.pszMainMsgQFName)) { - snprintf((char*)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", - ++qfn_renamenum, ourConf->globals.mainQ.pszMainMsgQFName, - (pszQueueName == NULL) ? "NONAME" : (char*)pszQueueName); - qfname = ustrdup(qfrenamebuf); - errmsg.LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " - " - using '%s' instead", ourConf->globals.mainQ.pszMainMsgQFName, qfname); - break; + if(ourConf->globals.mainQ.pszMainMsgQFName != NULL) { + /* check if the queue file name is unique, else emit an error */ + for(qfn = queuefilenames ; qfn != NULL ; qfn = qfn->next) { + dbgprintf("check queue file name '%s' vs '%s'\n", qfn->name, ourConf->globals.mainQ.pszMainMsgQFName ); + if(!ustrcmp(qfn->name, ourConf->globals.mainQ.pszMainMsgQFName)) { + snprintf((char*)qfrenamebuf, sizeof(qfrenamebuf), "%d-%s-%s", + ++qfn_renamenum, ourConf->globals.mainQ.pszMainMsgQFName, + (pszQueueName == NULL) ? "NONAME" : (char*)pszQueueName); + qfname = ustrdup(qfrenamebuf); + errmsg.LogError(0, NO_ERRCODE, "Error: queue file name '%s' already in use " + " - using '%s' instead", ourConf->globals.mainQ.pszMainMsgQFName, qfname); + break; + } } + if(qfname == NULL) + qfname = ustrdup(ourConf->globals.mainQ.pszMainMsgQFName); + qfn = malloc(sizeof(struct queuefilenames_s)); + qfn->name = qfname; + qfn->next = queuefilenames; + queuefilenames = qfn; } - if(qfname == NULL) - qfname = ustrdup(ourConf->globals.mainQ.pszMainMsgQFName); - qfn = malloc(sizeof(struct queuefilenames_s)); - qfn->name = qfname; - qfn->next = queuefilenames; - queuefilenames = qfn; - } - setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); - setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); - setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); - setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); - setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); - setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); - setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown ); - setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); - setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); - setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); - setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); - setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); - setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); - setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); - setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); - setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); - setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); - setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); - setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); - -# undef setQPROP -# undef setQPROPstr + setQPROP(qqueueSetMaxFileSize, "$MainMsgQueueFileSize", ourConf->globals.mainQ.iMainMsgQueMaxFileSize); + setQPROP(qqueueSetsizeOnDiskMax, "$MainMsgQueueMaxDiskSpace", ourConf->globals.mainQ.iMainMsgQueMaxDiskSpace); + setQPROP(qqueueSetiDeqBatchSize, "$MainMsgQueueDequeueBatchSize", ourConf->globals.mainQ.iMainMsgQueDeqBatchSize); + setQPROPstr(qqueueSetFilePrefix, "$MainMsgQueueFileName", qfname); + setQPROP(qqueueSetiPersistUpdCnt, "$MainMsgQueueCheckpointInterval", ourConf->globals.mainQ.iMainMsgQPersistUpdCnt); + setQPROP(qqueueSetbSyncQueueFiles, "$MainMsgQueueSyncQueueFiles", ourConf->globals.mainQ.bMainMsgQSyncQeueFiles); + setQPROP(qqueueSettoQShutdown, "$MainMsgQueueTimeoutShutdown", ourConf->globals.mainQ.iMainMsgQtoQShutdown ); + setQPROP(qqueueSettoActShutdown, "$MainMsgQueueTimeoutActionCompletion", ourConf->globals.mainQ.iMainMsgQtoActShutdown); + setQPROP(qqueueSettoWrkShutdown, "$MainMsgQueueWorkerTimeoutThreadShutdown", ourConf->globals.mainQ.iMainMsgQtoWrkShutdown); + setQPROP(qqueueSettoEnq, "$MainMsgQueueTimeoutEnqueue", ourConf->globals.mainQ.iMainMsgQtoEnq); + setQPROP(qqueueSetiHighWtrMrk, "$MainMsgQueueHighWaterMark", ourConf->globals.mainQ.iMainMsgQHighWtrMark); + setQPROP(qqueueSetiLowWtrMrk, "$MainMsgQueueLowWaterMark", ourConf->globals.mainQ.iMainMsgQLowWtrMark); + setQPROP(qqueueSetiDiscardMrk, "$MainMsgQueueDiscardMark", ourConf->globals.mainQ.iMainMsgQDiscardMark); + setQPROP(qqueueSetiDiscardSeverity, "$MainMsgQueueDiscardSeverity", ourConf->globals.mainQ.iMainMsgQDiscardSeverity); + setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", ourConf->globals.mainQ.iMainMsgQWrkMinMsgs); + setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", ourConf->globals.mainQ.bMainMsgQSaveOnShutdown); + setQPROP(qqueueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", ourConf->globals.mainQ.iMainMsgQDeqSlowdown); + setQPROP(qqueueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", ourConf->globals.mainQ.iMainMsgQueueDeqtWinFromHr); + setQPROP(qqueueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", ourConf->globals.mainQ.iMainMsgQueueDeqtWinToHr); + + # undef setQPROP + # undef setQPROPstr + } else { /* use new style config! */ + qqueueSetDefaultsRulesetQueue(*ppQueue); + qqueueApplyCnfParam(*ppQueue, queueParams); + } /* ... and finally start the queue! */ CHKiRet_Hdlr(qqueueStart(*ppQueue)) { @@ -2032,6 +2032,8 @@ int realMain(int argc, char **argv) } localRet = rsconf.Load(&ourConf, ConfFile); + queryLocalHostname(); /* need to re-query to pick up a changed hostname due to config */ + if(localRet == RS_RET_NONFATAL_CONFIG_ERR) { if(loadConf->globals.bAbortOnUncleanConfig) { fprintf(stderr, "rsyslogd: $AbortOnUncleanConfig is set, and config is not clean.\n" |