summaryrefslogtreecommitdiffstats
path: root/runtime/modules.c
diff options
context:
space:
mode:
authorBojan Smojver <bojan@rexursive.com>2011-02-23 11:25:43 +0100
committerRainer Gerhards <rgerhards@adiscon.com>2011-02-23 11:25:43 +0100
commitd1eb6e0edc51a78f3209448e800b25eda50340f2 (patch)
tree6d81c1de98eb0c77affaa2f112b5a0628f54ebc3 /runtime/modules.c
parentee065f1cb55be56da6ed12b35cd0e686abcb3a10 (diff)
downloadrsyslog-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.c48
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);