summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/rsyslog.h1
-rwxr-xr-xtests/manytcp.sh13
-rw-r--r--tests/tcpflood.c59
-rw-r--r--tests/testsuites/manytcp.conf4
-rw-r--r--tools/syslogd.c28
5 files changed, 89 insertions, 16 deletions
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index cea457d8..25ec30fc 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -262,6 +262,7 @@ 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 */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/tests/manytcp.sh b/tests/manytcp.sh
index f0a3eb96..d9b2e9a0 100755
--- a/tests/manytcp.sh
+++ b/tests/manytcp.sh
@@ -1,13 +1,18 @@
-rm -f rsyslog.out.log # work file
+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`
-./tcpflood 127.0.0.1 13514 1000 20000
-sleep 1
+# 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"
diff --git a/tests/tcpflood.c b/tests/tcpflood.c
index 83f0d1ee..254e9fd6 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,13 +151,16 @@ 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);
+ printf("Sending %d messages.\n", numMsgsToSend);
+ printf("\r%5.5d messages sent", 0);
+ lenMsg = sprintf(msgBuf, "\r%5.5d/%5.5d messages sent", 0, numMsgsToSend);
write(1, msgBuf, lenMsg);
for(i = 0 ; i < numMsgsToSend ; ++i) {
if(i < numConnections)
@@ -139,18 +170,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, MSG_NOSIGNAL);
+ 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;
}
@@ -219,7 +252,7 @@ int main(int argc, char *argv[])
int ret = 0;
static char buf[1024];
- setvbuf(stdout, _IONBF, buf, 48);
+ setvbuf(stdout, buf, _IONBF, 48);
if(argc != 5) {
printf("Invalid call of tcpflood\n");
@@ -241,5 +274,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
index e491cd04..8175732e 100644
--- a/tests/testsuites/manytcp.conf
+++ b/tests/testsuites/manytcp.conf
@@ -1,7 +1,9 @@
# Test for tcp "flood" testing
# rgerhards, 2009-04-08
$ModLoad ../plugins/imtcp/.libs/imtcp
-$inputtcpmaxsessions 2000
+$MainMsgQueueTimeoutShutdown 10000
+$MaxOpenFiles 2000
+$InputTCPMaxSessions 1100
$InputTCPServerRun 13514
$ErrorMessagesToStderr off
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,