step: added config-specific module list

This commit is contained in:
Rainer Gerhards 2011-04-27 15:38:06 +02:00
parent 17e3f6b49c
commit 4f8457ffe3
7 changed files with 158 additions and 51 deletions

View File

@ -279,7 +279,7 @@ doModLoad(uchar **pp, __attribute__((unused)) void* pVal)
else
pModName = szName;
CHKiRet(module.Load(pModName));
CHKiRet(module.Load(pModName, 1));
finalize_it:
RETiRet;

View File

@ -318,7 +318,7 @@ static uchar *modGetStateName(modInfo_t *pThis)
/* Add a module to the loaded module linked list
*/
static inline void
addModToList(modInfo_t *pThis)
addModToGlblList(modInfo_t *pThis)
{
assert(pThis != NULL);
@ -333,6 +333,53 @@ addModToList(modInfo_t *pThis)
}
/* Add a module to the config module list for current loadConf
*/
static inline rsRetVal
addModToCnfList(modInfo_t *pThis)
{
cfgmodules_etry_t *pNew;
cfgmodules_etry_t *pLast;
DEFiRet;
assert(pThis != NULL);
if(loadConf == NULL) {
/* we are in an early init state */
FINALIZE;
}
/* check for duplicates and, as a side-activity, identify last node */
pLast = loadConf->modules.root;
if(pLast != NULL) {
while(1) { /* loop broken inside */
if(pLast->pMod == pThis) {
DBGPRINTF("module '%s' already in this config\n", modGetName(pThis));
FINALIZE;
}
if(pLast->next == NULL)
break;
pLast = pLast -> next;
}
}
/* if we reach this point, pLast is the tail pointer */
CHKmalloc(pNew = MALLOC(sizeof(cfgmodules_etry_t)));
pNew->next = NULL;
pNew->pMod = pThis;
if(pLast == NULL) {
loadConf->modules.root = pNew;
} else {
/* there already exist entries */
pLast->next = pNew;
}
finalize_it:
RETiRet;
}
/* Get the next module pointer - this is used to traverse the list.
* The function returns the next pointer or NULL, if there is no next one.
* The last object must be provided to the function. If NULL is provided,
@ -407,7 +454,8 @@ finalize_it:
* everything needed to fully initialize the module.
*/
static rsRetVal
doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_t*), uchar *name, void *pModHdlr)
doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_t*),
uchar *name, void *pModHdlr, modInfo_t **pNewModule)
{
rsRetVal localRet;
modInfo_t *pNew = NULL;
@ -569,12 +617,14 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_
}
/* we initialized the structure, now let's add it to the linked list of modules */
addModToList(pNew);
addModToGlblList(pNew);
*pNewModule = pNew;
finalize_it:
if(iRet != RS_RET_OK) {
if(pNew != NULL)
moduleDestruct(pNew);
*pNewModule = NULL;
}
RETiRet;
@ -753,6 +803,27 @@ modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload)
RETiRet;
}
/* find module with given name in global list */
static inline rsRetVal
findModule(uchar *pModName, int iModNameLen, modInfo_t **pMod)
{
modInfo_t *pModInfo;
uchar *pModNameCmp;
DEFiRet;
pModInfo = GetNxt(NULL);
while(pModInfo != NULL) {
if(!strncmp((char *) pModName, (char *) (pModNameCmp = modGetName(pModInfo)), iModNameLen) &&
(!*(pModNameCmp + iModNameLen) || !strcmp((char *) pModNameCmp + iModNameLen, ".so"))) {
dbgprintf("Module '%s' found\n", pModName);
break;
}
pModInfo = GetNxt(pModInfo);
}
*pMod = pModInfo;
RETiRet;
}
/* load a module and initialize it, based on doModLoad() from conf.c
* rgerhards, 2008-03-05
@ -762,15 +833,20 @@ modUnloadAndDestructAll(eModLinkType_t modLinkTypesToUnload)
* configuration file processing, which is executed on a single thread. Should we
* change that design at any stage (what is unlikely), we need to find a
* replacement.
* rgerhards, 2011-04-27:
* Parameter "bConfLoad" tells us if the load was triggered by a config handler, in
* which case we need to tie the loaded module to the current config. If bConfLoad == 0,
* the system loads a module for internal reasons, this is not directly tied to a
* configuration. We could also think if it would be useful to add only certain types
* of modules, but the current implementation at least looks simpler.
*/
static rsRetVal
Load(uchar *pModName)
Load(uchar *pModName, sbool bConfLoad)
{
DEFiRet;
size_t iPathLen, iModNameLen;
uchar szPath[PATH_MAX];
uchar *pModNameCmp;
int bHasExtension;
void *pModHdlr, *pModInit;
modInfo_t *pModInfo;
@ -790,14 +866,12 @@ Load(uchar *pModName)
} else
bHasExtension = FALSE;
pModInfo = GetNxt(NULL);
while(pModInfo != NULL) {
if(!strncmp((char *) pModName, (char *) (pModNameCmp = modGetName(pModInfo)), iModNameLen) &&
(!*(pModNameCmp + iModNameLen) || !strcmp((char *) pModNameCmp + iModNameLen, ".so"))) {
dbgprintf("Module '%s' already loaded\n", pModName);
ABORT_FINALIZE(RS_RET_OK);
}
pModInfo = GetNxt(pModInfo);
CHKiRet(findModule(pModName, iModNameLen, &pModInfo));
if(pModInfo != NULL) {
if(bConfLoad)
addModToCnfList(pModInfo);
dbgprintf("Module '%s' already loaded\n", pModName);
FINALIZE;
}
pModDirCurr = (uchar *)((pModDir == NULL) ?
@ -825,7 +899,8 @@ Load(uchar *pModName)
}
break;
} else if(iPathLen > sizeof(szPath) - 1) {
errmsg.LogError(0, NO_ERRCODE, "could not load module '%s', module path too long\n", pModName);
errmsg.LogError(0, NO_ERRCODE, "could not load module '%s', "
"module path too long\n", pModName);
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
}
@ -851,17 +926,13 @@ Load(uchar *pModName)
/* now see if we have an extension and, if not, append ".so" */
if(!bHasExtension) {
/* we do not have an extension and so need to add ".so"
* TODO: I guess this is highly importable, so we should change the
* algo over time... -- rgerhards, 2008-03-05
*/
/* ... so now add the extension */
strncat((char *) szPath, ".so", sizeof(szPath) - strlen((char*) szPath) - 1);
iPathLen += 3;
}
if(iPathLen + strlen((char*) pModName) >= sizeof(szPath)) {
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);
}
@ -887,7 +958,8 @@ Load(uchar *pModName)
if(!pModHdlr) {
if(iLoadCnt) {
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_DLOPEN, "could not load module '%s', dlopen: %s\n", szPath, dlerror());
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_DLOPEN,
"could not load module '%s', dlopen: %s\n", szPath, dlerror());
} else {
errmsg.LogError(0, NO_ERRCODE, "could not load module '%s', ModDir was '%s'\n", szPath,
((pModDir == NULL) ? _PATH_MODDIR : (char *)pModDir));
@ -895,15 +967,19 @@ Load(uchar *pModName)
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_DLOPEN);
}
if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_NO_INIT, "could not load module '%s', dlsym: %s\n", szPath, dlerror());
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_NO_INIT,
"could not load module '%s', dlsym: %s\n", szPath, dlerror());
dlclose(pModHdlr);
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_NO_INIT);
}
if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) {
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_INIT_FAILED, "could not load module '%s', rsyslog error %d\n", szPath, iRet);
if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr, &pModInfo)) != RS_RET_OK) {
errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_INIT_FAILED,
"could not load module '%s', rsyslog error %d\n", szPath, iRet);
dlclose(pModHdlr);
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED);
}
if(bConfLoad)
addModToCnfList(pModInfo);
finalize_it:
pthread_mutex_unlock(&mutLoadUnload);

