diff options
author | Bojan Smojver <bojan@rexursive.com> | 2011-02-23 11:25:43 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2011-02-23 11:25:43 +0100 |
commit | d1eb6e0edc51a78f3209448e800b25eda50340f2 (patch) | |
tree | 6d81c1de98eb0c77affaa2f112b5a0628f54ebc3 /runtime/modules.c | |
parent | ee065f1cb55be56da6ed12b35cd0e686abcb3a10 (diff) | |
download | rsyslog-d1eb6e0edc51a78f3209448e800b25eda50340f2.tar.gz rsyslog-d1eb6e0edc51a78f3209448e800b25eda50340f2.tar.xz rsyslog-d1eb6e0edc51a78f3209448e800b25eda50340f2.zip |
added work-around for bug in gtls, which causes fd leak when using TLS
The capability has been added for module to specify that they do not
like being unloaded.
related bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=222
Signed-off-by: Rainer Gerhards <rgerhards@adiscon.com>
Diffstat (limited to 'runtime/modules.c')
-rw-r--r-- | runtime/modules.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/runtime/modules.c b/runtime/modules.c index d7362753..86e7c695 100644 --- a/runtime/modules.c +++ b/runtime/modules.c @@ -77,6 +77,9 @@ static pthread_mutex_t mutLoadUnload; static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */ static modInfo_t *pLoadedModulesLast = NULL; /* tail-pointer */ +/* already dlopen()-ed libs */ +static struct dlhandle_s *pHandles = NULL; + /* config settings */ uchar *pModDir = NULL; /* read-only after startup */ @@ -232,7 +235,9 @@ static void moduleDestruct(modInfo_t *pThis) # ifdef VALGRIND # warning "dlclose disabled for valgrind" # else - dlclose(pThis->pModHdlr); + if (pThis->eKeepType == eMOD_NOKEEP) { + dlclose(pThis->pModHdlr); + } # endif } @@ -413,6 +418,8 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ strgen_t *pStrgen; /* used for strgen modules */ rsRetVal (*GetName)(uchar**); rsRetVal (*modGetType)(eModType_t *pType); + rsRetVal (*modGetKeepType)(eModKeepType_t *pKeepType); + struct dlhandle_s *pHandle = NULL; DEFiRet; assert(modInit != NULL); @@ -433,6 +440,8 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"getType", &modGetType)); CHKiRet((*modGetType)(&pNew->eType)); + CHKiRet((*pNew->modQueryEtryPt)((uchar*)"getKeepType", &modGetKeepType)); + CHKiRet((*modGetKeepType)(&pNew->eKeepType)); dbgprintf("module of type %d being loaded.\n", pNew->eType); /* OK, we know we can successfully work with the module. So we now fill the @@ -529,11 +538,28 @@ doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_ pNew->pszName = (uchar*) strdup((char*)name); /* we do not care if strdup() fails, we can accept that */ pNew->pModHdlr = pModHdlr; /* TODO: take this from module */ - if(pModHdlr == NULL) + if(pModHdlr == NULL) { pNew->eLinkType = eMOD_LINK_STATIC; - else + } else { pNew->eLinkType = eMOD_LINK_DYNAMIC_LOADED; + /* if we need to keep the linked module, save it */ + if (pNew->eKeepType == eMOD_KEEP) { + if((pHandle = calloc(1, sizeof (*pHandle))) == NULL) { + iRet = RS_RET_OUT_OF_MEMORY; + goto finalize_it; + } + + strncpy((char *)pHandle->szName, + (char *)name, PATH_MAX - 1); + pHandle->szName[PATH_MAX - 1] = '\0'; + pHandle->pModHdlr = pModHdlr; + pHandle->next = pHandles; + + pHandles = pHandle; + } + } + /* we initialized the structure, now let's add it to the linked list of modules */ addModToList(pNew); @@ -740,6 +766,7 @@ Load(uchar *pModName) modInfo_t *pModInfo; uchar *pModDirCurr, *pModDirNext; int iLoadCnt; + struct dlhandle_s *pHandle = NULL; assert(pModName != NULL); dbgprintf("Requested to load module '%s'\n", pModName); @@ -829,7 +856,20 @@ Load(uchar *pModName) /* complete load path constructed, so ... GO! */ dbgprintf("loading module '%s'\n", szPath); - pModHdlr = dlopen((char *) szPath, RTLD_NOW); + + /* see if we have this one already */ + for (pHandle = pHandles; pHandle; pHandle = pHandle->next) { + if (!strcmp((char *)pModName, (char *)pHandle->szName)) { + pModHdlr = pHandle->pModHdlr; + break; + } + } + + /* not found, try to dynamically link it */ + if (!pModHdlr) { + pModHdlr = dlopen((char *) szPath, RTLD_NOW); + } + iLoadCnt++; } while(pModHdlr == NULL && *pModName != '/' && pModDirNext); |