summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog114
-rw-r--r--action.c8
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac2
-rw-r--r--dirty.h2
-rw-r--r--doc/imklog.html13
-rw-r--r--doc/imptcp.html18
-rw-r--r--doc/manual.html2
-rw-r--r--grammar/rainerscript.c30
-rw-r--r--grammar/rainerscript.h1
-rw-r--r--plugins/imdiag/imdiag.c1
-rw-r--r--plugins/imklog/bsd.c49
-rw-r--r--plugins/imklog/imklog.c23
-rw-r--r--plugins/imklog/imklog.h2
-rw-r--r--plugins/imptcp/imptcp.c2
-rw-r--r--plugins/imuxsock/imuxsock.c10
-rw-r--r--plugins/mmjsonparse/mmjsonparse.c2
-rw-r--r--plugins/mmnormalize/mmnormalize.c2
-rw-r--r--plugins/mmsnmptrapd/mmsnmptrapd.c1
-rw-r--r--plugins/ommail/ommail.c1
-rw-r--r--plugins/omprog/omprog.c7
-rw-r--r--plugins/omrelp/omrelp.c1
-rw-r--r--plugins/omruleset/omruleset.c1
-rw-r--r--plugins/omstdout/omstdout.c9
-rw-r--r--plugins/omtesting/omtesting.c1
-rw-r--r--runtime/datetime.c5
-rw-r--r--runtime/debug.c8
-rw-r--r--runtime/module-template.h2
-rw-r--r--runtime/msg.c146
-rw-r--r--runtime/msg.h12
-rw-r--r--runtime/queue.c44
-rw-r--r--runtime/queue.h2
-rw-r--r--runtime/rsconf.c8
-rw-r--r--runtime/ruleset.c25
-rw-r--r--template.c17
-rw-r--r--tools/pidfile.c6
-rw-r--r--tools/syslogd.c136
37 files changed, 426 insertions, 307 deletions
diff --git a/ChangeLog b/ChangeLog
index a9e7e17..89238d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/action.c b/action.c
index ca260f9..dbd4e70 100644
--- a/action.c
+++ b/action.c
@@ -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
diff --git a/configure b/configure
index e62d6ec..65f5579 100755
--- a/configure
+++ b/configure
@@ -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])])
diff --git a/dirty.h b/dirty.h
index a3940cb..3a1a995 100644
--- a/dirty.h
+++ b/dirty.h
@@ -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 &lt;number&gt;<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> &lt;Delimiter&gt;<br>
+<li><b>AddtlFrameDelimiter</b> &lt;Delimiter&gt;<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 &lt;Delimiter&gt;<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 &copy; 2010 by <a href="http://www.gerhards.net/rainer">Rainer
+Copyright &copy; 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:
diff --git a/template.c b/template.c
index 1b8b218..8427e85 100644
--- a/template.c
+++ b/template.c
@@ -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"