View File

@ -166,11 +166,14 @@ BEGINinterface(module) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Release)(char *srcFile, modInfo_t **ppThis); /**< release a module (ref counting) */
void (*PrintList)(void);
rsRetVal (*UnloadAndDestructAll)(eModLinkType_t modLinkTypesToUnload);
rsRetVal (*doModInit)(rsRetVal (*modInit)(), uchar *name, void *pModHdlr);
rsRetVal (*Load)(uchar *name);
rsRetVal (*doModInit)(rsRetVal (*modInit)(), uchar *name, void *pModHdlr, modInfo_t **pNew);
rsRetVal (*Load)(uchar *name, sbool bConfLoad);
rsRetVal (*SetModDir)(uchar *name);
ENDinterface(module)
#define moduleCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
#define moduleCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
/* Changes:
* v2 - added param bCondLoad to Load call - 2011-04-27
*/
/* prototypes */
PROTOTYPEObj(module);

View File

@ -1154,7 +1154,7 @@ UseObj(char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf)
if(pObjFile == NULL) {
FINALIZE; /* no chance, we have lost... */
} else {
CHKiRet(module.Load(pObjFile));
CHKiRet(module.Load(pObjFile, 0));
/* NOW, we must find it or we have a problem... */
CHKiRet(FindObjInfo(pStr, &pObjInfo));
}

