From: aland Date: Sun, 2 Dec 2007 15:48:14 +0000 (+0000) Subject: Call lt_dlexit() AFTER detach modules. X-Git-Tag: release_2_0_0~212 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=ed7e8b26254fab318206e5ab78bbc9e6519280ed;p=freeradius.git Call lt_dlexit() AFTER detach modules. Call xlat_free() AFTER detach modules. Move module instances to a tree, in preparation for getting rid of cf_data (which should help with HUP) --- diff --git a/src/main/mainconfig.c b/src/main/mainconfig.c index a606e8e..3f6170b 100644 --- a/src/main/mainconfig.c +++ b/src/main/mainconfig.c @@ -797,9 +797,7 @@ int free_mainconfig(void) free(mainconfig.radiusd_conf); realms_free(); listen_free(&mainconfig.listen); - xlat_free(); dict_free(); - lt_dlexit(); return 0; } diff --git a/src/main/modules.c b/src/main/modules.c index 47db15b..be3c197 100644 --- a/src/main/modules.c +++ b/src/main/modules.c @@ -42,10 +42,12 @@ typedef struct indexed_modcallable { /* * For each component, keep an ordered list of ones to call. */ -static rbtree_t *components; +static rbtree_t *components = NULL; static rbtree_t *module_tree = NULL; +static rbtree_t *instance_tree = NULL; + typedef struct section_type_value_t { const char *section; const char *typename; @@ -96,14 +98,35 @@ static int indexed_modcallable_cmp(const void *one, const void *two) /* + * Compare two module entries + */ +static int module_instance_cmp(const void *one, const void *two) +{ + const module_instance_t *a = one; + const module_instance_t *b = two; + + return strcmp(a->name, b->name); +} + + +/* * Free a module instance. */ static void module_instance_free(void *data) { module_instance_t *this = data; - if (this->entry->module->detach) + if (this->entry->module->detach) { + int i; + (this->entry->module->detach)(this->insthandle); + for (i = 0; i < 16; i++) { + if (this->old_insthandle[i]) { + (this->entry->module->detach)(this->old_insthandle[i]); + } + } + } + #ifdef HAVE_PTHREAD_H if (this->mutex) { /* @@ -115,6 +138,7 @@ static void module_instance_free(void *data) free(this->mutex); } #endif + memset(this, 0, sizeof(*this)); free(this); } @@ -138,6 +162,7 @@ static void module_entry_free(void *data) module_entry_t *this = data; lt_dlclose(this->handle); /* ignore any errors */ + memset(this, 0, sizeof(*this)); free(this); } @@ -147,9 +172,12 @@ static void module_entry_free(void *data) */ int detach_modules(void) { + rbtree_free(instance_tree); rbtree_free(components); rbtree_free(module_tree); + lt_dlexit(); + return 0; } @@ -165,7 +193,7 @@ static module_entry_t *linkto_module(const char *module_name, lt_dlhandle handle; char module_struct[256]; char *p; - const void *module; + const module_t *module; strlcpy(myentry.name, module_name, sizeof(myentry.name)); node = rbtree_finddata(module_tree, &myentry); @@ -209,7 +237,7 @@ static module_entry_t *linkto_module(const char *module_name, /* * Before doing anything else, check if it's sane. */ - if ((*(const uint32_t *) module) != RLM_MODULE_MAGIC_NUMBER) { + if (module->magic != RLM_MODULE_MAGIC_NUMBER) { lt_dlclose(handle); cf_log_err(cf_sectiontoitem(cs), "Invalid version in module '%s'", @@ -249,7 +277,7 @@ module_instance_t *find_module_instance(CONF_SECTION *modules, { CONF_SECTION *cs; const char *name1, *name2; - module_instance_t *node; + module_instance_t *node, myNode; char module_name[256]; if (!modules) return NULL; @@ -269,7 +297,8 @@ module_instance_t *find_module_instance(CONF_SECTION *modules, /* * If there's already a module instance, return it. */ - node = cf_data_find(cs, "instance"); + strlcpy(myNode.name, instname, sizeof(myNode.name)); + node = rbtree_finddata(instance_tree, &myNode); if (node) return node; name1 = cf_section_name1(cs); @@ -343,7 +372,7 @@ module_instance_t *find_module_instance(CONF_SECTION *modules, } #endif - cf_data_add(cs, "instance", node, module_instance_free); + rbtree_insert(instance_tree, node); return node; } @@ -791,6 +820,8 @@ int module_hup(CONF_SECTION *modules) ci=cf_item_find_next(modules, ci)) { int i; void *insthandle = NULL; + const char *instname; + module_instance_t myNode; /* * If it's not a section, ignore it. @@ -798,8 +829,11 @@ int module_hup(CONF_SECTION *modules) if (!cf_item_is_section(ci)) continue; cs = cf_itemtosection(ci); + instname = cf_section_name2(cs); + if (!instname) instname = cf_section_name1(cs); - node = cf_data_find(cs, "instance"); + strlcpy(myNode.name, instname, sizeof(myNode.name)); + node = rbtree_finddata(instance_tree, &myNode); if (!node || !node->entry->module->instantiate || ((node->entry->module->type & RLM_TYPE_HUP_SAFE) == 0)) { @@ -878,6 +912,8 @@ int setup_modules(int reload, CONF_SECTION *config) rad_listen_t *listener; int null_server = FALSE; + if (reload) return 0; + /* * If necessary, initialize libltdl. */ @@ -913,8 +949,13 @@ int setup_modules(int reload, CONF_SECTION *config) radlog(L_ERR, "Failed to initialize modules\n"); return -1; } - } else { - rbtree_free(components); + + instance_tree = rbtree_create(module_instance_cmp, + module_instance_free, 0); + if (!instance_tree) { + radlog(L_ERR, "Failed to initialize modules\n"); + return -1; + } } components = rbtree_create(indexed_modcallable_cmp, diff --git a/src/main/radiusd.c b/src/main/radiusd.c index 02c9705..e1c33bb 100644 --- a/src/main/radiusd.c +++ b/src/main/radiusd.c @@ -483,6 +483,8 @@ int main(int argc, char *argv[]) */ detach_modules(); + xlat_free(); /* modules may have xlat's */ + free(radius_dir); #ifdef WIN32