diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | doc/features.html | 1 | ||||
-rw-r--r-- | doc/rsconf1_maxopenfiles.html | 35 | ||||
-rw-r--r-- | doc/rsyslog_conf.html | 6 | ||||
-rw-r--r-- | doc/rsyslog_conf_global.html | 18 | ||||
-rw-r--r-- | doc/status.html | 8 | ||||
-rw-r--r-- | plugins/im3195/im3195.c | 3 | ||||
-rw-r--r-- | plugins/omdtn/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/omdtn/omdtn.c | 130 | ||||
-rw-r--r-- | plugins/omprog/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/omprog/omprog.c | 357 | ||||
-rw-r--r-- | runtime/conf.c | 1 | ||||
-rw-r--r-- | runtime/rsyslog.h | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 5 | ||||
-rwxr-xr-x | tests/manytcp.sh | 18 | ||||
-rwxr-xr-x | tests/tcpflood | bin | 17972 -> 0 bytes | |||
-rw-r--r-- | tests/tcpflood.c | 68 | ||||
-rw-r--r-- | tests/testsuites/manytcp.conf | 13 | ||||
-rw-r--r-- | tools/omfile.c | 4 | ||||
-rw-r--r-- | tools/syslogd.c | 28 |
22 files changed, 581 insertions, 181 deletions
@@ -1,5 +1,8 @@ --------------------------------------------------------------------------- Version 4.3.0 [DEVEL] (rgerhards), 2009-03-?? +- new feature: new output plugin omprog, which permits to start program + and feed it (via its stdin) with syslog messages. If the program + terminates, it is restarted. - improved internal handling of RainerScript functions, building the necessary plumbing to support more functions with decent runtime performance. This is also necessary towards the long-term goal @@ -8,12 +11,16 @@ Version 4.3.0 [DEVEL] (rgerhards), 2009-03-?? - improved testbench * added tests for tcp-based reception * added tcp-load test (1000 connections, 20,000 messages) +- added $MaxOpenFiles configuration directive - bugfix: solved potential memory leak in msg processing, could manifest itself in imtcp --------------------------------------------------------------------------- Version 4.1.7 [BETA] (rgerhards), 2009-04-?? - bugfix: $InputTCPMaxSessions config directive was accepted, but not honored. This resulted in a fixed upper limit of 200 connections. +- bugfix: the default for $DirCreateMode was 0644, and as such wrong. + It has now been changed to 0700. For some background, please see + http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html --------------------------------------------------------------------------- Version 4.1.6 [DEVEL] (rgerhards), 2009-04-07 - added new "csv" property replacer options to enable simple creation @@ -154,6 +161,9 @@ version before switching to this one. Version 3.22.0 [v3-stable] (rgerhards), 2009-04-?? - bugfix: $InputTCPMaxSessions config directive was accepted, but not honored. This resulted in a fixed upper limit of 200 connections. +- bugfix: the default for $DirCreateMode was 0644, and as such wrong. + It has now been changed to 0700. For some background, please see + http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html --------------------------------------------------------------------------- Version 3.21.11 [BETA] (rgerhards), 2009-04-03 - build system improvements contributed by Michael Biebl - thx! @@ -309,9 +319,13 @@ Version 3.21.0 [DEVEL] (rgerhards), 2008-07-18 - imported all changes from 3.18.1 until today (some quite important, see below) --------------------------------------------------------------------------- -Version 3.20.6 [v3-stable] (rgerhards), 2009-04-?? +Version 3.20.6 [v3-stable] (rgerhards), 2009-04-16 +- this is the last v3-stable for the 3.20.x series - bugfix: $InputTCPMaxSessions config directive was accepted, but not honored. This resulted in a fixed upper limit of 200 connections. +- bugfix: the default for $DirCreateMode was 0644, and as such wrong. + It has now been changed to 0700. For some background, please see + http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html --------------------------------------------------------------------------- Version 3.20.5 [v3-stable] (rgerhards), 2009-04-02 - bugfix: potential abort with DA queue after high watermark is reached @@ -556,7 +570,9 @@ Version 3.19.0 (rgerhards), 2008-05-06 for the patch --------------------------------------------------------------------------- Version 3.18.7 (rgerhards), 2008-12-?? -======= +- bugfix: the default for $DirCreateMode was 0644, and as such wrong. + It has now been changed to 0700. For some background, please see + http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html - fixed a potential segfault condition with $AllowedSender directive On HUP, the root pointers were not properly cleaned up. Thanks to Michael Biebel, olgoat, and Juha Koho for reporting and analyzing @@ -1242,7 +1258,10 @@ Version 3.10.0 (rgerhards), 2008-01-07 - much cleaner code due to new objects and removal of single-threading mode --------------------------------------------------------------------------- -Version 2.0.7 V2-STABLE (rgerhards), 2008-??-?? +Version 2.0.7 V2-STABLE (rgerhards), 2008-04-14 +- bugfix: the default for $DirCreateMode was 0644, and as such wrong. + It has now been changed to 0700. For some background, please see + http://lists.adiscon.net/pipermail/rsyslog/2009-April/001986.html - bugfix: "$CreateDirs off" also disabled file creation Thanks to William Tisater for analyzing this bug and providing a patch. The actual code change is heavily based on William's patch. diff --git a/Makefile.am b/Makefile.am index dfb33339..a5cf879c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -108,6 +108,10 @@ if ENABLE_MAIL SUBDIRS += plugins/ommail endif +if ENABLE_OMPROG +SUBDIRS += plugins/omprog +endif + if ENABLE_RFC3195 SUBDIRS += plugins/im3195 endif @@ -127,5 +131,5 @@ SUBDIRS += tests # temporarily be removed below. The intent behind forcing everthing to compile # in a make distcheck is so that we detect code that accidently was not updated # when some global update happened. -DISTCHECK_CONFIGURE_FLAGS=--enable-gssapi_krb5 --enable-imfile --enable-snmp --enable-pgsql --enable-libdbi --enable-mysql --enable-omtemplate --enable-imtemplate --enable-relp --enable-rsyslogd --enable-mail --enable-klog --enable-diagtools --enable-gnutls --enable-omstdout --enable-oracle +DISTCHECK_CONFIGURE_FLAGS=--enable-gssapi_krb5 --enable-imfile --enable-snmp --enable-pgsql --enable-libdbi --enable-mysql --enable-omtemplate --enable-imtemplate --enable-relp --enable-rsyslogd --enable-mail --enable-klog --enable-diagtools --enable-gnutls --enable-omstdout --enable-omprog ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index cd950071..c7f1d532 100644 --- a/configure.ac +++ b/configure.ac @@ -700,6 +700,20 @@ AM_CONDITIONAL(ENABLE_IMTEMPLATE, test x$enable_imtemplate = xyes) # end of copy template - be sure to serach for imtemplate to find everything! +# settings for the omprog output module +AC_ARG_ENABLE(omprog, + [AS_HELP_STRING([--enable-omprog],[Compiles omprog template module @<:@default=no@:>@])], + [case "${enableval}" in + yes) enable_omprog="yes" ;; + no) enable_omprog="no" ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-omprog) ;; + esac], + [enable_omprog=no] +) +AM_CONDITIONAL(ENABLE_OMPROG, test x$enable_omprog = xyes) +# end of omprog + + # settings for the template output module; copy and modify this code # if you intend to add your own module. Be sure to replace omtemplate # by the actual name of your module. @@ -752,6 +766,7 @@ AC_CONFIG_FILES([Makefile \ plugins/imklog/Makefile \ plugins/imtemplate/Makefile \ plugins/omtemplate/Makefile \ + plugins/omprog/Makefile \ plugins/omstdout/Makefile \ plugins/imfile/Makefile \ plugins/imrelp/Makefile \ @@ -786,6 +801,7 @@ echo "imdiag enabled: $enable_imdiag" echo "file input module enabled: $enable_imfile" echo "input template module will be compiled: $enable_imtemplate" echo "output template module will be compiled: $enable_omtemplate" +echo "omprog module will be compiled: $enable_omprog" echo "omstdout module will be compiled: $enable_omstdout" echo "Large file support enabled: $enable_largefile" echo "Networking support enabled: $enable_inet" diff --git a/doc/features.html b/doc/features.html index 17a995bf..626ff65d 100644 --- a/doc/features.html +++ b/doc/features.html @@ -127,7 +127,6 @@ community. Plus, it can be financially attractive: just think about how much les be to sponsor a feature instead of purchasing a commercial implementation. Also, the benefit of being recognised as a sponsor may even drive new customers to your business!</b> <ul> -<li>Finalize the DTN "planetary Internet" space ship mode output plugin <li>port it to more *nix variants (eg AIX and HP UX) - this needs volunteers with access to those machines and knowledge </li> <li>pcre filtering - maybe (depending on feedback) - diff --git a/doc/rsconf1_maxopenfiles.html b/doc/rsconf1_maxopenfiles.html new file mode 100644 index 00000000..b6c9cc0e --- /dev/null +++ b/doc/rsconf1_maxopenfiles.html @@ -0,0 +1,35 @@ +<html> +<head> +<title>$MaxOpenFiles - rsyslog.conf file</title> +</head> +<body> +<a href="rsyslog_conf_global.html">[rsyslog configuration directive overview]</a> + +<h2>$MaxOpenFiles</h2> +<p><b>Available Since:</b> 4.3.0</p> +<p><b>Type:</b> global configuration directive</p> +<p><b>Default:</b> <i>operating system default</i></p> +<p><b>Description:</b></p> +<p>Set the maximum number of files that the rsyslog process can have open at any given +time. Note that this includes open tcp sockets, so this setting is the upper limit for +the number of open TCP connections as well. If you expect a large nubmer of concurrent +connections, it is suggested that the number is set to the max number connected plus 1000. +Please note that each dynafile also requires up to 100 open file handles. +<p>The setting is similar to running "ulimit -n number-of-files". +<p>Please note that depending on permissions and operating system configuration, the +setrlimit() request issued by rsyslog may fail, in which case the previous limit is kept +in effect. Rsyslog will emit a warning message in this case. +<p><b>Sample:</b></p> +<p><code><b>$MaxOpenFiles 2000</b></code></p> +<p><b>Bugs:</b></p> +<p>For some reason, this settings seems not to work on all platforms. If you experience +problems, please let us know so that we can (hopefully) narrow down the issue. +<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>] [<a href="manual.html">manual +index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> +<p><font size="2">This documentation is part of the +<a href="http://www.rsyslog.com/">rsyslog</a> project.<br> +Copyright © 2009 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> +</body> +</html> diff --git a/doc/rsyslog_conf.html b/doc/rsyslog_conf.html index 852d95b5..6990c6bd 100644 --- a/doc/rsyslog_conf.html +++ b/doc/rsyslog_conf.html @@ -26,7 +26,7 @@ Lines can be continued by specifying a backslash ("\") as the last character of the line. There is a hard-coded maximum line length of 4K. If you need lines larger than that, you need to change compile-time settings inside rsyslog and recompile. -<h2><a href="rsyslog_conf_global.html">Global Directives</a></h2> +<h2><a href="rsyslog_conf_global.html">Configuration Directives</a></h2> <h2>Basic Structure</h2> <p>Rsyslog supports standard sysklogd's configuration file format and extends it. So in general, you can take a "normal" syslog.conf and @@ -74,9 +74,9 @@ such features is available in rsyslogd, only.</p> [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> <p><font size="2">This documentation is part of the <a href="http://www.rsyslog.com/">rsyslog</a> project.<br> -Copyright © 2008 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and +Copyright © 2008,2009 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 2 or higher.</font></p> +version 3 or higher.</font></p> </body> </html> > diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index d011bd2b..3e33f0da 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -1,14 +1,14 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html><head><title>Global Directives - rsyslog.conf</title></head> +<html><head><title>Configuration Directives - rsyslog.conf</title></head> <body> <p>This is a part of the rsyslog.conf documentation.</p> <a href="rsyslog_conf.html">back</a> -<h2>Global Directives</h2> -<p>All global directives need to be specified on a line by their -own and must start with a dollar-sign. Here is a list in alphabetical -order. Follow links for a description.</p> -<p>Please note that not all directives here are actually global. Some affect -only the next action. This documentation will be changed soon. +<h2>Configuration Directives</h2> +<p>All configuration directives need to be specified on a line by their +own and must start with a dollar-sign. Note that those starting with +the word "Action" modify the next action and should be specified +in front of it. +<p>Here is a list in alphabetical order. Follow links for a description.</p> <p>Not all directives have an in-depth description right now. Default values for them are in bold. A more in-depth description will appear as implementation progresses. @@ -180,6 +180,7 @@ instead of UDP (plain TCP syslog, RELP). This resolves the UDP stack size restri <br>Note that 2k, the current default, is the smallest size that must be supported in order to be compliant to the upcoming new syslog RFC series. </li> +<li><a href="rsconf1_maxopenfiles.html">$MaxOpenFiles</a></li> <li><a href="rsconf1_moddir.html">$ModDir</a></li> <li><a href="rsconf1_modload.html">$ModLoad</a></li> <li><b>$RepeatedMsgContainsOriginalMsg</b> [on/<b>off</b>] - "last message repeated n times" messages, if generated, @@ -214,7 +215,6 @@ the value, the less precise the timestamp. <li><a href="droppriv.html">$PrivDropToGroupID</a></li> <li><a href="droppriv.html">$PrivDropToUser</a></li> <li><a href="droppriv.html">$PrivDropToUserID</a></li> -</ul> <li><a href="rsconf1_umask.html">$UMASK</a></li> </ul> <p><b>Where <size_nbr> is specified above,</b> @@ -235,7 +235,7 @@ point of view, "1,,0.0.,.,0" also has the value 1000. </p> <a href="http://www.rsyslog.com/">rsyslog</a> project.<br> Copyright © 2008, 2009 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 2 or higher.</font></p> +version 3 or higher.</font></p> </body> </html> diff --git a/doc/status.html b/doc/status.html index dae94884..fff3a6ff 100644 --- a/doc/status.html +++ b/doc/status.html @@ -5,15 +5,15 @@ <p>This page reflects the status as of 2009-04-03.</p> <h2>Current Releases</h2> -<p><b>development:</b> 4.1.5 [2009-03-11] - -<a href="http://www.rsyslog.com/Article349.phtml">change log</a> - -<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-150.phtml">download</a> +<p><b>development:</b> 4.1.6 [2009-04-07] - +<a href="http://www.rsyslog.com/Article360.phtml">change log</a> - +<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-153.phtml">download</a> <br><b>beta:</b> 3.21.11 [2009-04-03] - <a href="http://www.rsyslog.com/Article358.phtml">change log</a> - <a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-152.phtml">download</a></p> -<p><b>v3 stable:</b> 3.20.3 [2009-04-02] - <a href="http://www.rsyslog.com/Article356.phtml">change log</a> - +<p><b>v3 stable:</b> 3.20.5 [2009-04-02] - <a href="http://www.rsyslog.com/Article356.phtml">change log</a> - <a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-151.phtml">download</a> <br><b>v2 stable:</b> 2.0.6 [2008-08-07] - <a href="http://www.rsyslog.com/Article266.phtml">change log</a> - diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c index 1c2502fe..106da2c8 100644 --- a/plugins/im3195/im3195.c +++ b/plugins/im3195/im3195.c @@ -47,6 +47,7 @@ #include "liblogging/syslogmessage.h" #include "module-template.h" #include "cfsysline.h" +#include "msg.h" #include "errmsg.h" MODULE_TYPE_INPUT @@ -83,7 +84,7 @@ void OnReceive(srAPIObj __attribute__((unused)) *pMyAPI, srSLMGObj* pSLMG) srSLMGGetRawMSG(pSLMG, &pszRawMsg); parseAndSubmitMessage(fromHost, fromHostIP, pszRawMsg, strlen((char*)pszRawMsg), - MSG_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_FULL_DELAY, (uchar*)"im3195"); + PARSE_HOSTNAME, eFLOWCTL_FULL_DELAY, (uchar*)"im3195", NULL, 0); } diff --git a/plugins/omdtn/Makefile.am b/plugins/omdtn/Makefile.am deleted file mode 100644 index afb57476..00000000 --- a/plugins/omdtn/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -pkglib_LTLIBRARIES = omdtn.la - -omdtn_la_SOURCES = omdtn.c -omdtn_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) -omdtn_la_LDFLAGS = -module -avoid-version -omdtn_la_LIBADD = - -EXTRA_DIST = diff --git a/plugins/omdtn/omdtn.c b/plugins/omdtn/omdtn.c deleted file mode 100644 index 761bde79..00000000 --- a/plugins/omdtn/omdtn.c +++ /dev/null @@ -1,130 +0,0 @@ -/* omdtn.c - * This is the plugin for rsyslog use in the interplanetary Internet, - * especially useful for rsyslog in space ships of all kinds. - * The core idea was introduced in early 2009 and considered - * doable. - * - * Note that this has not yet been tested for robustness but needs - * to prior to placing it on top of a rocket. - * - * NOTE: read comments in module-template.h for more specifics! - * - * File begun on 2009-04-01 by RGerhards - * - * Copyright 2009 Rainer Gerhards and Adiscon GmbH. - * - * This file is part of rsyslog. - * - * Rsyslog is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Rsyslog is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. - * - * A copy of the GPL can be found in the file "COPYING" in this distribution. - */ -#include "config.h" -#include "rsyslog.h" -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <signal.h> -#include <errno.h> -#include <unistd.h> -#include "dirty.h" -#include "syslogd-types.h" -#include "srUtils.h" -#include "template.h" -#include "module-template.h" -#include "errmsg.h" -#include "cfsysline.h" - -MODULE_TYPE_OUTPUT - -/* internal structures - */ -DEF_OMOD_STATIC_DATA - -typedef struct _instanceData { -} instanceData; - -BEGINcreateInstance -CODESTARTcreateInstance -ENDcreateInstance - - -BEGINisCompatibleWithFeature -CODESTARTisCompatibleWithFeature - if(eFeat == sFEATURERepeatedMsgReduction) - iRet = RS_RET_OK; -ENDisCompatibleWithFeature - - -BEGINfreeInstance -CODESTARTfreeInstance -ENDfreeInstance - - -BEGINdbgPrintInstInfo -CODESTARTdbgPrintInstInfo -ENDdbgPrintInstInfo - - -BEGINtryResume -CODESTARTtryResume -ENDtryResume - -BEGINdoAction -CODESTARTdoAction - write(1, (char*)ppString[0], strlen((char*)ppString[0])); -ENDdoAction - - -BEGINparseSelectorAct -CODESTARTparseSelectorAct -CODE_STD_STRING_REQUESTparseSelectorAct(1) - /* first check if this config line is actually for us */ - if(strncmp((char*) p, ":omstdout:", sizeof(":omstdout:") - 1)) { - ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); - } - - /* ok, if we reach this point, we have something for us */ - p += sizeof(":omstdout:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ - CHKiRet(createInstance(&pData)); - - /* check if a non-standard template is to be applied */ - if(*(p-1) == ';') - --p; - CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat")); -CODE_STD_FINALIZERparseSelectorAct -ENDparseSelectorAct - - -BEGINmodExit -CODESTARTmodExit -ENDmodExit - - -BEGINqueryEtryPt -CODESTARTqueryEtryPt -CODEqueryEtryPt_STD_OMOD_QUERIES -ENDqueryEtryPt - - -BEGINmodInit() -CODESTARTmodInit - *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ -CODEmodInit_QueryRegCFSLineHdlr -ENDmodInit - -/* vi:set ai: - */ diff --git a/plugins/omprog/Makefile.am b/plugins/omprog/Makefile.am new file mode 100644 index 00000000..63fe09b8 --- /dev/null +++ b/plugins/omprog/Makefile.am @@ -0,0 +1,8 @@ +pkglib_LTLIBRARIES = omprog.la + +omprog_la_SOURCES = omprog.c +omprog_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) +omprog_la_LDFLAGS = -module -avoid-version +omprog_la_LIBADD = + +EXTRA_DIST = diff --git a/plugins/omprog/omprog.c b/plugins/omprog/omprog.c new file mode 100644 index 00000000..2a078a6d --- /dev/null +++ b/plugins/omprog/omprog.c @@ -0,0 +1,357 @@ +/* omprog.c + * This output plugin enables rsyslog to execute a program and + * feed it the message stream as standard input. + * + * NOTE: read comments in module-template.h for more specifics! + * + * File begun on 2009-04-01 by RGerhards + * + * Copyright 2009 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include "rsyslog.h" +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <signal.h> +#include <errno.h> +#include <unistd.h> +#include <wait.h> +#include "dirty.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "template.h" +#include "module-template.h" +#include "errmsg.h" +#include "cfsysline.h" + +MODULE_TYPE_OUTPUT + +/* internal structures + */ +DEF_OMOD_STATIC_DATA +DEFobjCurrIf(errmsg) + +typedef struct _instanceData { + uchar *szBinary; /* name of binary to call */ + pid_t pid; /* pid of currently running process */ + int fdPipe; /* file descriptor to write to */ + int bIsRunning; /* is binary currently running? 0-no, 1-yes */ +} instanceData; + +/* config settings */ +static uchar *szBinary = NULL; /* name of binary to call */ + +BEGINcreateInstance +CODESTARTcreateInstance +ENDcreateInstance + + +BEGINisCompatibleWithFeature +CODESTARTisCompatibleWithFeature + if(eFeat == sFEATURERepeatedMsgReduction) + iRet = RS_RET_OK; +ENDisCompatibleWithFeature + + +BEGINfreeInstance +CODESTARTfreeInstance + if(pData->szBinary != NULL) + free(pData->szBinary); +ENDfreeInstance + + +BEGINdbgPrintInstInfo +CODESTARTdbgPrintInstInfo +ENDdbgPrintInstInfo + + +BEGINtryResume +CODESTARTtryResume +ENDtryResume + + +/* execute the child process (must be called in child context + * after fork). + */ + +static void execBinary(instanceData *pData, int fdStdin) +{ + int i; + struct sigaction sigAct; + char *newargv[] = { NULL }; + char *newenviron[] = { NULL }; + + assert(pData != NULL); + + fclose(stdin); + dup(fdStdin); + //fclose(stdout); + + /* we close all file handles as we fork soon + * Is there a better way to do this? - mail me! rgerhards@adiscon.com + */ +# ifndef VALGRIND /* we can not use this with valgrind - too many errors... */ + for(i = 3 ; i <= 65535 ; ++i) + close(i); +# endif + + /* reset signal handlers to default */ + memset(&sigAct, 0, sizeof(sigAct)); + sigfillset(&sigAct.sa_mask); + sigAct.sa_handler = SIG_DFL; + for(i = 1 ; i < NSIG ; ++i) + sigaction(i, &sigAct, NULL); + + alarm(0); + + /* finally exec child */ + execve((char*)pData->szBinary, newargv, newenviron); + /* switch to? + execlp((char*)program, (char*) program, (char*)arg, NULL); + */ + + /* we should never reach this point, but if we do, we terminate */ + exit(1); +} + + +/* creates a pipe and starts program, uses pipe as stdin for program. + * rgerhards, 2009-04-01 + */ +static rsRetVal +openPipe(instanceData *pData) +{ + int pipefd[2]; + pid_t cpid; + DEFiRet; + + assert(pData != NULL); + + if(pipe(pipefd) == -1) { + ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE); + } + + DBGPRINTF("executing program '%s'\n", pData->szBinary); + + /* NO OUTPUT AFTER FORK! */ + + cpid = fork(); + if(cpid == -1) { + ABORT_FINALIZE(RS_RET_ERR_FORK); + } + + if(cpid == 0) { + /* we are now the child, just set the right selectors and + * exec the binary. If that fails, there is not much we can do. + */ + close(pipefd[1]); + execBinary(pData, pipefd[0]); + /*NO CODE HERE - WILL NEVER BE REACHED!*/ + } + + DBGPRINTF("child has pid %d\n", cpid); + pData->fdPipe = pipefd[1]; + pData->pid = cpid; + close(pipefd[0]); + pData->bIsRunning = 1; +finalize_it: + RETiRet; +} + + +/* clean up after a terminated child + */ +static inline rsRetVal +cleanup(instanceData *pData) +{ + int status; + int ret; + char errStr[1024]; + DEFiRet; + + assert(pData != NULL); + assert(pData->bIsRunning == 1); +RUNLOG_VAR("%d", pData->pid); + ret = waitpid(pData->pid, &status, 0); + if(ret != pData->pid) { + /* if waitpid() fails, we can not do much - try to ignore it... */ + DBGPRINTF("waitpid() returned state %d[%s], future malfunction may happen\n", ret, + rs_strerror_r(errno, errStr, sizeof(errStr))); + } else { + /* check if we should print out some diagnostic information */ + DBGPRINTF("waitpid status return for program '%s': %2.2x\n", + pData->szBinary, status); + if(WIFEXITED(status)) { + errmsg.LogError(0, NO_ERRCODE, "program '%s' exited normally, state %d", + pData->szBinary, WEXITSTATUS(status)); + } else if(WIFSIGNALED(status)) { + errmsg.LogError(0, NO_ERRCODE, "program '%s' terminated by signal %d.", + pData->szBinary, WTERMSIG(status)); + } + } + + pData->bIsRunning = 0; + RETiRet; +} + + +/* try to restart the binary when it has stopped. + */ +static inline rsRetVal +tryRestart(instanceData *pData) +{ + DEFiRet; + assert(pData != NULL); + assert(pData->bIsRunning == 0); + + iRet = openPipe(pData); + RETiRet; +} + + +/* write to pipe + * note that we do not try to run block-free. If the users fears something + * may block (and this not be acceptable), the action should be run on its + * own action queue. + */ +static rsRetVal +writePipe(instanceData *pData, uchar *szMsg) +{ + int lenWritten; + int lenWrite; + int writeOffset; + char errStr[1024]; + DEFiRet; + + assert(pData != NULL); + + lenWrite = strlen((char*)szMsg); + writeOffset = 0; + + do + { + lenWritten = write(pData->fdPipe, ((char*)szMsg)+writeOffset, lenWrite); + if(lenWritten == -1) { + switch(errno) { + case EPIPE: + DBGPRINTF("Program '%s' terminated, trying to restart\n", + pData->szBinary); + CHKiRet(cleanup(pData)); + CHKiRet(tryRestart(pData)); + break; + default: + DBGPRINTF("error %d writing to pipe: %s\n", errno, + rs_strerror_r(errno, errStr, sizeof(errStr))); + ABORT_FINALIZE(RS_RET_ERR_WRITE_PIPE); + break; + } + } else { + writeOffset += lenWritten; + } + } while(lenWritten != lenWrite); + + +finalize_it: + RETiRet; +} + + +BEGINdoAction +CODESTARTdoAction + if(pData->bIsRunning == 0) { + openPipe(pData); + } + + iRet = writePipe(pData, ppString[0]); + + if(iRet != RS_RET_OK) + iRet = RS_RET_SUSPENDED; +ENDdoAction + + +BEGINparseSelectorAct +CODESTARTparseSelectorAct +CODE_STD_STRING_REQUESTparseSelectorAct(1) + /* first check if this config line is actually for us */ + if(strncmp((char*) p, ":omprog:", sizeof(":omprog:") - 1)) { + ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED); + } + + /* ok, if we reach this point, we have something for us */ + p += sizeof(":omprog:") - 1; /* eat indicator sequence (-1 because of '\0'!) */ + CHKiRet(createInstance(&pData)); + + CHKmalloc(pData->szBinary = (uchar*) strdup((char*)szBinary)); + /* check if a non-standard template is to be applied */ + if(*(p-1) == ';') + --p; + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat")); +CODE_STD_FINALIZERparseSelectorAct +ENDparseSelectorAct + + +BEGINmodExit +CODESTARTmodExit + if(szBinary != NULL) { + free(szBinary); + szBinary = NULL; + } + CHKiRet(objRelease(errmsg, CORE_COMPONENT)); +finalize_it: +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_OMOD_QUERIES +ENDqueryEtryPt + + + +/* Reset config variables for this module to default values. + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + DEFiRet; + + if(szBinary != NULL) { + free(szBinary); + szBinary = NULL; + } + + RETiRet; +} + + +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomprogbinary", 0, eCmdHdlrGetWord, NULL, &szBinary, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +CODEmodInit_QueryRegCFSLineHdlr +ENDmodInit + +/* vi:set ai: + */ diff --git a/runtime/conf.c b/runtime/conf.c index ede15cc7..27ab8bb4 100644 --- a/runtime/conf.c +++ b/runtime/conf.c @@ -796,7 +796,6 @@ dbgprintf("calling expression parser, pp %p ('%s')\n", *pline, *pline); /* debug support - print vmprg after construction (uncomment to use) */ /* vmprgDebugPrint(f->f_filterData.f_expr->pVmprg); */ - vmprgDebugPrint(f->f_filterData.f_expr->pVmprg); /* we now need to skip whitespace to the action part, else we confuse * the legacy rsyslog conf parser. -- rgerhards, 2008-02-25 diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 8e181b9e..026fbbed 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -262,6 +262,10 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_INVLD_FUNC = -2113, /**< invalid function name for function call (rainerscript) */ RS_RET_DUP_FUNC_NAME = -2114, /**< duplicate function name (rainerscript) */ RS_RET_UNKNW_FUNC = -2115, /**< unkown function name (rainerscript) */ + RS_RET_ERR_RLIM_NOFILE = -2116, /**< error setting max. nbr open files process limit */ + RS_RET_ERR_CREAT_PIPE = -2117, /**< error during pipe creation */ + RS_RET_ERR_FORK = -2118, /**< error during fork() */ + RS_RET_ERR_WRITE_PIPE = -2119, /**< error writing to pipe */ RS_RET_RSCORE_TOO_OLD = -2120, /**< rsyslog core is too old for ... (eg this plugin) */ /* RainerScript error messages (range 1000.. 1999) */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 53a81a93..87dca985 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,13 +28,16 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/1.omod-if-array \ parsertest.sh \ manytcp.sh \ + testsuites/manytcp.conf \ omod-if-array.sh \ cfg.sh ourtail_SOURCES = ourtail.c -tcpflood_SOURCES = tcpflood.c chkseq_SOURCES = chkseq.c +tcpflood_SOURCES = tcpflood.c +tcpflood_LDADD = $(SOL_LIBS) + nettester_SOURCES = nettester.c getline.c nettester_LDADD = $(SOL_LIBS) diff --git a/tests/manytcp.sh b/tests/manytcp.sh index 3accfb8a..d9b2e9a0 100755 --- a/tests/manytcp.sh +++ b/tests/manytcp.sh @@ -1,13 +1,21 @@ -rm -f rsyslog.out.log # work file -../tools/rsyslogd -c4 -u2 -n -irsyslog.pid -M../runtime/.libs:../.libs -ftestsuites/manytcp.conf & -echo "rsyslogd started with pid " `cat rsyslog.pid` -./tcpflood 127.0.0.1 13514 1000 20000 +rm -f work rsyslog.out.log rsyslog.out.log.save # work files +../tools/rsyslogd -c4 -u2 -n -irsyslog.pid -M../runtime/.libs:../.libs -f$srcdir/testsuites/manytcp.conf & sleep 1 +echo "rsyslogd started with pid " `cat rsyslog.pid` +# the config file specifies exactly 1100 connections +./tcpflood 127.0.0.1 13514 1000 40000 +if [ "$?" -ne "0" ]; then + echo "error during tcpflood! see rsyslog.out.log.save for what was written" + cp rsyslog.out.log rsyslog.out.log.save +fi +sleep 5 # we need this so that rsyslogd can receive all outstanding messages kill `cat rsyslog.pid` rm -f work sort < rsyslog.out.log > work -./chkseq work 0 19999 +./chkseq work 0 39999 if [ "$?" -ne "0" ]; then + rm -f work rsyslog.out.log echo "sequence error detected" exit 1 fi +rm -f work rsyslog.out.log diff --git a/tests/tcpflood b/tests/tcpflood Binary files differdeleted file mode 100755 index ae00fcd5..00000000 --- a/tests/tcpflood +++ /dev/null diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 83f0d1ee..9c17fd5b 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -95,21 +95,49 @@ int openConnections(void) sockArray = calloc(numConnections, sizeof(int)); for(i = 0 ; i < numConnections ; ++i) { if(i % 10 == 0) { - lenMsg = sprintf(msgBuf, "\retb\b\b\b\b%5.5d", i); - write(1, msgBuf, lenMsg); + printf("\r%5.5d", i); + //lenMsg = sprintf(msgBuf, "\r%5.5d", i); + //write(1, msgBuf, lenMsg); } if(openConn(&(sockArray[i])) != 0) { printf("error in trying to open connection i=%d\n", i); return 1; } } - lenMsg = sprintf(msgBuf, "\retb\b\b\b\b%5.5d open connections\n", i); + lenMsg = sprintf(msgBuf, "\r%5.5d open connections\n", i); write(1, msgBuf, lenMsg); return 0; } +/* we also close all connections because otherwise we may get very bad + * timing for the syslogd - it may not be able to process all incoming + * messages fast enough if we immediately shut down. + * TODO: it may be an interesting excercise to handle that situation + * at the syslogd level, too + * rgerhards, 2009-04-14 + */ +void closeConnections(void) +{ + int i; + char msgBuf[128]; + size_t lenMsg; + + write(1, " close connections", sizeof(" close connections")-1); + for(i = 0 ; i < numConnections ; ++i) { + if(i % 10 == 0) { + lenMsg = sprintf(msgBuf, "\r%5.5d", i); + write(1, msgBuf, lenMsg); + } + close(sockArray[i]); + } + lenMsg = sprintf(msgBuf, "\r%5.5d close connections\n", i); + write(1, msgBuf, lenMsg); + +} + + /* send messages to the tcp connections we keep open. We use * a very basic format that helps identify the message * (via msgnum:<number>: e.g. msgnum:00000001:). This format is suitable @@ -123,14 +151,15 @@ int sendMessages(void) int i; int socknum; int lenBuf; + int lenSend; char buf[2048]; char msgBuf[128]; size_t lenMsg; srand(time(NULL)); /* seed is good enough for our needs */ - lenMsg = sprintf(msgBuf, "\retb\b\b\b\b%5.5d messages sent", 0); - write(1, msgBuf, lenMsg); + printf("Sending %d messages.\n", numMsgsToSend); + printf("\r%5.5d messages sent", 0); for(i = 0 ; i < numMsgsToSend ; ++i) { if(i < numConnections) socknum = i; @@ -139,18 +168,20 @@ int sendMessages(void) else socknum = rand() % numConnections; lenBuf = sprintf(buf, "<167>Mar 1 01:00:00 172.20.245.8 tag msgnum:%8.8d:\n", i); - if(send(sockArray[socknum], buf, lenBuf, 0) != lenBuf) { + lenSend = send(sockArray[socknum], buf, lenBuf, 0); + if(lenSend != lenBuf) { + printf("\r%5.5d\n", i); + fflush(stdout); perror("send test data"); - fprintf(stderr, "send() failed\n"); + printf("send() failed at socket %d, index %d\n", socknum, i); + fflush(stderr); return(1); } if(i % 100 == 0) { - lenMsg = sprintf(msgBuf, "\retb\b\b\b\b%5.5d", i); - write(1, msgBuf, lenMsg); + printf("\r%5.5d", i); } } - lenMsg = sprintf(msgBuf, "\retb\b\b\b\b%5.5d messages sent\n", i); - write(1, msgBuf, lenMsg); + printf("\r%5.5d messages sent\n", i); return 0; } @@ -217,9 +248,18 @@ tcpSend(char *buf, int lenBuf) int main(int argc, char *argv[]) { int ret = 0; + struct sigaction sigAct; static char buf[1024]; - setvbuf(stdout, _IONBF, buf, 48); + /* on Solaris, we do not HAVE MSG_NOSIGNAL, so for this reason + * we block SIGPIPE (not an issue for this program) + */ + memset(&sigAct, 0, sizeof(sigAct)); + sigemptyset(&sigAct.sa_mask); + sigAct.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &sigAct, NULL); + + setvbuf(stdout, buf, _IONBF, 48); if(argc != 5) { printf("Invalid call of tcpflood\n"); @@ -241,5 +281,9 @@ int main(int argc, char *argv[]) printf("error sending messages\n"); exit(1); } + + //closeConnections(); + printf("End of tcpflood Run\n"); + exit(ret); } diff --git a/tests/testsuites/manytcp.conf b/tests/testsuites/manytcp.conf new file mode 100644 index 00000000..8175732e --- /dev/null +++ b/tests/testsuites/manytcp.conf @@ -0,0 +1,13 @@ +# Test for tcp "flood" testing +# rgerhards, 2009-04-08 +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$MaxOpenFiles 2000 +$InputTCPMaxSessions 1100 +$InputTCPServerRun 13514 + +$ErrorMessagesToStderr off + +$template outfmt,"%msg:F,58:2%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +:msg, contains, "msgnum:" ?dynfile;outfmt diff --git a/tools/omfile.c b/tools/omfile.c index 36f160d1..c7283e4d 100644 --- a/tools/omfile.c +++ b/tools/omfile.c @@ -78,7 +78,7 @@ typedef struct s_dynaFileCacheEntry dynaFileCacheEntry; /* globals for default values */ static int iDynaFileCacheSize = 10; /* max cache for dynamic files */ static int fCreateMode = 0644; /* mode to use when creating files */ -static int fDirCreateMode = 0644; /* mode to use when creating files */ +static int fDirCreateMode = 0700; /* mode to use when creating files */ static int bFailOnChown; /* fail if chown fails? */ static uid_t fileUID; /* UID to be used for newly created files */ static uid_t fileGID; /* GID to be used for newly created files */ @@ -847,7 +847,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a bFailOnChown = 1; iDynaFileCacheSize = 10; fCreateMode = 0644; - fDirCreateMode = 0644; + fDirCreateMode = 0700; bCreateDirs = 1; bEnableSync = 0; if(pszTplName != NULL) { diff --git a/tools/syslogd.c b/tools/syslogd.c index a4f0059b..8c86c12e 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -87,6 +87,7 @@ #include <sys/ioctl.h> #include <sys/wait.h> #include <sys/file.h> +#include <sys/resource.h> #include <grp.h> #if HAVE_SYS_TIMESPEC_H @@ -2073,6 +2074,32 @@ static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int } +/* set the processes max number ob files (upon configuration request) + * 2009-04-14 rgerhards + */ +static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles) +{ + struct rlimit maxFiles; + char errStr[1024]; + DEFiRet; + + maxFiles.rlim_cur = iFiles; + maxFiles.rlim_max = iFiles; + + if(setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { + /* NOTE: under valgrind, we seem to be unable to extend the size! */ + rs_strerror_r(errno, errStr, sizeof(errStr)); + errmsg.LogError(0, RS_RET_ERR_RLIM_NOFILE, "could not set process file limit to %d: %s [kernel max %ld]", + iFiles, errStr, (long) maxFiles.rlim_max); + ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE); + } + dbgprintf("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max); + +finalize_it: + RETiRet; +} + + /* set the processes umask (upon configuration request) */ static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask) { @@ -2870,6 +2897,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, conf.doModLoad, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, conf.doIncludeLine, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"maxopenfiles", 0, eCmdHdlrInt, setMaxFiles, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary, |