rsyslog/rsyslog-3.21.11-HUPisRestart.patch

452 lines
17 KiB
Diff
Raw Normal View History

2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/ChangeLog rsyslog-3.21.11/ChangeLog
--- rsyslog-3.21.11.orig/ChangeLog 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/ChangeLog 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -1,3 +1,6 @@
+- added configuration directive "HUPisRestart" which enables to configure
+ HUP to be either a full restart or "just" a leightweight way to
+ close open files.
---------------------------------------------------------------------------
2009-04-13 15:21:15 +00:00
Version 3.21.11 [BETA] (rgerhards), 2009-04-03
- build system improvements contributed by Michael Biebl - thx!
Only in rsyslog-3.21.11: ChangeLog.orig
diff -u -p -r rsyslog-3.21.11.orig/action.c rsyslog-3.21.11/action.c
--- rsyslog-3.21.11.orig/action.c 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/action.c 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -498,6 +498,39 @@ finalize_it:
}
#pragma GCC diagnostic warning "-Wempty-body"
+
+/* call the HUP handler for a given action, if such a handler is defined. The
+ * action mutex is locked, because the HUP handler most probably needs to modify
+ * some internal state information.
+ * rgerhards, 2008-10-22
+ */
+#pragma GCC diagnostic ignored "-Wempty-body"
+rsRetVal
+actionCallHUPHdlr(action_t *pAction)
+{
+ DEFiRet;
+ int iCancelStateSave;
+
+ ASSERT(pAction != NULL);
+ dbgprintf("Action %p checks HUP hdlr: %p\n", pAction, pAction->pMod->doHUP);
+
+ if(pAction->pMod->doHUP == NULL) {
+ FINALIZE; /* no HUP handler, so we are done ;) */
+ }
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave);
+ d_pthread_mutex_lock(&pAction->mutActExec);
+ pthread_cleanup_push(mutexCancelCleanup, &pAction->mutActExec);
+ pthread_setcancelstate(iCancelStateSave, NULL);
+ CHKiRet(pAction->pMod->doHUP(pAction->pModData));
+ pthread_cleanup_pop(1); /* unlock mutex */
+
+finalize_it:
+ RETiRet;
+}
+#pragma GCC diagnostic warning "-Wempty-body"
+
+
/* set the action message queue mode
* TODO: probably move this into queue object, merge with MainMsgQueue!
* rgerhards, 2008-01-28
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/action.h rsyslog-3.21.11/action.h
--- rsyslog-3.21.11.orig/action.h 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/action.h 2009-04-13 11:53:46.000000000 +0200
@@ -85,6 +85,7 @@ rsRetVal actionSetGlobalResumeInterval(i
2009-04-03 15:01:28 +00:00
rsRetVal actionDoAction(action_t *pAction);
rsRetVal actionCallAction(action_t *pAction, msg_t *pMsg);
rsRetVal actionWriteToAction(action_t *pAction);
+rsRetVal actionCallHUPHdlr(action_t *pAction);
rsRetVal actionClassInit(void);
rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, int bSuspended);
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/doc/rsyslog_conf.html rsyslog-3.21.11/doc/rsyslog_conf.html
--- rsyslog-3.21.11.orig/doc/rsyslog_conf.html 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/doc/rsyslog_conf.html 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -175,6 +175,11 @@ default 60000 (1 minute)]</li>
<li><a href="rsconf1_gssforwardservicename.html">$GssForwardServiceName</a></li>
<li><a href="rsconf1_gsslistenservicename.html">$GssListenServiceName</a></li>
<li><a href="rsconf1_gssmode.html">$GssMode</a></li>
+<li>$HUPisRestart [<b>on</b>/off] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending
+on queue configuration, of course) all modules are unloaded and reloaded. This mode keeps compatible with sysklogd, but is
+not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default is "on" for
+compatibility reasons. If it is set to "off", a HUP will only close open files. This is a much quicker action and usually
+the only one that is needed e.g. for log rotation. <b>It is recommended to set the setting to "off".</b></li>
<li><a href="rsconf1_includeconfig.html">$IncludeConfig</a></li><li>MainMsgQueueCheckpointInterval &lt;number&gt;</li>
<li>$MainMsgQueueDequeueSlowdown &lt;number&gt; [number
is timeout in <i> micro</i>seconds (1000000us is 1sec!),
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/runtime/glbl.c rsyslog-3.21.11/runtime/glbl.c
--- rsyslog-3.21.11.orig/runtime/glbl.c 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/runtime/glbl.c 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -52,6 +52,7 @@ DEFobjStaticHelpers
*/
static uchar *pszWorkDir = NULL;
static int iMaxLine = 2048; /* maximum length of a syslog message */
+static int bHUPisRestart = 1; /* should SIGHUP cause a full system restart? */
static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
@@ -86,6 +87,7 @@ static dataType Get##nameFunc(void) \
}
SIMP_PROP(MaxLine, iMaxLine, int)
+SIMP_PROP(HUPisRestart, bHUPisRestart, int)
SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may check the family argument */
SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
SIMP_PROP(Option_DisallowWarning, option_DisallowWarning, int)
@@ -173,6 +175,7 @@ CODESTARTobjQueryInterface(glbl)
pIf->Get##name = Get##name; \
pIf->Set##name = Set##name;
SIMP_PROP(MaxLine);
+ SIMP_PROP(HUPisRestart);
SIMP_PROP(DefPFFamily);
SIMP_PROP(DropMalPTRMsgs);
SIMP_PROP(Option_DisallowWarning);
2009-04-13 15:21:15 +00:00
@@ -216,6 +219,7 @@ static rsRetVal resetConfigVariables(uch
2009-04-03 15:01:28 +00:00
pszWorkDir = NULL;
}
bDropMalPTRMsgs = 0;
+ bHUPisRestart = 1;
return RS_RET_OK;
}
2009-04-13 15:21:15 +00:00
@@ -235,6 +239,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_I
2009-04-03 15:01:28 +00:00
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercafile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCAF, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"hupisrestart", 0, eCmdHdlrBinary, NULL, &bHUPisRestart, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
ENDObjClassInit(glbl)
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/runtime/glbl.h rsyslog-3.21.11/runtime/glbl.h
--- rsyslog-3.21.11.orig/runtime/glbl.h 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/runtime/glbl.h 2009-04-13 11:53:46.000000000 +0200
@@ -41,6 +41,7 @@ BEGINinterface(glbl) /* name must also b
2009-04-03 15:01:28 +00:00
dataType (*Get##name)(void); \
rsRetVal (*Set##name)(dataType);
SIMP_PROP(MaxLine, int)
+ SIMP_PROP(HUPisRestart, int)
SIMP_PROP(DefPFFamily, int)
SIMP_PROP(DropMalPTRMsgs, int)
SIMP_PROP(Option_DisallowWarning, int)
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/runtime/module-template.h rsyslog-3.21.11/runtime/module-template.h
--- rsyslog-3.21.11.orig/runtime/module-template.h 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/runtime/module-template.h 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -481,6 +481,33 @@ static rsRetVal afterRun(void)\
}
-/*
- * vi:set ai:
+/* doHUP()
+ * This function is optional. Currently, it is available to output plugins
+ * only, but may be made available to other types of plugins in the future.
+ * A plugin does not need to define this entry point. If if does, it gets
+ * called when a non-restart type of HUP is done. A plugin should register
+ * this function so that it can close files, connection or other ressources
+ * on HUP - if it can be assume the user wanted to do this as a part of HUP
+ * processing. Note that the name "HUP" has historical reasons, it stems back
+ * to the infamous SIGHUP which was sent to restart a syslogd. We still retain
+ * that legacy, but may move this to a different signal.
+ * rgerhards, 2008-10-22
+ */
+#define CODEqueryEtryPt_doHUP \
+ else if(!strcmp((char*) name, "doHUP")) {\
+ *pEtryPoint = doHUP;\
+ }
+#define BEGINdoHUP \
+static rsRetVal doHUP(instanceData __attribute__((unused)) *pData)\
+{\
+ DEFiRet;
+
+#define CODESTARTdoHUP
+
+#define ENDdoHUP \
+ RETiRet;\
+}
+
+
+/* vim:set ai:
*/
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/runtime/modules.c rsyslog-3.21.11/runtime/modules.c
--- rsyslog-3.21.11.orig/runtime/modules.c 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/runtime/modules.c 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -347,6 +347,7 @@ static rsRetVal
doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_t*), uchar *name, void *pModHdlr)
{
DEFiRet;
+ rsRetVal localRet;
modInfo_t *pNew = NULL;
rsRetVal (*modGetType)(eModType_t *pType);
2009-04-13 15:21:15 +00:00
@@ -391,6 +392,10 @@ doModInit(rsRetVal (*modInit)(int, int*,
2009-04-03 15:01:28 +00:00
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"parseSelectorAct", &pNew->mod.om.parseSelectorAct));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"isCompatibleWithFeature", &pNew->isCompatibleWithFeature));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"tryResume", &pNew->tryResume));
+ /* try load optional interfaces */
+ localRet = (*pNew->modQueryEtryPt)((uchar*)"doHUP", &pNew->doHUP);
+ if(localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND)
+ ABORT_FINALIZE(localRet);
break;
case eMOD_LIB:
break;
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/runtime/modules.h rsyslog-3.21.11/runtime/modules.h
--- rsyslog-3.21.11.orig/runtime/modules.h 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/runtime/modules.h 2009-04-13 11:53:46.000000000 +0200
2009-04-03 15:01:28 +00:00
@@ -88,6 +88,7 @@ typedef struct modInfo_s {
rsRetVal (*tryResume)(void*);/* called to see if module actin can be resumed now */
rsRetVal (*modExit)(void); /* called before termination or module unload */
rsRetVal (*modGetID)(void **); /* get its unique ID from module */
+ rsRetVal (*doHUP)(void *); /* non-restart type HUP handler */
/* below: parse a configuration line - return if processed
* or not. If not, must be parsed to next module.
*/
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/tools/omfile.c rsyslog-3.21.11/tools/omfile.c
--- rsyslog-3.21.11.orig/tools/omfile.c 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/tools/omfile.c 2009-04-13 11:53:46.000000000 +0200
@@ -244,7 +244,6 @@ static rsRetVal cflineParseOutchannel(in
2009-04-03 15:01:28 +00:00
*/
pData->f_sizeLimitCmd = (char*) pOch->cmdOnSizeLimit;
-RUNLOG_VAR("%p", pszTplName);
iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts,
(pszTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszTplName);
@@ -349,9 +348,11 @@ finalize_it:
}
-/* This function frees the dynamic file name cache.
+/* This function frees all dynamic file name cache entries and closes the
+ * relevant files. Part of Shutdown and HUP processing.
+ * rgerhards, 2008-10-23
*/
-static void dynaFileFreeCache(instanceData *pData)
+static inline void dynaFileFreeCacheEntries(instanceData *pData)
{
register int i;
ASSERT(pData != NULL);
2009-04-13 15:21:15 +00:00
@@ -360,17 +361,36 @@ static void dynaFileFreeCache(instanceDa
2009-04-03 15:01:28 +00:00
for(i = 0 ; i < pData->iCurrCacheSize ; ++i) {
dynaFileDelCacheEntry(pData->dynCache, i, 1);
}
+ ENDfunc;
+}
+
+
+/* This function frees the dynamic file name cache.
+ */
+static void dynaFileFreeCache(instanceData *pData)
+{
+ ASSERT(pData != NULL);
+ BEGINfunc;
+ dynaFileFreeCacheEntries(pData);
if(pData->dynCache != NULL)
d_free(pData->dynCache);
ENDfunc;
}
-/* This is a shared code for both static and dynamic files.
+/* This is now shared code for all types of files. It simply prepares
+ * file access, which, among others, means the the file wil be opened
+ * and any directories in between will be created (based on config, of
+ * course). -- rgerhards, 2008-10-22
*/
static void prepareFile(instanceData *pData, uchar *newFileName)
{
+ if(pData->fileType == eTypePIPE) {
+ pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK);
+ FINALIZE; /* we are done in this case */
+ }
+
if(access((char*)newFileName, F_OK) == 0) {
/* file already exists */
pData->fd = open((char*) newFileName, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
2009-04-13 15:21:15 +00:00
@@ -413,6 +433,12 @@ static void prepareFile(instanceData *pD
2009-04-03 15:01:28 +00:00
}
}
}
+finalize_it:
+ if((pData->fd) != 0 && isatty(pData->fd)) {
+ dbgprintf("file %d is a tty file\n", pData->fd);
+ pData->fileType = eTypeTTY;
+ untty();
+ }
}
2009-04-13 15:21:15 +00:00
@@ -537,6 +563,8 @@ static rsRetVal writeFile(uchar **ppStri
2009-04-03 15:01:28 +00:00
if(pData->bDynamicName) {
if(prepareDynFile(pData, ppString[1], iMsgOpts) != 0)
ABORT_FINALIZE(RS_RET_ERR);
+ } else if(pData->fd == -1) {
+ prepareFile(pData, pData->f_fname);
}
/* create the message based on format specified */
@@ -642,12 +670,7 @@ ENDtryResume
BEGINdoAction
CODESTARTdoAction
dbgprintf(" (%s)\n", pData->f_fname);
- /* pData->fd == -1 is an indicator that the we couldn't
- * open the file at startup. For dynaFiles, this is ok,
- * all others are doomed.
- */
- if(pData->bDynamicName || (pData->fd != -1))
- iRet = writeFile(ppString, iMsgOpts, pData);
+ iRet = writeFile(ppString, iMsgOpts, pData);
ENDdoAction
@@ -764,11 +787,7 @@ CODESTARTparseSelectorAct
pData->dirUID = dirUID;
pData->dirGID = dirGID;
- if(pData->fileType == eTypePIPE) {
- pData->fd = open((char*) pData->f_fname, O_RDWR|O_NONBLOCK);
- } else {
- prepareFile(pData, pData->f_fname);
- }
+ prepareFile(pData, pData->f_fname);
if ( pData->fd < 0 ){
pData->fd = -1;
@@ -776,10 +795,6 @@ CODESTARTparseSelectorAct
errmsg.LogError(0, NO_ERRCODE, "%s", pData->f_fname);
break;
}
- if (isatty(pData->fd)) {
- pData->fileType = eTypeTTY;
- untty();
- }
if (strcmp((char*) p, _PATH_CONSOLE) == 0)
pData->fileType = eTypeCONSOLE;
break;
2009-04-13 15:21:15 +00:00
@@ -815,6 +830,20 @@ static rsRetVal resetConfigVariables(uch
2009-04-03 15:01:28 +00:00
}
+BEGINdoHUP
+CODESTARTdoHUP
+ if(pData->bDynamicName) {
+ dynaFileFreeCacheEntries(pData);
+ pData->iCurrElt = -1; /* invalidate current element */
+ } else {
+ if(pData->fd != -1) {
+ close(pData->fd);
+ pData->fd = -1;
+ }
+ }
+ENDdoHUP
+
+
BEGINmodExit
CODESTARTmodExit
if(pszTplName != NULL)
@@ -825,6 +854,7 @@ ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
+CODEqueryEtryPt_doHUP
ENDqueryEtryPt
2009-04-13 15:21:15 +00:00
diff -u -p -r rsyslog-3.21.11.orig/tools/syslogd.c rsyslog-3.21.11/tools/syslogd.c
--- rsyslog-3.21.11.orig/tools/syslogd.c 2009-04-13 11:50:41.000000000 +0200
+++ rsyslog-3.21.11/tools/syslogd.c 2009-04-13 11:53:46.000000000 +0200
@@ -219,7 +219,7 @@ static char *PidFile = _PATH_LOGPID; /*
2009-04-03 15:01:28 +00:00
static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */
/* mypid is read-only after the initial fork() */
-static int restart = 0; /* do restart (config read) - multithread safe */
+static int bHadHUP = 0; /* did we have a HUP? */
static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be
* parsed inside message - rgerhards, 2006-03-13 */
2009-04-13 15:21:15 +00:00
@@ -2525,13 +2525,13 @@ static rsRetVal setMainMsgQueType(void _
2009-04-03 15:01:28 +00:00
* The following function is resposible for handling a SIGHUP signal. Since
* we are now doing mallocs/free as part of init we had better not being
* doing this during a signal handler. Instead this function simply sets
- * a flag variable which will tell the main loop to go through a restart.
+ * a flag variable which will tells the main loop to do "the right thing".
*/
void sighup_handler()
{
struct sigaction sigAct;
- restart = 1;
+ bHadHUP = 1;
memset(&sigAct, 0, sizeof (sigAct));
sigemptyset(&sigAct.sa_mask);
@@ -2560,6 +2560,49 @@ static void processImInternal(void)
}
+/* helper to doHUP(), this "HUPs" each action. The necessary locking
+ * is done inside the action class and nothing we need to take care of.
+ * rgerhards, 2008-10-22
+ */
+DEFFUNC_llExecFunc(doHUPActions)
+{
+ BEGINfunc
+ actionCallHUPHdlr((action_t*) pData);
+ ENDfunc
+ return RS_RET_OK; /* we ignore errors, we can not do anything either way */
+}
+
+
+/* This function processes a HUP after one has been detected. Note that this
+ * is *NOT* the sighup handler. The signal is recorded by the handler, that record
+ * detected inside the mainloop and then this function is called to do the
+ * real work. -- rgerhards, 2008-10-22
+ */
+static inline void
+doHUP(void)
+{
+ selector_t *f;
+ char buf[512];
+
+ snprintf(buf, sizeof(buf) / sizeof(char),
+ " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION
+ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.",
+ (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight");
+ errno = 0;
+ logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
+
+ if(glbl.GetHUPisRestart()) {
+ dbgprintf("Received SIGHUP, configured to be restart, reloading rsyslogd.\n");
+ init(); /* main queue is stopped as part of init() */
+ } else {
+ dbgprintf("Received SIGHUP, configured to be a non-restart type of HUP - notifying actions.\n");
+ for(f = Files; f != NULL ; f = f->f_next) {
+ llExecFunc(&f->llActList, doHUPActions, NULL);
+ }
+ }
+}
+
+
/* This is the main processing loop. It is called after successful initialization.
* When it returns, the syslogd terminates.
* Its sole function is to provide some housekeeping things. The real work is done
@@ -2616,11 +2659,9 @@ mainloop(void)
if(bReduceRepeatMsgs == 1)
doFlushRptdMsgs();
- if(restart) {
- dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n");
- /* main queue is stopped as part of init() */
- init();
- restart = 0;
+ if(bHadHUP) {
+ doHUP();
+ bHadHUP = 0;
continue;
}
}