summaryrefslogtreecommitdiffstats
path: root/runtime/modules.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/modules.c')
-rw-r--r--runtime/modules.c109
1 files changed, 96 insertions, 13 deletions
diff --git a/runtime/modules.c b/runtime/modules.c
index 39f977dd..d3c51e90 100644
--- a/runtime/modules.c
+++ b/runtime/modules.c
@@ -11,7 +11,7 @@
*
* File begun on 2007-07-22 by RGerhards
*
- * Copyright 2007-2011 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -75,6 +75,18 @@ static struct dlhandle_s *pHandles = NULL;
static uchar *pModDir; /* directory where loadable modules are found */
+/* tables for interfacing with the v6 config system */
+/* action (instance) parameters */
+static struct cnfparamdescr actpdescr[] = {
+ { "load", eCmdHdlrGetWord, 1 }
+};
+static struct cnfparamblk pblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(actpdescr)/sizeof(struct cnfparamdescr),
+ actpdescr
+ };
+
+
/* we provide a set of dummy functions for modules that do not support the
* some interfaces.
* On the commit feature: As the modules do not support it, they commit each message they
@@ -337,7 +349,8 @@ addModToGlblList(modInfo_t *pThis)
}
-/* Add a module to the config module list for current loadConf
+/* Add a module to the config module list for current loadConf and
+ * provide its config params to it.
*/
rsRetVal
addModToCnfList(modInfo_t *pThis)
@@ -358,11 +371,16 @@ addModToCnfList(modInfo_t *pThis)
while(1) { /* loop broken inside */
if(pLast->pMod == pThis) {
DBGPRINTF("module '%s' already in this config\n", modGetName(pThis));
+ if(strncmp((char*)modGetName(pThis), "builtin:", sizeof("builtin:")-1)) {
+ errmsg.LogError(0, RS_RET_MODULE_ALREADY_IN_CONF,
+ "module '%s' already in this config, cannot be added\n", modGetName(pThis));
+ ABORT_FINALIZE(RS_RET_MODULE_ALREADY_IN_CONF);
+ }
FINALIZE;
}
if(pLast->next == NULL)
break;
- pLast = pLast -> next;
+ pLast = pLast->next;
}
}
@@ -535,7 +553,7 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_
CHKiRet((*modGetType)(&pNew->eType));
CHKiRet((*pNew->modQueryEtryPt)((uchar*)"getKeepType", &modGetKeepType));
CHKiRet((*modGetKeepType)(&pNew->eKeepType));
- dbgprintf("module %s of type %d being loaded.\n", name, pNew->eType);
+ dbgprintf("module %s of type %d being loaded (keepType=%d).\n", name, pNew->eType, pNew->eKeepType);
/* OK, we know we can successfully work with the module. So we now fill the
* rest of the data elements. First we load the interfaces common to all
@@ -548,6 +566,11 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_
pNew->isCompatibleWithFeature = dummyIsCompatibleWithFeature;
else if(localRet != RS_RET_OK)
ABORT_FINALIZE(localRet);
+ localRet = (*pNew->modQueryEtryPt)((uchar*)"setModCnf", &pNew->setModCnf);
+ if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND)
+ pNew->setModCnf = NULL;
+ else if(localRet != RS_RET_OK)
+ ABORT_FINALIZE(localRet);
/* optional calls for new config system */
localRet = (*pNew->modQueryEtryPt)((uchar*)"getModCnfName", &getModCnfName);
@@ -754,6 +777,7 @@ static void modPrintList(void)
dbgprintf("\tdbgPrintInstInfo: 0x%lx\n", (unsigned long) pMod->dbgPrintInstInfo);
dbgprintf("\tfreeInstance: 0x%lx\n", (unsigned long) pMod->freeInstance);
dbgprintf("\tbeginCnfLoad: 0x%lx\n", (unsigned long) pMod->beginCnfLoad);
+ dbgprintf("\tSetModCnf: 0x%lx\n", (unsigned long) pMod->setModCnf);
dbgprintf("\tcheckCnf: 0x%lx\n", (unsigned long) pMod->checkCnf);
dbgprintf("\tactivateCnfPrePrivDrop: 0x%lx\n", (unsigned long) pMod->activateCnfPrePrivDrop);
dbgprintf("\tactivateCnf: 0x%lx\n", (unsigned long) pMod->activateCnf);
@@ -931,14 +955,12 @@ findModule(uchar *pModName, int iModNameLen, modInfo_t **pMod)
* 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.
+ * Note: pvals = NULL means legacy config system
*/
static rsRetVal
-Load(uchar *pModName, sbool bConfLoad)
+Load(uchar *pModName, sbool bConfLoad, struct nvlst *lst)
{
- DEFiRet;
-
size_t iPathLen, iModNameLen;
- uchar *pModNameCmp;
int bHasExtension;
void *pModHdlr, *pModInit;
modInfo_t *pModInfo;
@@ -952,9 +974,11 @@ Load(uchar *pModName, sbool bConfLoad)
# endif
uchar *pPathBuf = pathBuf;
size_t lenPathBuf = sizeof(pathBuf);
+ rsRetVal localRet;
+ DEFiRet;
assert(pModName != NULL);
- dbgprintf("Requested to load module '%s'\n", pModName);
+ DBGPRINTF("Requested to load module '%s'\n", pModName);
iModNameLen = strlen((char*)pModName);
/* overhead for a full path is potentially 1 byte for a slash,
@@ -972,9 +996,28 @@ Load(uchar *pModName, sbool bConfLoad)
CHKiRet(findModule(pModName, iModNameLen, &pModInfo));
if(pModInfo != NULL) {
- if(bConfLoad)
- addModToCnfList(pModInfo);
- dbgprintf("Module '%s' already loaded\n", pModName);
+ DBGPRINTF("Module '%s' already loaded\n", pModName);
+ if(bConfLoad) {
+ localRet = addModToCnfList(pModInfo);
+ if(pModInfo->setModCnf != NULL && localRet == RS_RET_OK) {
+ if(!strncmp((char*)pModName, "builtin:", sizeof("builtin:")-1)) {
+ if(pModInfo->bSetModCnfCalled) {
+ errmsg.LogError(0, RS_RET_DUP_PARAM,
+ "parameters for built-in module %s already set - ignored\n",
+ pModName);
+ ABORT_FINALIZE(RS_RET_DUP_PARAM);
+ } else {
+ /* for built-in moules, we need to call setModConf,
+ * because there is no way to set parameters at load
+ * time for obvious reasons...
+ */
+ if(lst != NULL)
+ pModInfo->setModCnf(lst);
+ pModInfo->bSetModCnfCalled = 1;
+ }
+ }
+ }
+ }
FINALIZE;
}
@@ -1082,8 +1125,15 @@ Load(uchar *pModName, sbool bConfLoad)
dlclose(pModHdlr);
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED);
}
- if(bConfLoad)
+
+ if(bConfLoad) {
addModToCnfList(pModInfo);
+ if(pModInfo->setModCnf != NULL) {
+ if(lst != NULL)
+ pModInfo->setModCnf(lst);
+ pModInfo->bSetModCnfCalled = 1;
+ }
+ }
finalize_it:
if(pPathBuf != pathBuf) /* used malloc()ed memory? */
@@ -1093,6 +1143,39 @@ finalize_it:
}
+/* the v6+ way of loading modules: process a "module(...)" directive.
+ * rgerhards, 2012-06-20
+ */
+rsRetVal
+modulesProcessCnf(struct cnfobj *o)
+{
+ struct cnfparamvals *pvals;
+ uchar *cnfModName = NULL;
+ int typeIdx;
+ DEFiRet;
+
+ pvals = nvlstGetParams(o->nvlst, &pblk, NULL);
+ if(pvals == NULL) {
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ DBGPRINTF("modulesProcessCnf params:\n");
+ cnfparamsPrint(&pblk, pvals);
+ typeIdx = cnfparamGetIdx(&pblk, "load");
+ if(pvals[typeIdx].bUsed == 0) {
+ errmsg.LogError(0, RS_RET_CONF_RQRD_PARAM_MISSING, "module type missing");
+ ABORT_FINALIZE(RS_RET_CONF_RQRD_PARAM_MISSING);
+ }
+
+ cnfModName = (uchar*)es_str2cstr(pvals[typeIdx].val.d.estr, NULL);
+ iRet = Load(cnfModName, 1, o->nvlst);
+
+finalize_it:
+ free(cnfModName);
+ cnfparamvalsDestruct(pvals, &pblk);
+ RETiRet;
+}
+
+
/* set the default module load directory. A NULL value may be provided, in
* which case any previous value is deleted but no new one set. The caller-provided
* string is duplicated. If it needs to be freed, that's the caller's duty.