diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2011-05-03 18:02:18 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2011-05-03 18:02:18 +0200 |
commit | d0d9f823b79c5649dad18cb1d8d7744796ae0907 (patch) | |
tree | 52c7fe67ad47f6395a2974cdeda22736904f2c0c | |
parent | 3ad873e17adf89de8437aa5638b412e9fc730acf (diff) | |
download | rsyslog-d0d9f823b79c5649dad18cb1d8d7744796ae0907.tar.gz rsyslog-d0d9f823b79c5649dad18cb1d8d7744796ae0907.tar.bz2 rsyslog-d0d9f823b79c5649dad18cb1d8d7744796ae0907.zip |
step: put plumbing in place for new input module config system
-rw-r--r-- | action.h | 1 | ||||
-rw-r--r-- | plugins/im3195/im3195.c | 30 | ||||
-rw-r--r-- | plugins/imdiag/imdiag.c | 29 | ||||
-rw-r--r-- | plugins/imfile/imfile.c | 29 | ||||
-rw-r--r-- | plugins/imgssapi/imgssapi.c | 29 | ||||
-rw-r--r-- | plugins/imklog/imklog.c | 30 | ||||
-rw-r--r-- | plugins/immark/immark.c | 65 | ||||
-rw-r--r-- | plugins/impstats/impstats.c | 30 | ||||
-rw-r--r-- | plugins/imptcp/imptcp.c | 30 | ||||
-rw-r--r-- | plugins/imrelp/imrelp.c | 29 | ||||
-rw-r--r-- | plugins/imsolaris/imsolaris.c | 29 | ||||
-rw-r--r-- | plugins/imtcp/imtcp.c | 30 | ||||
-rw-r--r-- | plugins/imtemplate/imtemplate.c | 29 | ||||
-rw-r--r-- | plugins/imttcp/imttcp.c | 29 | ||||
-rw-r--r-- | plugins/imudp/imudp.c | 30 | ||||
-rw-r--r-- | plugins/imuxsock/imuxsock.c | 30 | ||||
-rw-r--r-- | runtime/conf.c | 34 | ||||
-rw-r--r-- | runtime/module-template.h | 114 | ||||
-rw-r--r-- | runtime/modules.c | 40 | ||||
-rw-r--r-- | runtime/modules.h | 16 | ||||
-rw-r--r-- | runtime/rsconf.c | 104 | ||||
-rw-r--r-- | runtime/rsconf.h | 3 |
22 files changed, 725 insertions, 65 deletions
@@ -106,5 +106,6 @@ rsRetVal actionClassInit(void); rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, int bSuspended); rsRetVal actionNewScope(void); rsRetVal actionRestoreScope(void); +rsRetVal activateActions(void); #endif /* #ifndef ACTION_H_INCLUDED */ diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c index 156524c9..89dffacd 100644 --- a/plugins/im3195/im3195.c +++ b/plugins/im3195/im3195.c @@ -58,6 +58,11 @@ DEF_IMOD_STATIC_DATA DEFobjCurrIf(errmsg) /* configuration settings */ + +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int listenPort = 601; /* we use a global API object below, because this listener is @@ -89,6 +94,31 @@ void OnReceive(srAPIObj __attribute__((unused)) *pMyAPI, srSLMGObj* pSLMG) } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + BEGINrunInput CODESTARTrunInput /* this is an endless loop - it is terminated when the thread is diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c index 12b3318d..2595b903 100644 --- a/plugins/imdiag/imdiag.c +++ b/plugins/imdiag/imdiag.c @@ -78,6 +78,10 @@ static prop_t *pRcvIPDummy = NULL; /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int iTCPSessMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */ @@ -383,6 +387,31 @@ finalize_it: RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c index 67eebefe..f3aff1bb 100644 --- a/plugins/imfile/imfile.c +++ b/plugins/imfile/imfile.c @@ -83,6 +83,10 @@ typedef struct fileInfo_s { static rsRetVal persistStrmState(fileInfo_t *pInfo); /* config variables */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static uchar *pszFileName = NULL; static uchar *pszFileTag = NULL; static uchar *pszStateFile = NULL; @@ -322,6 +326,31 @@ ENDrunInput * ------------------------------------------------------------------------------------------ */ +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + /* The function is called by rsyslog before runInput() is called. It is a last chance * to set up anything specific. Most importantly, it can be used to tell rsyslog if the * input shall run or not. The idea is that if some config settings (or similiar things) diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c index 41e34973..4d790cb0 100644 --- a/plugins/imgssapi/imgssapi.c +++ b/plugins/imgssapi/imgssapi.c @@ -104,6 +104,10 @@ typedef struct gss_sess_s { /* config variables */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int iTCPSessMax = 200; /* max number of sessions */ static char *gss_listen_service_name = NULL; static int bPermitPlainTcp = 0; /* plain tcp syslog allowed on GSSAPI port? */ @@ -640,6 +644,31 @@ TCPSessGSSDeinit(void) RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c index 568fa8c1..05365588 100644 --- a/plugins/imklog/imklog.c +++ b/plugins/imklog/imklog.c @@ -67,6 +67,11 @@ DEFobjCurrIf(glbl) DEFobjCurrIf(prop) /* configuration settings */ + +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */ int symbols_twice = 0; int use_syscall = 0; @@ -249,6 +254,31 @@ finalize_it: ENDrunInput +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + BEGINwillRun CODESTARTwillRun /* we need to create the inputName property (only once during our lifetime) */ diff --git a/plugins/immark/immark.c b/plugins/immark/immark.c index 609c8847..6b46b29f 100644 --- a/plugins/immark/immark.c +++ b/plugins/immark/immark.c @@ -10,7 +10,7 @@ * of the "old" message code without any modifications. However, it * helps to have things at the right place one we go to the meat of it. * - * Copyright 2007 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -54,7 +54,12 @@ MODULE_TYPE_NOKEEP /* Module static data */ DEF_IMOD_STATIC_DATA DEFobjCurrIf(glbl) +DEFobjCurrIf(errmsg) + static int iMarkMessagePeriod = DEFAULT_MARK_PERIOD; +typedef struct { + int iMarkMessagePeriod; +} modConfData_t; BEGINisCompatibleWithFeature CODESTARTisCompatibleWithFeature @@ -63,6 +68,43 @@ CODESTARTisCompatibleWithFeature ENDisCompatibleWithFeature +BEGINafterRun +CODESTARTafterRun +ENDafterRun + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad + pModConf->iMarkMessagePeriod = iMarkMessagePeriod; +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf + if(pModConf->iMarkMessagePeriod == 0) { + errmsg.LogError(0, NO_ERRCODE, "immark: mark message period must not be 0, can not run"); + ABORT_FINALIZE(RS_RET_NO_RUN); /* we can not run with this error */ + } +finalize_it: +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf + MarkInterval = pModConf->iMarkMessagePeriod; +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + /* This function is called to gather input. It must terminate only * a) on failure (iRet set accordingly) * b) on termination of the input module (as part of the unload process) @@ -82,7 +124,7 @@ CODESTARTrunInput * right into the sleep below. */ while(1) { - srSleep(iMarkMessagePeriod, 0); /* seconds, micro seconds */ + srSleep(MarkInterval, 0); /* seconds, micro seconds */ if(glbl.GetGlobalInputTermState() == 1) break; /* terminate input! */ @@ -95,19 +137,14 @@ ENDrunInput BEGINwillRun CODESTARTwillRun /* We set the global MarkInterval to what is configured here -- rgerhards, 2008-07-15 */ - MarkInterval = iMarkMessagePeriod; - if(iMarkMessagePeriod == 0) + if(MarkInterval == 0) iRet = RS_RET_NO_RUN; ENDwillRun -BEGINafterRun -CODESTARTafterRun -ENDafterRun - - BEGINmodExit CODESTARTmodExit + objRelease(errmsg, CORE_COMPONENT); ENDmodExit @@ -120,7 +157,6 @@ ENDqueryEtryPt static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { iMarkMessagePeriod = DEFAULT_MARK_PERIOD; - return RS_RET_OK; } @@ -129,8 +165,13 @@ CODESTARTmodInit *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(glbl, CORE_COMPONENT)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"markmessageperiod", 0, eCmdHdlrInt, NULL, &iMarkMessagePeriod, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); - CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + + /* legacy config handlers */ + CHKiRet(omsdRegCFSLineHdlr((uchar *)"markmessageperiod", 0, eCmdHdlrInt, NULL, + &iMarkMessagePeriod, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); ENDmodInit /* vi:set ai: */ diff --git a/plugins/impstats/impstats.c b/plugins/impstats/impstats.c index 35851231..139652c1 100644 --- a/plugins/impstats/impstats.c +++ b/plugins/impstats/impstats.c @@ -69,6 +69,11 @@ typedef struct configSettings_s { int iSeverity; } configSettings_t; +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + + static configSettings_t cs; static prop_t *pInputName = NULL; @@ -139,6 +144,31 @@ generateStatsMsgs(void) } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + BEGINrunInput CODESTARTrunInput /* this is an endless loop - it is terminated when the thread is diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 1c9450c2..31f6fbc6 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -198,6 +198,11 @@ static int iMaxLine; /* maximum size of a single message */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal); static rsRetVal addLstn(ptcpsrv_t *pSrv, int sock); +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + + /* some simple constructors/destructors */ static void @@ -1145,6 +1150,31 @@ wrkr(void *myself) } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c index 8650c86e..39c90849 100644 --- a/plugins/imrelp/imrelp.c +++ b/plugins/imrelp/imrelp.c @@ -60,6 +60,10 @@ static prop_t *pInputName = NULL; /* there is only one global inputName for all /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int iTCPSessMax = 200; /* max number of sessions */ @@ -117,6 +121,31 @@ finalize_it: RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imsolaris/imsolaris.c b/plugins/imsolaris/imsolaris.c index ee9ec5c6..b9701076 100644 --- a/plugins/imsolaris/imsolaris.c +++ b/plugins/imsolaris/imsolaris.c @@ -99,6 +99,10 @@ DEFobjCurrIf(prop) /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static prop_t *pInputName = NULL; /* our inputName currently is always "imuxsock", and this will hold it */ static char *LogName = NULL; /* the log socket name TODO: make configurable! */ @@ -302,6 +306,31 @@ finalize_it: } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + /* This function is called to gather input. */ BEGINrunInput CODESTARTrunInput diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c index be95d287..b034ebe9 100644 --- a/plugins/imtcp/imtcp.c +++ b/plugins/imtcp/imtcp.c @@ -82,6 +82,11 @@ static permittedPeers_t *pPermPeersRoot = NULL; /* config settings */ + +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + static int iTCPSessMax = 200; /* max number of sessions */ static int iTCPLstnMax = 20; /* max number of sessions */ static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */ @@ -228,6 +233,31 @@ finalize_it: RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imtemplate/imtemplate.c b/plugins/imtemplate/imtemplate.c index f18eba92..1f60bef7 100644 --- a/plugins/imtemplate/imtemplate.c +++ b/plugins/imtemplate/imtemplate.c @@ -95,6 +95,35 @@ DEF_IMOD_STATIC_DATA /* must be present, starts static data */ /* static int imtemplateWhateverVar = 0; */ /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + + + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf /* You may add any functions that you feel are useful for your needs. No specific restrictions diff --git a/plugins/imttcp/imttcp.c b/plugins/imttcp/imttcp.c index 44dc3267..47bd071e 100644 --- a/plugins/imttcp/imttcp.c +++ b/plugins/imttcp/imttcp.c @@ -135,6 +135,10 @@ DEFobjCurrIf(ruleset) /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + typedef struct configSettings_s { int bEmitMsgOnClose; /* emit an informational message on close by remote peer */ int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */ @@ -984,6 +988,31 @@ startupListeners() RETiRet; } + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. */ BEGINrunInput diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 4a3560aa..2fa62fd5 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -92,6 +92,11 @@ static int iTimeRequery = TIME_REQUERY_DFLT;/* how often is time to be queried i /* config settings */ +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + + static rsRetVal check_scheduling_priority(int report_error) { DEFiRet; @@ -569,6 +574,31 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd) } #endif /* #if HAVE_EPOLL_CREATE1 */ + +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + /* This function is called to gather input. * Note that udpLstnSocks must be non-NULL because otherwise we would not have * indicated that we want to run (or we have a programming error ;)). -- rgerhards, 2008-10-02 diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index cbf87d7f..91f273c1 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -87,6 +87,11 @@ DEFobjCurrIf(parser) DEFobjCurrIf(datetime) DEFobjCurrIf(statsobj) + +typedef struct { + EMPTY_STRUCT; +} modConfData_t; + statsobj_t *modStats; STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) STATSCOUNTER_DEF(ctrLostRatelimit, mutCtrLostRatelimit) @@ -684,6 +689,31 @@ finalize_it: } +BEGINbeginCnfLoad +CODESTARTbeginCnfLoad +ENDbeginCnfLoad + + +BEGINendCnfLoad +CODESTARTendCnfLoad +ENDendCnfLoad + + +BEGINcheckCnf +CODESTARTcheckCnf +ENDcheckCnf + + +BEGINactivateCnf +CODESTARTactivateCnf +ENDactivateCnf + + +BEGINfreeCnf +CODESTARTfreeCnf +ENDfreeCnf + + /* This function is called to gather input. */ BEGINrunInput int maxfds; diff --git a/runtime/conf.c b/runtime/conf.c index ea7102a6..6a2e57fa 100644 --- a/runtime/conf.c +++ b/runtime/conf.c @@ -1095,24 +1095,26 @@ finalize_it: */ static rsRetVal cflineDoAction(rsconf_t *conf, uchar **p, action_t **ppAction) { - DEFiRet; modInfo_t *pMod; + cfgmodules_etry_t *node; omodStringRequest_t *pOMSR; action_t *pAction = NULL; void *pModData; + DEFiRet; ASSERT(p != NULL); ASSERT(ppAction != NULL); /* loop through all modules and see if one picks up the line */ - pMod = module.GetNxtCnfType(conf, NULL, eMOD_OUT); - /* Note: clang static analyzer reports that pMod mybe == NULL. However, this is + node = module.GetNxtCnfType(conf, NULL, eMOD_OUT); + /* Note: clang static analyzer reports that node maybe == NULL. However, this is * not possible, because we have the built-in output modules which are always * present. Anyhow, we guard this by an assert. -- rgerhards, 2010-12-16 */ - assert(pMod != NULL); - while(pMod != NULL) { + assert(node != NULL); + while(node != NULL) { pOMSR = NULL; + pMod = node->pMod; iRet = pMod->mod.om.parseSelectorAct(p, &pModData, &pOMSR); dbgprintf("tried selector action for %s: %d\n", module.GetName(pMod), iRet); if(iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) { @@ -1144,7 +1146,7 @@ static rsRetVal cflineDoAction(rsconf_t *conf, uchar **p, action_t **ppAction) dbgprintf("error %d parsing config line\n", (int) iRet); break; } - pMod = module.GetNxtCnfType(conf, pMod, eMOD_OUT); + node = module.GetNxtCnfType(conf, node, eMOD_OUT); } *ppAction = pAction; @@ -1279,17 +1281,17 @@ static inline rsRetVal setActionScope(void) { DEFiRet; - modInfo_t *pMod; + cfgmodules_etry_t *node; currConfObj = eConfObjAction; DBGPRINTF("entering action scope\n"); CHKiRet(actionNewScope()); /* now tell each action to start the scope */ - pMod = NULL; - while((pMod = module.GetNxtCnfType(loadConf, pMod, eMOD_OUT)) != NULL) { - DBGPRINTF("beginning scope on module %s\n", pMod->pszName); - pMod->mod.om.newScope(); + node = NULL; + while((node = module.GetNxtCnfType(loadConf, node, eMOD_OUT)) != NULL) { + DBGPRINTF("beginning scope on module %s\n", node->pMod->pszName); + node->pMod->mod.om.newScope(); } finalize_it: @@ -1304,17 +1306,17 @@ static inline rsRetVal unsetActionScope(void) { DEFiRet; - modInfo_t *pMod; + cfgmodules_etry_t *node; currConfObj = eConfObjAction; DBGPRINTF("exiting action scope\n"); CHKiRet(actionRestoreScope()); /* now tell each action to restore the scope */ - pMod = NULL; - while((pMod = module.GetNxtCnfType(loadConf, pMod, eMOD_OUT)) != NULL) { - DBGPRINTF("exiting scope on module %s\n", pMod->pszName); - pMod->mod.om.restoreScope(); + node = NULL; + while((node = module.GetNxtCnfType(loadConf, node, eMOD_OUT)) != NULL) { + DBGPRINTF("exiting scope on module %s\n", node->pMod->pszName); + node->pMod->mod.om.restoreScope(); } finalize_it: diff --git a/runtime/module-template.h b/runtime/module-template.h index 2b0ed593..1ec1d8d2 100644 --- a/runtime/module-template.h +++ b/runtime/module-template.h @@ -459,6 +459,16 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\ *pEtryPoint = willRun;\ } else if(!strcmp((char*) name, "afterRun")) {\ *pEtryPoint = afterRun;\ + } else if(!strcmp((char*) name, "beginCnfLoad")) {\ + *pEtryPoint = beginCnfLoad;\ + } else if(!strcmp((char*) name, "endCnfLoad")) {\ + *pEtryPoint = endCnfLoad;\ + } else if(!strcmp((char*) name, "checkCnf")) {\ + *pEtryPoint = checkCnf;\ + } else if(!strcmp((char*) name, "activateCnf")) {\ + *pEtryPoint = activateCnf;\ + } else if(!strcmp((char*) name, "freeCnf")) {\ + *pEtryPoint = freeCnf;\ } /* the following definition is the standard block for queryEtryPt for LIBRARY @@ -600,6 +610,110 @@ static rsRetVal modExit(void)\ } +/* beginCnfLoad() + * This is a function tells an input module that a new config load begins. + * The core passes in a handle to the new module-specific module conf to + * the module. -- rgerards, 2011-05-03 + */ +#define BEGINbeginCnfLoad \ +static rsRetVal beginCnfLoad(modConfData_t **ptr)\ +{\ + modConfData_t *pModConf; \ + DEFiRet; + +#define CODESTARTbeginCnfLoad \ + if((pModConf = calloc(1, sizeof(modConfData_t))) == NULL) {\ + *ptr = NULL;\ + ENDfunc \ + return RS_RET_OUT_OF_MEMORY;\ + } + +#define ENDbeginCnfLoad \ + *ptr = pModConf;\ + RETiRet;\ +} + + +/* endCnfLoad() + * This is a function tells an input module that the current config load ended. + * It gets a last chance to make changes to its in-memory config object. After + * this call, the config object must no longer be changed. + * The pModConf pointer passed into the module must no longer be used. + * rgerards, 2011-05-03 + */ +#define BEGINendCnfLoad \ +static rsRetVal endCnfLoad(modConfData_t *ptr)\ +{\ + modConfData_t *pModConf = (modConfData_t*) ptr; \ + DEFiRet; + +#define CODESTARTendCnfLoad + +#define ENDendCnfLoad \ + RETiRet;\ +} + + +/* checkCnf() + * Check the provided config object for errors, inconsistencies and other things + * that do not work out. + * NOTE: no part of the config must be activated, so some checks that require + * activation can not be done in this entry point. They must be done in the + * activateConf() stage, where the caller must also be prepared for error + * returns. + * rgerhards, 2011-05-03 + */ +#define BEGINcheckCnf \ +static rsRetVal checkCnf(modConfData_t *ptr)\ +{\ + modConfData_t *pModConf = (modConfData_t*) ptr; \ + DEFiRet; + +#define CODESTARTcheckCnf + +#define ENDcheckCnf \ + RETiRet;\ +} + + +/* activateCnf() + * This activates the provided config, and may report errors if they are detected + * during activation. + * rgerhards, 2011-05-03 + */ +#define BEGINactivateCnf \ +static rsRetVal activateCnf(modConfData_t *ptr)\ +{\ + modConfData_t *pModConf = (modConfData_t*) ptr; \ + DEFiRet; + +#define CODESTARTactivateCnf + +#define ENDactivateCnf \ + RETiRet;\ +} + + +/* freeCnf() + * This is a function tells an input module that it must free all data + * associated with the passed-in module config. + * rgerhards, 2011-05-03 + */ +#define BEGINfreeCnf \ +static rsRetVal freeCnf(void *ptr)\ +{\ + modConfData_t *pModConf = (modConfData_t*) ptr; \ + DEFiRet; + +#define CODESTARTfreeCnf + +#define ENDfreeCnf \ + if(pModConf != NULL)\ + free(pModConf); /* we need to free this in any case */\ + RETiRet;\ +} + + /* runInput() * This is the main function for input modules. It is used to gather data from the * input source and submit it to the message queue. Each runInput() instance has its own diff --git a/runtime/modules.c b/runtime/modules.c index 69c89790..67f16e65 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -362,12 +362,19 @@ addModToCnfList(modInfo_t *pThis) } } - /* if we reach this point, pLast is the tail pointer */ + /* if we reach this point, pLast is the tail pointer and this module is new + * inside the currently loaded config. So, iff it is an input module, let's + * pass it a pointer which it can populate with a pointer to its module conf. + */ CHKmalloc(pNew = MALLOC(sizeof(cfgmodules_etry_t))); pNew->next = NULL; pNew->pMod = pThis; + if(pThis->eType == eMOD_IN) { + CHKiRet(pThis->mod.im.beginCnfLoad(&pNew->modCnf)); + } + if(pLast == NULL) { loadConf->modules.root = pNew; } else { @@ -401,31 +408,27 @@ static modInfo_t *GetNxt(modInfo_t *pThis) /* this function is like GetNxt(), but it returns pointers to + * the configmodules entry, which than can be used to obtain the + * actual module pointer. Note that it returns those for * modules of specific type only. Only modules from the provided * config are returned. Note that processing speed could be improved, * but this is really not relevant, as config file loading is not really * something we are concerned about in regard to runtime. */ -static modInfo_t *GetNxtCnfType(rsconf_t *cnf, modInfo_t *pThis, eModType_t rqtdType) +static cfgmodules_etry_t +*GetNxtCnfType(rsconf_t *cnf, cfgmodules_etry_t *node, eModType_t rqtdType) { - cfgmodules_etry_t *node; - - if(pThis == NULL) { /* start at beginning of module list */ + if(node == NULL) { /* start at beginning of module list */ node = cnf->modules.root; - } else { /* start at last location - then we need to find the module in the config list */ - for(node = cnf->modules.root ; node != NULL && node->pMod != pThis ; node = node->next) - /*search only, all done in for() */; - if(node != NULL) - node = node->next; /* skip to NEXT element in list */ + } else { + node = node->next; } -dbgprintf("XXXX: entering node, ptr %p: %s\n", node, (node == NULL)? "":modGetName(node->pMod)); while(node != NULL && node->pMod->eType != rqtdType) { node = node->next; /* warning: do ... while() */ -dbgprintf("XXXX: in loop, ptr %p: %s\n", node, (node == NULL)? "":modGetName(node->pMod)); } - return (node == NULL) ? NULL : node->pMod; + return node; } @@ -518,6 +521,11 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ /* ... and now the module-specific interfaces */ switch(pNew->eType) { case eMOD_IN: + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"beginCnfLoad", &pNew->mod.im.beginCnfLoad)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"endCnfLoad", &pNew->mod.im.endCnfLoad)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"freeCnf", &pNew->mod.im.freeCnf)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"checkCnf", &pNew->mod.im.checkCnf)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"activateCnf", &pNew->mod.im.activateCnf)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"runInput", &pNew->mod.im.runInput)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"willRun", &pNew->mod.im.willRun)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"afterRun", &pNew->mod.im.afterRun)); @@ -697,6 +705,9 @@ static void modPrintList(void) break; case eMOD_IN: dbgprintf("Input Module Entry Points\n"); + dbgprintf("\tbeginCnfLoad: 0x%lx\n", (unsigned long) pMod->mod.im.beginCnfLoad); + dbgprintf("\tendCnfLoad: 0x%lx\n", (unsigned long) pMod->mod.im.endCnfLoad); + dbgprintf("\tfreeCnf: 0x%lx\n", (unsigned long) pMod->mod.im.freeCnf); dbgprintf("\trunInput: 0x%lx\n", (unsigned long) pMod->mod.im.runInput); dbgprintf("\twillRun: 0x%lx\n", (unsigned long) pMod->mod.im.willRun); dbgprintf("\tafterRun: 0x%lx\n", (unsigned long) pMod->mod.im.afterRun); @@ -928,7 +939,8 @@ Load(uchar *pModName, sbool bConfLoad) szPath[iPathLen++] = '/'; szPath[iPathLen] = '\0'; } else { - errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, "could not load module '%s', path too long\n", pModName); + errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, + "could not load module '%s', path too long\n", pModName); ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN); } } diff --git a/runtime/modules.h b/runtime/modules.h index 37a73ecd..759e3350 100644 --- a/runtime/modules.h +++ b/runtime/modules.h @@ -110,19 +110,19 @@ struct modInfo_s { 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. - */ - rsRetVal (*parseConfigLine)(uchar **pConfLine); /* below: create an instance of this module. Most importantly the module * can allocate instance memory in this call. */ rsRetVal (*createInstance)(); - /* TODO: pass pointer to msg submit function to IM rger, 2007-12-14 */ union { struct {/* data for input modules */ + rsRetVal (*beginCnfLoad)(void*newCnf); + rsRetVal (*endCnfLoad)(void*Cnf); + rsRetVal (*checkCnf)(void*Cnf); + rsRetVal (*activateCnf)(void*Cnf); /* make provided config the running conf */ + rsRetVal (*freeCnf)(void*Cnf); +/* TODO: remove? */rsRetVal (*willRun)(void); /* check if the current config will be able to run*/ rsRetVal (*runInput)(thrdInfo_t*); /* function to gather input and submit to queue */ - rsRetVal (*willRun)(void); /* function to gather input and submit to queue */ rsRetVal (*afterRun)(thrdInfo_t*); /* function to gather input and submit to queue */ int bCanRun; /* cached value of whether willRun() succeeded */ } im; @@ -159,7 +159,7 @@ struct modInfo_s { /* interfaces */ BEGINinterface(module) /* name must also be changed in ENDinterface macro! */ modInfo_t *(*GetNxt)(modInfo_t *pThis); - modInfo_t *(*GetNxtCnfType)(rsconf_t *cnf, modInfo_t *pThis, eModType_t rqtdType); + cfgmodules_etry_t *(*GetNxtCnfType)(rsconf_t *cnf, cfgmodules_etry_t *pThis, eModType_t rqtdType); uchar *(*GetName)(modInfo_t *pThis); uchar *(*GetStateName)(modInfo_t *pThis); rsRetVal (*Use)(char *srcFile, modInfo_t *pThis); /**< must be called before a module is used (ref counting) */ @@ -180,4 +180,6 @@ ENDinterface(module) /* prototypes */ PROTOTYPEObj(module); +/* TODO: remove "dirty" calls! */ +rsRetVal addModToCnfList(modInfo_t *pThis); #endif /* #ifndef MODULES_H_INCLUDED */ diff --git a/runtime/rsconf.c b/runtime/rsconf.c index 11eea2b7..1e427d42 100644 --- a/runtime/rsconf.c +++ b/runtime/rsconf.c @@ -294,25 +294,94 @@ dropPrivileges(rsconf_t *cnf) } +/* Tell input modules that the config parsing stage is over. */ +static rsRetVal +tellInputsConfigLoadDone(void) +{ + cfgmodules_etry_t *node; + + BEGINfunc + DBGPRINTF("telling inputs that config load for %p is done\n", loadConf); + node = module.GetNxtCnfType(loadConf, NULL, eMOD_IN); + while(node != NULL) { + node->pMod->mod.im.endCnfLoad(node->modCnf); + node = module.GetNxtCnfType(runConf, node, eMOD_IN); + } + + ENDfunc + return RS_RET_OK; /* intentional: we do not care about module errors */ +} + + +/* Tell input modules to verify config object */ +static rsRetVal +tellInputsCheckConfig(void) +{ + cfgmodules_etry_t *node; + rsRetVal localRet; + + BEGINfunc + DBGPRINTF("telling inputs to check config %p\n", loadConf); + node = module.GetNxtCnfType(loadConf, NULL, eMOD_IN); + while(node != NULL) { + localRet = node->pMod->mod.im.checkCnf(node->modCnf); + DBGPRINTF("module %s tells us config can %sbe activated\n", + node->pMod->pszName, (localRet == RS_RET_OK) ? "" : "NOT "); + if(localRet == RS_RET_OK) { + node->canActivate = 1; + } else { + node->canActivate = 0; + } + node = module.GetNxtCnfType(runConf, node, eMOD_IN); + } + + ENDfunc + return RS_RET_OK; /* intentional: we do not care about module errors */ +} + + +/* Tell input modules to activate current running config */ +static rsRetVal +tellInputsActivateConfig(void) +{ + cfgmodules_etry_t *node; + + BEGINfunc + DBGPRINTF("telling inputs to activate config %p\n", runConf); + node = module.GetNxtCnfType(runConf, NULL, eMOD_IN); + while(node != NULL) { + if(node->canActivate) { + DBGPRINTF("activating config %p for module %s\n", + runConf, node->pMod->pszName); + node->pMod->mod.im.activateCnf(node->modCnf); + } + node = module.GetNxtCnfType(runConf, node, eMOD_IN); + } + + ENDfunc + return RS_RET_OK; /* intentional: we do not care about module errors */ +} + + /* Actually run the input modules. This happens after privileges are dropped, * if that is requested. */ static rsRetVal runInputModules(void) { - modInfo_t *pMod; + cfgmodules_etry_t *node; int bNeedsCancel; BEGINfunc - pMod = module.GetNxtCnfType(runConf, NULL, eMOD_IN); - while(pMod != NULL) { - if(pMod->mod.im.bCanRun) { + node = module.GetNxtCnfType(runConf, NULL, eMOD_IN); + while(node != NULL) { + if(node->pMod->mod.im.bCanRun) { /* activate here */ - bNeedsCancel = (pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? + bNeedsCancel = (node->pMod->isCompatibleWithFeature(sFEATURENonCancelInputTermination) == RS_RET_OK) ? 0 : 1; - thrdCreate(pMod->mod.im.runInput, pMod->mod.im.afterRun, bNeedsCancel); + thrdCreate(node->pMod->mod.im.runInput, node->pMod->mod.im.afterRun, bNeedsCancel); } - pMod = module.GetNxtCnfType(runConf, pMod, eMOD_IN); + node = module.GetNxtCnfType(runConf, node, eMOD_IN); } ENDfunc @@ -326,16 +395,16 @@ static rsRetVal startInputModules(void) { DEFiRet; - modInfo_t *pMod; - - pMod = module.GetNxtCnfType(runConf, NULL, eMOD_IN); - while(pMod != NULL) { - iRet = pMod->mod.im.willRun(); - pMod->mod.im.bCanRun = (iRet == RS_RET_OK); - if(!pMod->mod.im.bCanRun) { - DBGPRINTF("module %lx will not run, iRet %d\n", (unsigned long) pMod, iRet); + cfgmodules_etry_t *node; + + node = module.GetNxtCnfType(runConf, NULL, eMOD_IN); + while(node != NULL) { + iRet = node->pMod->mod.im.willRun(); + node->pMod->mod.im.bCanRun = (iRet == RS_RET_OK); + if(!node->pMod->mod.im.bCanRun) { + DBGPRINTF("module %lx will not run, iRet %d\n", (unsigned long) node->pMod, iRet); } - pMod = module.GetNxtCnfType(runConf, pMod, eMOD_IN); + node = module.GetNxtCnfType(runConf, node, eMOD_IN); } ENDfunc @@ -381,6 +450,8 @@ activate(rsconf_t *cnf) if(ourConf->globals.pszConfDAGFile != NULL) generateConfigDAG(ourConf->globals.pszConfDAGFile); # endif + tellInputsConfigLoadDone(); + tellInputsCheckConfig(); /* the output part and the queue is now ready to run. So it is a good time * to initialize the inputs. Please note that the net code above should be @@ -390,6 +461,7 @@ activate(rsconf_t *cnf) * Keep in mind. though, that the outputs already run if the queue was * persisted to disk. -- rgerhards */ + tellInputsActivateConfig(); startInputModules(); CHKiRet(dropPrivileges(cnf)); diff --git a/runtime/rsconf.h b/runtime/rsconf.h index 63754e6f..0718566a 100644 --- a/runtime/rsconf.h +++ b/runtime/rsconf.h @@ -96,6 +96,9 @@ struct defaults_s { struct cfgmodules_etry_s { cfgmodules_etry_t *next; modInfo_t *pMod; + /* the following data is input module specific */ + void *modCnf; /* pointer to the input module conf */ + sbool canActivate; /* OK to activate this config? */ }; struct cfgmodules_s { |