View File

@ -155,6 +155,8 @@ ENDobjDestruct(rsconf)
/* DebugPrint support for the rsconf object */
BEGINobjDebugPrint(rsconf) /* be sure to specify the object type also in END and CODESTART macros! */
cfgmodules_etry_t *modNode;
dbgprintf("configuration object %p\n", pThis);
dbgprintf("Global Settings:\n");
dbgprintf(" bDebugPrintTemplateList.............: %d\n",
@ -170,7 +172,7 @@ BEGINobjDebugPrint(rsconf) /* be sure to specify the object type also in END and
dbgprintf(" drop Msgs with malicious PTR Record : %d\n",
glbl.GetDropMalPTRMsgs());
ruleset.DebugPrintAll(pThis);
DBGPRINTF("\n");
dbgprintf("\n");
if(pThis->globals.bDebugPrintTemplateList)
tplPrintList(pThis);
if(pThis->globals.bDebugPrintModuleList)
@ -178,14 +180,17 @@ BEGINobjDebugPrint(rsconf) /* be sure to specify the object type also in END and
if(pThis->globals.bDebugPrintCfSysLineHandlerList)
dbgPrintCfSysLineHandlers();
// TODO: The following code needs to be "streamlined", so far just moved over...
DBGPRINTF("Main queue size %d messages.\n", pThis->globals.mainQ.iMainMsgQueueSize);
DBGPRINTF("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n",
pThis->globals.mainQ.iMainMsgQueueNumWorkers, pThis->globals.mainQ.iMainMsgQtoWrkShutdown, pThis->globals.mainQ.iMainMsgQPersistUpdCnt);
DBGPRINTF("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n",
pThis->globals.mainQ.iMainMsgQtoQShutdown, pThis->globals.mainQ.iMainMsgQtoActShutdown, pThis->globals.mainQ.iMainMsgQtoEnq);
DBGPRINTF("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n",
pThis->globals.mainQ.iMainMsgQHighWtrMark, pThis->globals.mainQ.iMainMsgQLowWtrMark, pThis->globals.mainQ.iMainMsgQDiscardMark, pThis->globals.mainQ.iMainMsgQDiscardSeverity);
DBGPRINTF("Main queue save on shutdown %d, max disk space allowed %lld\n",
dbgprintf("Main queue size %d messages.\n", pThis->globals.mainQ.iMainMsgQueueSize);
dbgprintf("Main queue worker threads: %d, wThread shutdown: %d, Perists every %d updates.\n",
pThis->globals.mainQ.iMainMsgQueueNumWorkers,
pThis->globals.mainQ.iMainMsgQtoWrkShutdown, pThis->globals.mainQ.iMainMsgQPersistUpdCnt);
dbgprintf("Main queue timeouts: shutdown: %d, action completion shutdown: %d, enq: %d\n",
pThis->globals.mainQ.iMainMsgQtoQShutdown,
pThis->globals.mainQ.iMainMsgQtoActShutdown, pThis->globals.mainQ.iMainMsgQtoEnq);
dbgprintf("Main queue watermarks: high: %d, low: %d, discard: %d, discard-severity: %d\n",
pThis->globals.mainQ.iMainMsgQHighWtrMark, pThis->globals.mainQ.iMainMsgQLowWtrMark,
pThis->globals.mainQ.iMainMsgQDiscardMark, pThis->globals.mainQ.iMainMsgQDiscardSeverity);
dbgprintf("Main queue save on shutdown %d, max disk space allowed %lld\n",
pThis->globals.mainQ.bMainMsgQSaveOnShutdown, pThis->globals.mainQ.iMainMsgQueMaxDiskSpace);
/* TODO: add
iActionRetryCount = 0;
@ -196,8 +201,12 @@ BEGINobjDebugPrint(rsconf) /* be sure to specify the object type also in END and
setQPROP(qqueueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100);
setQPROP(qqueueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1);
*/
DBGPRINTF("Work Directory: '%s'.\n", glbl.GetWorkDir());
dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir());
ochPrintList();
dbgprintf("Modules used in this configuration:\n");
for(modNode = pThis->modules.root ; modNode != NULL ; modNode = modNode->next) {
dbgprintf(" %s\n", module.GetName(modNode->pMod));
}
CODESTARTobjDebugPrint(rsconf)
ENDobjDebugPrint(rsconf)
@ -573,6 +582,18 @@ setModDir(void __attribute__((unused)) *pVal, uchar* pszNewVal)
}
/* "load" a build in module and register it for the current load config */
static rsRetVal
regBuildInModule(rsRetVal (*modInit)(), uchar *name, void *pModHdlr)
{
modInfo_t *pMod;
DEFiRet;
CHKiRet(module.doModInit(modInit, name, pModHdlr, &pMod));
finalize_it:
RETiRet;
}
/* load build-in modules
* very first version begun on 2007-07-23 by rgerhards
*/
@ -581,12 +602,12 @@ loadBuildInModules()
{
DEFiRet;
CHKiRet(module.doModInit(modInitFile, UCHAR_CONSTANT("builtin-file"), NULL));
CHKiRet(module.doModInit(modInitPipe, UCHAR_CONSTANT("builtin-pipe"), NULL));
CHKiRet(module.doModInit(modInitShell, UCHAR_CONSTANT("builtin-shell"), NULL));
CHKiRet(module.doModInit(modInitDiscard, UCHAR_CONSTANT("builtin-discard"), NULL));
CHKiRet(regBuildInModule(modInitFile, UCHAR_CONSTANT("builtin-file"), NULL));
CHKiRet(regBuildInModule(modInitPipe, UCHAR_CONSTANT("builtin-pipe"), NULL));
CHKiRet(regBuildInModule(modInitShell, UCHAR_CONSTANT("builtin-shell"), NULL));
CHKiRet(regBuildInModule(modInitDiscard, UCHAR_CONSTANT("builtin-discard"), NULL));
# ifdef SYSLOG_INET
CHKiRet(module.doModInit(modInitFwd, UCHAR_CONSTANT("builtin-fwd"), NULL));
CHKiRet(regBuildInModule(modInitFwd, UCHAR_CONSTANT("builtin-fwd"), NULL));
# endif
/* dirty, but this must be for the time being: the usrmsg module must always be
@ -598,11 +619,11 @@ loadBuildInModules()
* User names now must begin with:
* [a-zA-Z0-9_.]
*/
CHKiRet(module.doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL));
CHKiRet(regBuildInModule(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL));
/* load build-in parser modules */
CHKiRet(module.doModInit(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL));
CHKiRet(module.doModInit(modInitpmrfc3164, UCHAR_CONSTANT("builtin-pmrfc3164"), NULL));
CHKiRet(regBuildInModule(modInitpmrfc5424, UCHAR_CONSTANT("builtin-pmrfc5424"), NULL));
CHKiRet(regBuildInModule(modInitpmrfc3164, UCHAR_CONSTANT("builtin-pmrfc3164"), NULL));
/* and set default parser modules. Order is *very* important, legacy
* (3164) parser needs to go last! */
@ -610,10 +631,10 @@ loadBuildInModules()
CHKiRet(parser.AddDfltParser(UCHAR_CONSTANT("rsyslog.rfc3164")));
/* load build-in strgen modules */
CHKiRet(module.doModInit(modInitsmfile, UCHAR_CONSTANT("builtin-smfile"), NULL));
CHKiRet(module.doModInit(modInitsmtradfile, UCHAR_CONSTANT("builtin-smtradfile"), NULL));
CHKiRet(module.doModInit(modInitsmfwd, UCHAR_CONSTANT("builtin-smfwd"), NULL));
CHKiRet(module.doModInit(modInitsmtradfwd, UCHAR_CONSTANT("builtin-smtradfwd"), NULL));
CHKiRet(regBuildInModule(modInitsmfile, UCHAR_CONSTANT("builtin-smfile"), NULL));
CHKiRet(regBuildInModule(modInitsmtradfile, UCHAR_CONSTANT("builtin-smtradfile"), NULL));
CHKiRet(regBuildInModule(modInitsmfwd, UCHAR_CONSTANT("builtin-smfwd"), NULL));
CHKiRet(regBuildInModule(modInitsmtradfwd, UCHAR_CONSTANT("builtin-smtradfwd"), NULL));
finalize_it:
if(iRet != RS_RET_OK) {

View File

@ -93,7 +93,13 @@ struct defaults_s {
/* list of modules loaded in this configuration (config specific module list) */
struct cfgmodules_etry_s {
cfgmodules_etry_t *next;
modInfo_t *pMod;
};
struct cfgmodules_s {
cfgmodules_etry_t *root;
};
/* outchannel-specific data */

View File

@ -88,6 +88,7 @@ typedef struct defaults_s defaults_t;
typedef struct actions_s actions_t;
typedef struct rsconf_s rsconf_t;
typedef struct cfgmodules_s cfgmodules_t;
typedef struct cfgmodules_etry_s cfgmodules_etry_t;
typedef struct outchannels_s outchannels_t;
typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */
typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */