diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-09-27 16:25:53 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-09-27 16:25:53 +0200 |
commit | a96e4966677d21e8bda6ed47b2ee72f565478562 (patch) | |
tree | 485ddc0c5628cad7dbc13be0760a7a936216a63f /runtime | |
parent | 4cc23e9dc9e906e18539015081b2e5ad16b29417 (diff) | |
parent | 53df5066688c8472a9f7be5c86bbc253378e6572 (diff) | |
download | rsyslog-a96e4966677d21e8bda6ed47b2ee72f565478562.tar.gz rsyslog-a96e4966677d21e8bda6ed47b2ee72f565478562.tar.xz rsyslog-a96e4966677d21e8bda6ed47b2ee72f565478562.zip |
Merge branch 'v6-devel'
Conflicts:
ChangeLog
action.c
grammar/grammar.y
runtime/modules.h
runtime/rsconf.c
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/module-template.h | 28 | ||||
-rw-r--r-- | runtime/modules.c | 70 | ||||
-rw-r--r-- | runtime/modules.h | 5 | ||||
-rw-r--r-- | runtime/rsconf.c | 58 | ||||
-rw-r--r-- | runtime/rsyslog.h | 1 | ||||
-rw-r--r-- | runtime/typedefs.h | 2 |
6 files changed, 151 insertions, 13 deletions
diff --git a/runtime/module-template.h b/runtime/module-template.h index 5d32b909..9dd759a5 100644 --- a/runtime/module-template.h +++ b/runtime/module-template.h @@ -353,6 +353,24 @@ finalize_it:\ } +/* newInpInst() + * This is basically the equivalent to newActInst() for creating input + * module (listener) instances. + */ +#define BEGINnewInpInst \ +static rsRetVal newInpInst(struct nvlst *lst)\ +{\ + DEFiRet; + +#define CODESTARTnewInpInst \ + +#define CODE_STD_FINALIZERnewInpInst + +#define ENDnewInpInst \ + RETiRet;\ +} + + /* tryResume() * This entry point is called to check if a module can resume operations. This * happens when a module requested that it be suspended. In suspended state, @@ -521,6 +539,16 @@ static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\ CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES +/* the following block is to be added for input modules that support the v2 + * config system. The config name is also provided. + */ +#define CODEqueryEtryPt_STD_CONF2_IMOD_QUERIES \ + else if(!strcmp((char*) name, "newInpInst")) {\ + *pEtryPoint = newInpInst;\ + } \ + CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES + + /* the following block is to be added for modules that require * pre priv drop activation support. */ diff --git a/runtime/modules.c b/runtime/modules.c index 8675e414..9f7ff31c 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -350,11 +350,13 @@ addModToGlblList(modInfo_t *pThis) } -/* Add a module to the config module list for current loadConf and - * provide its config params to it. +/* ready module for config processing. this includes checking if the module + * is already in the config, so this function may return errors. Returns a + * pointer to the last module inthe current config. That pointer needs to + * be passed to addModToCnfLst() when it is called later in the process. */ rsRetVal -addModToCnfList(modInfo_t *pThis) +readyModForCnf(modInfo_t *pThis, cfgmodules_etry_t **ppNew, cfgmodules_etry_t **ppLast) { cfgmodules_etry_t *pNew; cfgmodules_etry_t *pLast; @@ -362,8 +364,7 @@ addModToCnfList(modInfo_t *pThis) assert(pThis != NULL); if(loadConf == NULL) { - /* we are in an early init state */ - FINALIZE; + FINALIZE; /* we are in an early init state */ } /* check for duplicates and, as a side-activity, identify last node */ @@ -399,6 +400,36 @@ addModToCnfList(modInfo_t *pThis) CHKiRet(pThis->beginCnfLoad(&pNew->modCnf, loadConf)); } + *ppLast = pLast; + *ppNew = pNew; +finalize_it: + RETiRet; +} + + +/* abort the creation of a module entry without adding it to the + * module list. Needed to prevent mem leaks. + */ +static inline void +abortCnfUse(cfgmodules_etry_t *pNew) +{ + free(pNew); +} + + +/* Add a module to the config module list for current loadConf. + * Requires last pointer obtained by readyModForCnf(). + */ +rsRetVal +addModToCnfList(cfgmodules_etry_t *pNew, cfgmodules_etry_t *pLast) +{ + DEFiRet; + assert(pNew != NULL); + + if(loadConf == NULL) { + FINALIZE; /* we are in an early init state */ + } + if(pLast == NULL) { loadConf->modules.root = pNew; } else { @@ -608,6 +639,12 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"willRun", &pNew->mod.im.willRun)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"afterRun", &pNew->mod.im.afterRun)); pNew->mod.im.bCanRun = 0; + localRet = (*pNew->modQueryEtryPt)((uchar*)"newInpInst", &pNew->mod.im.newInpInst); + if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { + pNew->mod.om.newActInst = NULL; + } else if(localRet != RS_RET_OK) { + ABORT_FINALIZE(localRet); + } break; case eMOD_OUT: CHKiRet((*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance)); @@ -626,7 +663,8 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ else if(localRet != RS_RET_OK) ABORT_FINALIZE(localRet); - localRet = (*pNew->modQueryEtryPt)((uchar*)"endTransaction", &pNew->mod.om.endTransaction); + localRet = (*pNew->modQueryEtryPt)((uchar*)"endTransaction", + &pNew->mod.om.endTransaction); if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.endTransaction = dummyEndTransaction; } else if(localRet != RS_RET_OK) { @@ -965,6 +1003,8 @@ Load(uchar *pModName, sbool bConfLoad, struct nvlst *lst) int bHasExtension; void *pModHdlr, *pModInit; modInfo_t *pModInfo; + cfgmodules_etry_t *pNew; + cfgmodules_etry_t *pLast; uchar *pModDirCurr, *pModDirNext; int iLoadCnt; struct dlhandle_s *pHandle = NULL; @@ -999,8 +1039,9 @@ Load(uchar *pModName, sbool bConfLoad, struct nvlst *lst) if(pModInfo != NULL) { DBGPRINTF("Module '%s' already loaded\n", pModName); if(bConfLoad) { - localRet = addModToCnfList(pModInfo); + localRet = readyModForCnf(pModInfo, &pNew, &pLast); if(pModInfo->setModCnf != NULL && localRet == RS_RET_OK) { + addModToCnfList(pNew, pLast); if(!strncmp((char*)pModName, "builtin:", sizeof("builtin:")-1)) { if(pModInfo->bSetModCnfCalled) { errmsg.LogError(0, RS_RET_DUP_PARAM, @@ -1128,12 +1169,21 @@ Load(uchar *pModName, sbool bConfLoad, struct nvlst *lst) } if(bConfLoad) { - addModToCnfList(pModInfo); + readyModForCnf(pModInfo, &pNew, &pLast); if(pModInfo->setModCnf != NULL) { - if(lst != NULL) - pModInfo->setModCnf(lst); + if(lst != NULL) { + localRet = pModInfo->setModCnf(lst); + if(localRet != RS_RET_OK) { + errmsg.LogError(0, localRet, + "module '%s', failed processing config parameters", + pPathBuf); + abortCnfUse(pNew); + ABORT_FINALIZE(localRet); + } + } pModInfo->bSetModCnfCalled = 1; } + addModToCnfList(pNew, pLast); } finalize_it: diff --git a/runtime/modules.h b/runtime/modules.h index 16425beb..e42d19e1 100644 --- a/runtime/modules.h +++ b/runtime/modules.h @@ -131,6 +131,7 @@ struct modInfo_s { /* 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 (*afterRun)(thrdInfo_t*); /* function to gather input and submit to queue */ + rsRetVal (*newInpInst)(struct nvlst *lst); int bCanRun; /* cached value of whether willRun() succeeded */ } im; struct {/* data for output modules */ @@ -194,6 +195,6 @@ PROTOTYPEObj(module); */ rsRetVal modulesProcessCnf(struct cnfobj *o); uchar *modGetName(modInfo_t *pThis); - -rsRetVal addModToCnfList(modInfo_t *pThis); +rsRetVal addModToCnfList(cfgmodules_etry_t *pNew, cfgmodules_etry_t *pLast); +rsRetVal readyModForCnf(modInfo_t *pThis, cfgmodules_etry_t **ppNew, cfgmodules_etry_t **ppLast); #endif /* #ifndef MODULES_H_INCLUDED */ diff --git a/runtime/rsconf.c b/runtime/rsconf.c index 2cffd14c..b45746c4 100644 --- a/runtime/rsconf.c +++ b/runtime/rsconf.c @@ -97,6 +97,17 @@ static uchar template_SysklogdFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogta static uchar template_StdJSONFmt[] = "\"{\\\"message\\\":\\\"%msg:::json%\\\",\\\"fromhost\\\":\\\"%HOSTNAME:::json%\\\",\\\"facility\\\":\\\"%syslogfacility-text%\\\",\\\"priority\\\":\\\"%syslogpriority-text%\\\",\\\"timereported\\\":\\\"%timereported:::date-rfc3339%\\\",\\\"timegenerated\\\":\\\"%timegenerated:::date-rfc3339%\\\"}\""; /* end templates */ +/* tables for interfacing with the v6 config system (as far as we need to) */ +static struct cnfparamdescr inppdescr[] = { + { "type", eCmdHdlrString, CNFPARAM_REQUIRED } +}; +static struct cnfparamblk inppblk = + { CNFPARAMBLK_VERSION, + sizeof(inppdescr)/sizeof(struct cnfparamdescr), + inppdescr + }; + +/* forward-definitions */ void cnfDoCfsysline(char *ln); /* Standard-Constructor @@ -323,6 +334,45 @@ finalize_it: return estr; } + +/* Process input() objects */ +rsRetVal +inputProcessCnf(struct cnfobj *o) +{ + struct cnfparamvals *pvals; + modInfo_t *pMod; + uchar *cnfModName = NULL; + int typeIdx; + DEFiRet; + + pvals = nvlstGetParams(o->nvlst, &inppblk, NULL); + if(pvals == NULL) { + ABORT_FINALIZE(RS_RET_ERR); + } + DBGPRINTF("input param blk after inputProcessCnf:\n"); + cnfparamsPrint(&inppblk, pvals); + typeIdx = cnfparamGetIdx(&inppblk, "type"); + if(pvals[typeIdx].bUsed == 0) { + errmsg.LogError(0, RS_RET_CONF_RQRD_PARAM_MISSING, "input type missing"); + ABORT_FINALIZE(RS_RET_CONF_RQRD_PARAM_MISSING); // TODO: move this into rainerscript handlers + } + cnfModName = (uchar*)es_str2cstr(pvals[typeIdx].val.d.estr, NULL); + if((pMod = module.FindWithCnfName(loadConf, cnfModName, eMOD_IN)) == NULL) { + errmsg.LogError(0, RS_RET_MOD_UNKNOWN, "input module name '%s' is unknown", cnfModName); + ABORT_FINALIZE(RS_RET_MOD_UNKNOWN); + } + if(pMod->mod.im.newInpInst == NULL) { + errmsg.LogError(0, RS_RET_MOD_NO_INPUT_STMT, + "input module '%s' does not support input() statement", cnfModName); + ABORT_FINALIZE(RS_RET_MOD_NO_INPUT_STMT); + } + CHKiRet(pMod->mod.im.newInpInst(o->nvlst)); +finalize_it: + free(cnfModName); + cnfparamvalsDestruct(pvals, &inppblk); + RETiRet; +} + /*------------------------------ interface to flex/bison parser ------------------------------*/ extern int yylineno; @@ -360,6 +410,9 @@ void cnfDoObj(struct cnfobj *o) case CNFOBJ_MODULE: modulesProcessCnf(o); break; + case CNFOBJ_INPUT: + inputProcessCnf(o); + break; case CNFOBJ_TPL: tplProcessCnf(o); break; @@ -941,10 +994,13 @@ setModDir(void __attribute__((unused)) *pVal, uchar* pszNewVal) static rsRetVal regBuildInModule(rsRetVal (*modInit)(), uchar *name, void *pModHdlr) { + cfgmodules_etry_t *pNew; + cfgmodules_etry_t *pLast; modInfo_t *pMod; DEFiRet; CHKiRet(module.doModInit(modInit, name, pModHdlr, &pMod)); - addModToCnfList(pMod); + readyModForCnf(pMod, &pNew, &pLast); + addModToCnfList(pNew, pLast); finalize_it: RETiRet; } diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index fe9f856a..336ab5bf 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -381,6 +381,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_MODULE_ALREADY_IN_CONF = -2221, /**< module already in current configuration */ RS_RET_PARAM_NOT_PERMITTED = -2222, /**< legacy parameter no longer permitted (usally already set by v2) */ RS_RET_NO_JSON_PASSING = -2223, /**< rsyslog core does not support JSON-passing plugin API */ + RS_RET_MOD_NO_INPUT_STMT = -2224, /**< (input) module does not support input() statement */ /**** up to 2300 is reserved for v6 use ****/ RS_RET_JNAME_NO_ROOT = -2301, /**< root element is missing in JSON path */ diff --git a/runtime/typedefs.h b/runtime/typedefs.h index b53c36f5..b99daed7 100644 --- a/runtime/typedefs.h +++ b/runtime/typedefs.h @@ -156,6 +156,8 @@ typedef enum cslCmdHdlrType { eCmdHdlrBinary, eCmdHdlrFileCreateMode, eCmdHdlrInt, + eCmdHdlrNonNegInt, + eCmdHdlrPositiveInt, eCmdHdlrSize, eCmdHdlrGetChar, eCmdHdlrFacility, |