From: Arran Cudbard-Bell Date: Mon, 19 Jun 2017 18:14:16 +0000 (-0400) Subject: Move more boilerplate code into the dl API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc4c65e72f07d94f0fea0f3b7778f59daa7bba15;p=thirdparty%2Ffreeradius-server.git Move more boilerplate code into the dl API the main function now creates structures containing the parent instance, the instance, and the module handle. --- diff --git a/src/include/dl.h b/src/include/dl.h index b6d6818e83b..9844522c142 100644 --- a/src/include/dl.h +++ b/src/include/dl.h @@ -150,31 +150,31 @@ struct dl_module { /** A module/inst tuple * - * Used to pass data back from dl_submodule_parse_func + * Used to pass data back from dl_instance_parse_func */ -typedef struct { +typedef struct dl_instance dl_instance_t; +struct dl_instance { + char const *name; //!< Instance name. dl_t const *module; - void *inst; + void *data; //!< Module instance's parsed configuration. CONF_SECTION *conf; //!< Module's instance configuration. -} dl_submodule_t; - - -int dl_symbol_init_cb_register(char const *symbol, dl_init_t func, void *ctx); + dl_instance_t const *parent; //!< Parent module's instance (if any). +}; -void dl_symbol_init_cb_unregister(char const *symbol, dl_init_t func); +int dl_symbol_init_cb_register(char const *symbol, dl_init_t func, void *ctx); -int dl_symbol_free_cb_register(char const *symbol, dl_free_t func, void *ctx); +void dl_symbol_init_cb_unregister(char const *symbol, dl_init_t func); -void dl_symbol_free_cb_unregister(char const *symbol, dl_free_t func); +int dl_symbol_free_cb_register(char const *symbol, dl_free_t func, void *ctx); -int dl_instance_data_alloc(TALLOC_CTX *ctx, void **out, dl_t const *module, CONF_SECTION *cs); +void dl_symbol_free_cb_unregister(char const *symbol, dl_free_t func); -dl_t const *dl_by_symbol(void *sym); +dl_instance_t const *dl_instance_find(void *data); -dl_t const *dl_module(CONF_SECTION *conf, dl_t const *parent, char const *name, dl_type_t type); +dl_t const *dl_module(CONF_SECTION *conf, dl_t const *parent, char const *name, dl_type_t type); /* DEPRECATED */ -int dl_submodule(TALLOC_CTX *ctx, dl_submodule_t **out, - CONF_SECTION *conf, dl_t const *parent, char const *name); +int dl_instance(TALLOC_CTX *ctx, dl_instance_t **out, + CONF_SECTION *conf, dl_instance_t const *parent, char const *name, dl_type_t type); #ifdef __cplusplus } diff --git a/src/include/heap.h b/src/include/heap.h index bda5d740d75..3395ed4fa5a 100644 --- a/src/include/heap.h +++ b/src/include/heap.h @@ -35,7 +35,6 @@ typedef int (*fr_heap_cmp_t)(void const *, void const *); typedef struct fr_heap_t fr_heap_t; fr_heap_t *fr_heap_create(fr_heap_cmp_t cmp, size_t offset); -void fr_heap_delete(fr_heap_t *hp); int fr_heap_insert(fr_heap_t *hp, void *data); int fr_heap_extract(fr_heap_t *hp, void *data); diff --git a/src/include/modpriv.h b/src/include/modpriv.h index 7d108ec087d..ff9ba425030 100644 --- a/src/include/modpriv.h +++ b/src/include/modpriv.h @@ -42,14 +42,12 @@ extern "C" { typedef struct { char const *name; //!< Instance name e.g. user_database. - rad_module_t const *module; //!< Module this is an instance of. - dl_t const *handle; //!< dlhandle of module. + dl_instance_t *dl_inst; //!< Structure containing the module's instance data, + //!< configuration, and dl handle. - void *data; //!< The module's private instance data, containing. - //!< its parsed configuration and static state. - pthread_mutex_t *mutex; + rad_module_t const *module; //!< Public module structure. Cached for convenience. - CONF_SECTION *cs; //!< Configuration section in modules {}. + pthread_mutex_t *mutex; bool instantiated; //!< Whether the module has been instantiated yet. diff --git a/src/lib/io/application.h b/src/lib/io/application.h index a1b4574436a..e28b7422ed5 100644 --- a/src/lib/io/application.h +++ b/src/lib/io/application.h @@ -49,7 +49,7 @@ typedef void (*fr_app_set_process_t)(void const *instance, REQUEST *request); * @param[in] instance of #fr_app_process_t or #fr_app_io_t. * @param[in] uctx provided by caller. */ -typedef void (*fr_app_set_uctx_t)(void *instance, void *uctx); +typedef void (*fr_app_set_parent_inst_t)(void *instance, void *uctx); /** Describes a new application (protocol) * @@ -73,7 +73,7 @@ typedef struct fr_app_process_t { fr_app_bootstrap_t bootstrap; fr_app_instantiate_t instantiate; - fr_app_set_uctx_t set_uctx; //!< Allow the submodule to receive data from the main module. + fr_app_set_parent_inst_t set_parent_inst;//!< Allow the submodule to receive data from the main module. fr_io_process_t process; //!< Entry point into the protocol subtype's state machine. } fr_app_process_t; @@ -86,9 +86,9 @@ typedef struct fr_app_io_t { fr_app_bootstrap_t bootstrap; fr_app_instantiate_t instantiate; - fr_app_set_uctx_t set_uctx; //!< Allow the submodule to receive data from the main module. + fr_app_set_parent_inst_t set_parent_inst; //!< Allow the submodule to receive data from the main module. - size_t default_message_size; // Usually minimum message size + size_t default_message_size; // Usually minimum message size fr_io_open_t open; //!< Open a new socket for listening, or accept/connect a new //!< connection. diff --git a/src/lib/util/event.c b/src/lib/util/event.c index dd249b6f91d..41e9a79cbc1 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -993,7 +993,7 @@ static int _event_list_free(fr_event_list_t *el) fr_event_timer_delete(el, &ev); } - fr_heap_delete(el->times); + talloc_free(el->times); close(el->kq); diff --git a/src/lib/util/heap.c b/src/lib/util/heap.c index fcfabe10168..200d96ba955 100644 --- a/src/lib/util/heap.c +++ b/src/lib/util/heap.c @@ -54,13 +54,6 @@ struct fr_heap_t { static int fr_heap_bubble(fr_heap_t *hp, size_t child); -void fr_heap_delete(fr_heap_t *hp) -{ - if (!hp) return; - - talloc_free(hp); -} - fr_heap_t *fr_heap_create(fr_heap_cmp_t cmp, size_t offset) { fr_heap_t *fh; @@ -383,7 +376,7 @@ int main(int argc, char **argv) fr_exit(1); } - fr_heap_delete(hp); + talloc_free(hp); return 0; } diff --git a/src/main/command.c b/src/main/command.c index 4f473565b05..4aa3c0e6c1c 100644 --- a/src/main/command.c +++ b/src/main/command.c @@ -1018,7 +1018,7 @@ static int command_show_module_config(rad_listen_t *listener, int argc, char *ar return CMD_FAIL; } - cprint_conf_parser(listener, 0, instance->cs, instance->data); + cprint_conf_parser(listener, 0, instance->dl_inst->conf, instance->dl_inst->data); return CMD_OK; } @@ -2491,7 +2491,7 @@ static int command_set_module_config(rad_listen_t *listener, int argc, char *arg return 0; } - variables = cf_section_parse_table(instance->cs); + variables = cf_section_parse_table(instance->dl_inst->conf); if (!variables) { cprintf_error(listener, "Cannot find configuration for module\n"); return 0; @@ -2526,9 +2526,9 @@ static int command_set_module_config(rad_listen_t *listener, int argc, char *arg return 0; } - data = ((char *) instance->data) + variables[i].offset; + data = ((char *) instance->dl_inst->data) + variables[i].offset; - cp = cf_pair_find(instance->cs, argv[1]); + cp = cf_pair_find(instance->dl_inst->conf, argv[1]); if (!cp) return 0; /* @@ -2539,9 +2539,9 @@ static int command_set_module_config(rad_listen_t *listener, int argc, char *arg * If it's a string, look for leading single/double quotes, * end then call tokenize functions??? */ - cf_pair_replace(instance->cs, cp, argv[2]); + cf_pair_replace(instance->dl_inst->conf, cp, argv[2]); - rcode = cf_pair_parse(NULL, instance->cs, argv[1], variables[i].type, data, argv[2], T_DOUBLE_QUOTED_STRING); + rcode = cf_pair_parse(NULL, instance->dl_inst->conf, argv[1], variables[i].type, data, argv[2], T_DOUBLE_QUOTED_STRING); if (rcode < 0) { cprintf_error(listener, "Failed to parse value\n"); return 0; diff --git a/src/main/dl.c b/src/main/dl.c index 240eec8bd0c..b99628effdb 100644 --- a/src/main/dl.c +++ b/src/main/dl.c @@ -52,7 +52,6 @@ RCSID("$Id$") char const *radlib_dir; - /** Symbol dependent initialisation callback * * Call this function when the module is loaded for the first time. @@ -95,11 +94,11 @@ typedef struct dl_loader { */ dl_symbol_free_t *sym_free; - /** Tree to map main symbol to dl_handle_t + /** Tree to map instance to dl_handle_t * * Used by modules to get their own dl_handle_t for loading submodules. */ - rbtree_t *sym_tree; + rbtree_t *inst_tree; /** Tree of shared objects loaded */ @@ -152,13 +151,13 @@ static int dl_symbol_free_cmp(void const *one, void const *two) return 0; } -static int dl_symbol_cmp(void const *one, void const *two) +static int dl_inst_cmp(void const *one, void const *two) { - dl_t const *a = one; - dl_t const *b = two; + dl_instance_t const *a = one; + dl_instance_t const *b = two; - if (a->common > b->common) return +1; - if (a->common < b->common) return -1; + if (a->data > b->data) return +1; + if (a->data < b->data) return -1; return 0; } @@ -388,51 +387,6 @@ static void *dl_by_name(char const *name) return handle; } -/** Allocate module instance data, and parse the module's configuration - * - * @param[in] ctx to allocate this instance data in. - * @param[out] data Module's private data, the result of parsing the config. - * @param[in] module to alloc instance data for. - * @param[in] cs module's config section. - * @return - * - 0 on success. - * - -1 on failure. - */ -int dl_instance_data_alloc(TALLOC_CTX *ctx, void **data, dl_t const *module, CONF_SECTION *cs) -{ - *data = NULL; - - if (module->common->inst_size == 0) return 0; - - /* - * If there is supposed to be instance data, allocate it now. - * Also parse the configuration data, if required. - */ - MEM(*data = talloc_zero_array(ctx, uint8_t, module->common->inst_size)); - - if (!module->common->inst_type) { - talloc_set_name(*data, "%s_t", module->name ? module->name : "config"); - } else { - talloc_set_name(*data, "%s", module->common->inst_type); - } - - if (module->common->config) { - if ((cf_section_rules_push(cs, module->common->config)) < 0 || - (cf_section_parse(*data, *data, cs) < 0)) { - cf_log_err(cs, "Invalid configuration for module \"%s\"", module->name); - talloc_free(*data); - return -1; - } - } - - /* - * Set the destructor. - */ - if (module->common->detach) talloc_set_destructor((void *)*data, module->common->detach); - - return 0; -} - /** Walk over the registered init callbacks, searching for the symbols they depend on * * Allows code outside of the dl API to register initialisation functions that get @@ -530,8 +484,6 @@ static int _dl_free(dl_t *module) module->handle = NULL; rbtree_deletebydata(dl->tree, module); - rbtree_deletebydata(dl->sym_tree, module); - if (rbtree_num_elements(dl->tree) == 0) talloc_free(dl); return 0; @@ -642,16 +594,54 @@ void dl_symbol_free_cb_unregister(char const *symbol, dl_free_t func) if (found) talloc_free(fr_cursor_remove(&cursor)); } -/** Lookup a dl_t via its public symbol +/** Lookup a dl_instance_t via instance data * */ -dl_t const *dl_by_symbol(void *sym) +dl_instance_t const *dl_instance_find(void *data) { - dl_t find; + dl_instance_t find = { .data = data }; - find.common = sym; + return rbtree_finddata(dl->inst_tree, &find); +} - return rbtree_finddata(dl->sym_tree, &find); +/** Allocate module instance data, and parse the module's configuration + * + * @param[in] ctx to allocate this instance data in. + * @param[out] data Module's private data, the result of parsing the config. + * @param[in] module to alloc instance data for. + * @param[in] cs module's config section. + * @return + * - 0 on success. + * - -1 on failure. + */ +static int dl_instance_data_alloc(TALLOC_CTX *ctx, void **data, dl_t const *module, CONF_SECTION *cs) +{ + *data = NULL; + + if (module->common->inst_size == 0) return 0; + + /* + * If there is supposed to be instance data, allocate it now. + * Also parse the configuration data, if required. + */ + MEM(*data = talloc_zero_array(ctx, uint8_t, module->common->inst_size)); + + if (!module->common->inst_type) { + talloc_set_name(*data, "%s_t", module->name ? module->name : "config"); + } else { + talloc_set_name(*data, "%s", module->common->inst_type); + } + + if (module->common->config) { + if ((cf_section_rules_push(cs, module->common->config)) < 0 || + (cf_section_parse(*data, *data, cs) < 0)) { + cf_log_err(cs, "Invalid configuration for module \"%s\"", module->name); + talloc_free(*data); + return -1; + } + } + + return 0; } /** Load a module library using dlopen() or return a previously loaded module from the cache @@ -757,7 +747,7 @@ dl_t const *dl_module(CONF_SECTION *conf, dl_t const *parent, char const *name, /* * Add the module to the dlhandle cache */ - if (!rbtree_insert(dl->tree, dl_module) || !rbtree_insert(dl->sym_tree, dl_module)) { + if (!rbtree_insert(dl->tree, dl_module)) { cf_log_err(conf, "Failed to cache module \"%s\"", module_name); goto error; } @@ -767,47 +757,94 @@ dl_t const *dl_module(CONF_SECTION *conf, dl_t const *parent, char const *name, return dl_module; } -/** Load a submodule and parse its #CONF_SECTION in one operation + +/** Free a module instance, removing it from the instance tree + * + * Also decrements the reference count of the module potentially unloading it. + * + * @param[in] dl_inst to free. + * @return 0. + */ +static int _dl_instance_free(dl_instance_t *dl_inst) +{ + if (dl_inst->module && dl_inst->module->common->detach) { + dl_inst->module->common->detach(dl_inst->data); + } + + /* + * Remove this instance from the tracking tree. + */ + rbtree_deletebydata(dl->inst_tree, dl_inst); + + /* + * Ensure sane free order, and that all destructors + * run before the .so/.dylib is unloaded. + */ + talloc_free_children(dl_inst); + + /* + * Decrements the reference count. The module object + * won't be unloaded until all instances of that module + * have been destroyed. + */ + talloc_decrease_ref_count(dl_inst->module); + + return 0; +} + +/** Load a module and parse its #CONF_SECTION in one operation + * * - * @note This is here as a convenience function for wrapping by #cf_parse_t callbacks. + * When this instance is no longer needed, it should be freed with talloc_free(). + * When all instances of a particular module are unloaded, the dl handle will be closed, + * unloading the module. * * @param[in] ctx to allocate structures in. - * @param[out] out where to write our #dl_submodule_t containing the module + * @param[out] out where to write our #dl_instance_t containing the module * handle and instance. * @param[in] conf section to parse. - * @param[in] parent module. - * @param[in] name of the submodule to load .e.g. 'udp' for 'proto_radius_udp' + * @param[in] parent of module instance. + * @param[in] name of the module to load .e.g. 'udp' for 'proto_radius_udp' * if the parent were 'proto_radius'. - + * @param[in] type of module to load. + * * @return * - 0 on success. * - -1 on failure. */ -int dl_submodule(TALLOC_CTX *ctx, dl_submodule_t **out, - CONF_SECTION *conf, dl_t const *parent, char const *name) +int dl_instance(TALLOC_CTX *ctx, dl_instance_t **out, + CONF_SECTION *conf, dl_instance_t const *parent, + char const *name, dl_type_t type) { - dl_submodule_t *submodule = talloc_zero(ctx, dl_submodule_t); + dl_instance_t *dl_inst; + + MEM(dl_inst = talloc_zero(ctx, dl_instance_t)); + talloc_set_destructor(dl_inst, _dl_instance_free); /* - * Find a section with the same name as the submodule + * Find a section with the same name as the module */ - submodule->module = dl_module(conf, parent, name, DL_TYPE_SUBMODULE); - if (!submodule->module) { - cf_log_err(conf, "Failed finding submodule library for '%s_%s'", parent->name, name); + dl_inst->module = dl_module(conf, parent ? parent->module : NULL, name, type); + if (!dl_inst->module) { + cf_log_err(conf, "Failed finding dl_instance library for '%s_%s'", parent->module->common->name, name); + talloc_free(dl_inst); return -1; } /* * ctx here is the main module's instance data */ - if (dl_instance_data_alloc(submodule, &submodule->inst, submodule->module, conf) < 0) { - cf_log_perr(conf, "Failed allocating instance data for '%s_%s'", parent->name, name); + if (dl_instance_data_alloc(dl_inst, &dl_inst->data, dl_inst->module, conf) < 0) { + cf_log_perr(conf, "Failed allocating instance data for '%s_%s'", parent->module->common->name, name); return -1; } - submodule->conf = conf; + dl_inst->conf = conf; + dl_inst->parent = parent; + + rbtree_insert(dl->inst_tree, dl_inst); /* Duplicates not possible */ - *out = submodule; + *out = dl_inst; return 0; } @@ -826,9 +863,9 @@ static int dl_init(void) return -1; } - dl->sym_tree = rbtree_create(dl, dl_symbol_cmp, NULL, 0); - if (!dl->sym_tree) { - ERROR("Failed initialising dl->sym_tree"); + dl->inst_tree = rbtree_create(dl, dl_inst_cmp, NULL, 0); + if (!dl->inst_tree) { + ERROR("Failed initialising dl->inst_tree"); return -1; } diff --git a/src/main/modules.c b/src/main/modules.c index 3cd4da79873..db5b527bfa7 100644 --- a/src/main/modules.c +++ b/src/main/modules.c @@ -145,7 +145,7 @@ int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char c CONF_DATA const *cd; - module_instance_t *inst; + module_instance_t *mod_inst; char const *inst_name; #define FIND_SIBLING_CF_KEY "find_sibling" @@ -181,14 +181,14 @@ int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char c * instantiation order issues. */ inst_name = cf_pair_value(cp); - inst = module_find(cf_item_to_section(cf_parent(module)), inst_name); - if (!inst) { + mod_inst = module_find(cf_item_to_section(cf_parent(module)), inst_name); + if (!mod_inst) { cf_log_err(cp, "Unknown module instance \"%s\"", inst_name); return -1; } - if (!inst->instantiated) { + if (!mod_inst->instantiated) { CONF_SECTION *parent = module; /* @@ -215,14 +215,14 @@ int module_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, char c /* * Check the module instances are of the same type. */ - if (strcmp(cf_section_name1(inst->cs), cf_section_name1(module)) != 0) { + if (strcmp(cf_section_name1(mod_inst->dl_inst->conf), cf_section_name1(module)) != 0) { cf_log_err(cp, "Referenced module is a rlm_%s instance, must be a rlm_%s instance", - cf_section_name1(inst->cs), cf_section_name1(module)); + cf_section_name1(mod_inst->dl_inst->conf), cf_section_name1(module)); return -1; } - *out = cf_section_find(inst->cs, name, NULL); + *out = cf_section_find(mod_inst->dl_inst->conf, name, NULL); return 1; } @@ -384,7 +384,7 @@ int module_instance_read_only(TALLOC_CTX *ctx, char const *name) */ module_instance_t *module_find(CONF_SECTION *modules, char const *asked_name) { - char const *instance_name; + char const *inst_name; void *inst; if (!modules) return NULL; @@ -394,10 +394,10 @@ module_instance_t *module_find(CONF_SECTION *modules, char const *asked_name) * which tells the server "it's OK for this module to not * exist." */ - instance_name = asked_name; - if (instance_name[0] == '-') instance_name++; + inst_name = asked_name; + if (inst_name[0] == '-') inst_name++; - inst = cf_data_value(cf_data_find(modules, module_instance_t, instance_name)); + inst = cf_data_value(cf_data_find(modules, module_instance_t, inst_name)); if (!inst) return NULL; return talloc_get_type_abort(inst, module_instance_t); @@ -434,14 +434,14 @@ module_instance_t *module_find_with_method(rlm_components_t *method, CONF_SECTIO { char *p; rlm_components_t i; - module_instance_t *inst; + module_instance_t *mod_inst; /* * Module names are allowed to contain '.' * so we search for the bare module name first. */ - inst = module_find(modules, name); - if (inst) return inst; + mod_inst = module_find(modules, name); + if (mod_inst) return mod_inst; /* * Find out if the instance name contains @@ -459,24 +459,25 @@ module_instance_t *module_find_with_method(rlm_components_t *method, CONF_SECTIO char *inst_name; inst_name = talloc_bstrndup(NULL, name, p - name); - inst = module_find(modules, inst_name); - if (!inst) return NULL; + mod_inst = module_find(modules, inst_name); + if (!mod_inst) return NULL; /* * Verify the module actually implements * the specified method. */ - if (!inst->module->methods[i]) { - cf_log_debug(modules, "%s does not implement method \"%s\"", inst->name, p + 1); + if (!mod_inst->module->methods[i]) { + cf_log_debug(modules, "%s does not implement method \"%s\"", + mod_inst->module->name, p + 1); return NULL; } if (method) *method = i; - return inst; + return mod_inst; } } - return inst; + return mod_inst; } /** Retrieve module/thread specific instance data for a module @@ -488,12 +489,12 @@ module_instance_t *module_find_with_method(rlm_components_t *method, CONF_SECTIO */ void *module_thread_instance_find(void *instance) { - module_instance_t *inst = instance; + module_instance_t *mod_inst = talloc_get_type_abort(instance, module_instance_t); rbtree_t *tree = module_thread_inst_tree; module_thread_instance_t find; memset(&find, 0, sizeof(find)); - find.inst = inst; + find.inst = mod_inst; return rbtree_finddata(tree, &find); } @@ -560,33 +561,35 @@ typedef struct { */ static int _module_thread_instantiate(void *instance, void *ctx) { - module_instance_t *inst = talloc_get_type_abort(instance, module_instance_t); + module_instance_t *mod_inst = talloc_get_type_abort(instance, module_instance_t); module_thread_instance_t *thread_inst; _thread_intantiate_ctx_t *thread_inst_ctx = ctx; int ret; MEM(thread_inst = talloc_zero(NULL, module_thread_instance_t)); - thread_inst->inst = inst; + thread_inst->inst = mod_inst; - if (inst->module->thread_inst_size) { + if (mod_inst->module->thread_inst_size) { char *type_name; - MEM(thread_inst->data = talloc_zero_array(thread_inst, uint8_t, inst->module->thread_inst_size)); + MEM(thread_inst->data = talloc_zero_array(thread_inst, uint8_t, mod_inst->module->thread_inst_size)); /* * Fixup the type name, incase something calls * talloc_get_type_abort() on it... */ - MEM(type_name = talloc_asprintf(NULL, "rlm_%s_thread_t", inst->name)); + MEM(type_name = talloc_asprintf(NULL, "rlm_%s_thread_t", mod_inst->module->name)); talloc_set_name(thread_inst->data, "%s", type_name); talloc_free(type_name); } - if (inst->module->thread_instantiate) { - ret = inst->module->thread_instantiate(inst->cs, inst->data, thread_inst_ctx->el, thread_inst->data); + if (mod_inst->module->thread_instantiate) { + ret = mod_inst->module->thread_instantiate(mod_inst->dl_inst->conf, mod_inst->dl_inst->data, + thread_inst_ctx->el, thread_inst->data); if (ret < 0) { - ERROR("Thread instantiation failed for module \"%s\"", inst->name); + ERROR("Thread instantiation failed for module \"%s\"", + mod_inst->name); return -1; } } @@ -645,27 +648,29 @@ int modules_thread_instantiate(CONF_SECTION *root, fr_event_list_t *el) */ static int _module_instantiate(void *instance, UNUSED void *ctx) { - module_instance_t *inst = talloc_get_type_abort(instance, module_instance_t); + module_instance_t *mod_inst = talloc_get_type_abort(instance, module_instance_t); - if (inst->instantiated) return 0; + if (mod_inst->instantiated) return 0; /* * Now that ALL modules are instantiated, and ALL xlats * are defined, go compile the config items marked as XLAT. */ - if (inst->module->config && (cf_section_parse_pass2(inst->data, inst->cs) < 0)) return -1; + if (mod_inst->module->config && (cf_section_parse_pass2(mod_inst->dl_inst->data, + mod_inst->dl_inst->conf) < 0)) return -1; /* * Call the instantiate method, if any. */ - if (inst->module->instantiate) { - cf_log_debug(inst->cs, "Instantiating module \"%s\"", inst->name); + if (mod_inst->module->instantiate) { + cf_log_debug(mod_inst->dl_inst->conf, "Instantiating module \"%s\"", mod_inst->name); /* * Call the module's instantiation routine. */ - if ((inst->module->instantiate)(inst->cs, inst->data) < 0) { - cf_log_err(inst->cs, "Instantiation failed for module \"%s\"", inst->name); + if ((mod_inst->module->instantiate)(mod_inst->dl_inst->conf, mod_inst->dl_inst->data) < 0) { + cf_log_err(mod_inst->dl_inst->conf, "Instantiation failed for module \"%s\"", + mod_inst->name); return -1; } @@ -676,20 +681,20 @@ static int _module_instantiate(void *instance, UNUSED void *ctx) * * If it isn't, we create a mutex. */ - if ((inst->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) { - inst->mutex = talloc_zero(inst, pthread_mutex_t); + if ((mod_inst->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) { + mod_inst->mutex = talloc_zero(mod_inst, pthread_mutex_t); /* * Initialize the mutex. */ - pthread_mutex_init(inst->mutex, NULL); + pthread_mutex_init(mod_inst->mutex, NULL); } #ifndef NDEBUG - if (inst->data) module_instance_read_only(inst->data, inst->name); + if (mod_inst->dl_inst->data) module_instance_read_only(mod_inst->dl_inst->data, mod_inst->name); #endif - inst->instantiated = true; + mod_inst->instantiated = true; return 0; } @@ -712,16 +717,16 @@ static int _module_instantiate(void *instance, UNUSED void *ctx) */ static int module_instantiate(CONF_SECTION *root, char const *name) { - module_instance_t *inst; + module_instance_t *mod_inst; CONF_SECTION *modules; modules = cf_section_find(root, "modules", NULL); if (!modules) return 0; - inst = cf_data_value(cf_data_find(modules, module_instance_t, name)); - if (!inst) return -1; + mod_inst = cf_data_value(cf_data_find(modules, module_instance_t, name)); + if (!mod_inst) return -1; - return _module_instantiate(inst, NULL); + return _module_instantiate(mod_inst, NULL); } /** Completes instantiation of modules @@ -762,31 +767,31 @@ int modules_instantiate(CONF_SECTION *root) /** Free module's instance data, and any xlats or paircompares * - * @param[in] instance to free. + * @param[in] mod_inst to free. * @return 0 */ -static int _module_instance_free(module_instance_t *instance) +static int _module_instance_free(module_instance_t *mod_inst) { - if (instance->mutex) { + if (mod_inst->mutex) { /* * FIXME * The mutex MIGHT be locked... * we'll check for that later, I guess. */ - pthread_mutex_destroy(instance->mutex); + pthread_mutex_destroy(mod_inst->mutex); } - xlat_unregister(instance->data, instance->name, NULL); + xlat_unregister(mod_inst->dl_inst->data, mod_inst->name, NULL); /* * Remove all xlat's registered to module instance. */ - if (instance->data) { + if (mod_inst->dl_inst->data) { /* * Remove any registered paircompares. */ - paircompare_unregister_instance(instance->data); - xlat_unregister_module(instance->data); + paircompare_unregister_instance(mod_inst->dl_inst->data); + xlat_unregister_module(mod_inst->dl_inst->data); } /* @@ -797,13 +802,7 @@ static int _module_instance_free(module_instance_t *instance) * If we don't do this, we get a SEGV deep inside the talloc code * when it tries to call a destructor that no longer exists. */ - talloc_free_children(instance); - - /* - * Decrements the reference count. The module object won't be unloaded - * until all instances of that module have been destroyed. - */ - talloc_decrease_ref_count(instance->handle); + talloc_free_children(mod_inst); return 0; } @@ -826,22 +825,21 @@ static int _module_instance_free(module_instance_t *instance) static module_instance_t *module_bootstrap(CONF_SECTION *modules, CONF_SECTION *cs) { int i; - char const *name1, *instance_name; - module_instance_t *instance; - dl_t const *module; + char const *name1, *inst_name; + module_instance_t *mod_inst; /* * Figure out which module we want to load. */ name1 = cf_section_name1(cs); - instance_name = cf_section_name2(cs); - if (!instance_name) instance_name = name1; + inst_name = cf_section_name2(cs); + if (!inst_name) inst_name = name1; /* * Don't allow modules to use reserved words. */ for (i = 1; unlang_ops[i].name != NULL; i++) { - if (strcmp(instance_name, unlang_ops[i].name) == 0) { + if (strcmp(inst_name, unlang_ops[i].name) == 0) { ERROR("Module names cannot use a reserved word \"%s\"", unlang_ops[i].name); return NULL; @@ -851,63 +849,48 @@ static module_instance_t *module_bootstrap(CONF_SECTION *modules, CONF_SECTION * /* * See if the module already exists. */ - instance = module_find(modules, instance_name); - if (instance) { + mod_inst = module_find(modules, inst_name); + if (mod_inst) { ERROR("Duplicate module \"%s\", in file %s:%d and file %s:%d", - instance_name, + inst_name, cf_filename(cs), cf_lineno(cs), - cf_filename(instance->cs), - cf_lineno(instance->cs)); + cf_filename(mod_inst->dl_inst->conf), + cf_lineno(mod_inst->dl_inst->conf)); return NULL; } - /* - * Load the module shared library. - */ - module = dl_module(cs, NULL, name1, DL_TYPE_MODULE); - if (!module) { - talloc_free(instance); - return NULL; - } - - instance = talloc_zero(instance_ctx, module_instance_t); - instance->cs = cs; - instance->name = instance_name; - instance->handle = module; - - talloc_set_destructor(instance, _module_instance_free); + MEM(mod_inst = talloc_zero(instance_ctx, module_instance_t)); + talloc_set_destructor(mod_inst, _module_instance_free); - instance->module = (rad_module_t const *)module->common; - if (!instance->module) { - talloc_free(instance); + if (dl_instance(mod_inst, &mod_inst->dl_inst, cs, NULL, name1, DL_TYPE_MODULE) < 0) { + talloc_free(mod_inst); return NULL; } - /* - * Parse the modules configuration. - */ - if (dl_instance_data_alloc(instance, &instance->data, instance->handle, cs) < 0) { - talloc_free(instance); + mod_inst->module = (rad_module_t const *)mod_inst->dl_inst->module->common; + if (!mod_inst->module) { + cf_log_err(cs, "Missing module public structure for \"%s\"", mod_inst->module->name); + talloc_free(mod_inst); return NULL; } /* * Bootstrap the module. */ - if (instance->module->bootstrap && - ((instance->module->bootstrap)(cs, instance->data) < 0)) { - cf_log_err(cs, "Instantiation failed for module \"%s\"", instance->name); - talloc_free(instance); + if (mod_inst->module->bootstrap && + ((mod_inst->module->bootstrap)(cs, mod_inst->dl_inst->data) < 0)) { + cf_log_err(cs, "Instantiation failed for module \"%s\"", mod_inst->name); + talloc_free(mod_inst); return NULL; } - + mod_inst->name = talloc_strdup(mod_inst, inst_name); /* * Remember the module for later. */ - cf_data_add(modules, instance, instance->name, false); + cf_data_add(modules, mod_inst, mod_inst->name, false); - return instance; + return mod_inst; } /** Bootstrap a virtual module from an instantiate section diff --git a/src/main/pool.c b/src/main/pool.c index 8baeb619c84..01e3101d656 100644 --- a/src/main/pool.c +++ b/src/main/pool.c @@ -1317,7 +1317,7 @@ void fr_pool_free(fr_pool_t *pool) connection_close_internal(pool, NULL, this); } - fr_heap_delete(pool->heap); + talloc_free(pool->heap); fr_pool_trigger_exec(pool, NULL, "stop"); diff --git a/src/main/threads.c b/src/main/threads.c index 2cd017ee937..d2e07de8eaa 100644 --- a/src/main/threads.c +++ b/src/main/threads.c @@ -615,7 +615,7 @@ done: FR_TLS_REMOVE_THREAD_STATE(); #endif - fr_heap_delete(local_backlog); + talloc_free(local_backlog); trigger_exec(NULL, NULL, "server.thread.stop", true, NULL); thread->status = THREAD_EXITED; diff --git a/src/main/unit_test_module.c b/src/main/unit_test_module.c index afd2995add2..3af5654fc26 100644 --- a/src/main/unit_test_module.c +++ b/src/main/unit_test_module.c @@ -441,13 +441,13 @@ static void print_packet(FILE *fp, RADIUS_PACKET *packet) * %{poke:sql.foo=bar} */ static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen, - UNUSED void const *mod_inst, UNUSED void const *xlat_inst, + UNUSED void const *inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt) { int i; void *data, *base; char *p, *q; - module_instance_t *instance; + module_instance_t *mod_inst; char *buffer; CONF_SECTION *modules; CONF_PAIR *cp; @@ -471,8 +471,8 @@ static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen, *(p++) = '\0'; - instance = module_find(modules, buffer); - if (!instance) { + mod_inst = module_find(modules, buffer); + if (!mod_inst) { RDEBUG("Failed finding module '%s'", buffer); fail: talloc_free(buffer); @@ -492,7 +492,7 @@ static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen, goto fail; } - cp = cf_pair_find(instance->cs, p); + cp = cf_pair_find(mod_inst->dl_inst->conf, p); if (!cp) { RDEBUG("No such item '%s'", p); goto fail; @@ -504,13 +504,13 @@ static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen, */ len = strlcpy(*out, cf_pair_value(cp), outlen); - if (cf_pair_replace(instance->cs, cp, q) < 0) { + if (cf_pair_replace(mod_inst->dl_inst->conf, cp, q) < 0) { RDEBUG("Failed replacing pair"); goto fail; } - base = instance->data; - variables = instance->module->config; + base = mod_inst->dl_inst->data; + variables = mod_inst->dl_inst->module->common->config; /* * Handle the known configuration parameters. @@ -539,7 +539,7 @@ static ssize_t xlat_poke(TALLOC_CTX *ctx, char **out, size_t outlen, /* * Parse the pair we found, or a default value. */ - ret = cf_pair_parse(ctx, instance->cs, variables[i].name, variables[i].type, + ret = cf_pair_parse(ctx, mod_inst->dl_inst->conf, variables[i].name, variables[i].type, data, variables[i].dflt, variables[i].quote); if (ret < 0) { DEBUG2("Failed inserting new value into module instance data"); diff --git a/src/main/unlang_interpret.c b/src/main/unlang_interpret.c index aeb392cf102..677d1f3a3d0 100644 --- a/src/main/unlang_interpret.c +++ b/src/main/unlang_interpret.c @@ -842,7 +842,7 @@ static unlang_action_t unlang_module_call(REQUEST *request, unlang_stack_t *stac * Lock is noop unless instance->mutex is set. */ safe_lock(sp->module_instance); - *presult = request->rcode = sp->method(sp->module_instance->data, modcall_state->thread->data, request); + *presult = request->rcode = sp->method(sp->module_instance->dl_inst->data, modcall_state->thread->data, request); safe_unlock(sp->module_instance); request->module = NULL; @@ -996,7 +996,7 @@ static unlang_action_t unlang_module_resumption(REQUEST *request, unlang_stack_t * Lock is noop unless instance->mutex is set. */ safe_lock(sp->module_instance); - *presult = request->rcode = mr->callback(request, mr->module.module_instance->data, mr->thread->data, mutable); + *presult = request->rcode = mr->callback(request, mr->module.module_instance->dl_inst->data, mr->thread->data, mutable); safe_unlock(sp->module_instance); request->module = NULL; @@ -1674,7 +1674,7 @@ int unlang_event_timeout_add(REQUEST *request, fr_unlang_timeout_callback_t call ev->request = request; ev->fd = -1; ev->timeout = callback; - ev->inst = sp->module_instance->data; + ev->inst = sp->module_instance->dl_inst->data; ev->thread = modcall_state->thread; ev->ctx = ctx; @@ -1758,7 +1758,7 @@ int unlang_event_fd_add(REQUEST *request, ev->fd_read = read; ev->fd_write = write; ev->fd_error = error; - ev->inst = sp->module_instance->data; + ev->inst = sp->module_instance->dl_inst->data; ev->thread = modcall_state->thread; ev->ctx = ctx; @@ -1883,7 +1883,7 @@ void unlang_signal(REQUEST *request, fr_state_action_t action) memcpy(&mutable, &mr->ctx, sizeof(mutable)); - mr->signal_callback(request, mr->module.module_instance->data, mr->thread, mutable, action); + mr->signal_callback(request, mr->module.module_instance->dl_inst->data, mr->thread, mutable, action); } /** Yield a request back to the interpreter from within a module diff --git a/src/main/virtual_servers.c b/src/main/virtual_servers.c index 8176467923e..71d4be729fd 100644 --- a/src/main/virtual_servers.c +++ b/src/main/virtual_servers.c @@ -52,7 +52,7 @@ static int default_component_results[MOD_COUNT] = { }; typedef struct { - dl_submodule_t *proto_module; //!< The proto_* module for a listen section. + dl_instance_t *proto_module; //!< The proto_* module for a listen section. fr_app_t const *app; //!< Easy access to the exported struct. } fr_virtual_listen_t; @@ -95,13 +95,12 @@ const CONF_PARSER virtual_servers_config[] = { * - 0 on success. * - -1 on failure. */ -static int listen_parse(UNUSED TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule) +static int listen_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule) { fr_virtual_listen_t *listen = out; /* Pre-allocated for us */ CONF_SECTION *listen_cs = cf_item_to_section(ci); CONF_SECTION *server = cf_item_to_section(cf_parent(ci)); CONF_PAIR *namespace; - dl_t const *module; namespace = cf_pair_find(server, "namespace"); if (!namespace) { @@ -115,22 +114,11 @@ static int listen_parse(UNUSED TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED if (DEBUG_ENABLED4) cf_log_debug(ci, "Loading %s listener into %p", cf_pair_value(namespace), out); - module = dl_module(listen_cs, NULL, cf_pair_value(namespace), DL_TYPE_PROTO); - if (!module) { - cf_log_perr(listen_cs, "Failed loading proto module"); + if (dl_instance(ctx, &listen->proto_module, listen_cs, NULL, cf_pair_value(namespace), DL_TYPE_PROTO) < 0) { + cf_log_err(listen_cs, "Failed loading proto module"); return -1; } - - MEM(listen->proto_module = talloc_zero(listen, dl_submodule_t)); - - if (dl_instance_data_alloc(listen, &listen->proto_module->inst, module, listen_cs) < 0) { - cf_log_perr(listen_cs, "Failed parsing config"); - talloc_free(listen); - return -1; - } - - listen->proto_module->module = module; - listen->proto_module->conf = listen_cs; + cf_data_add(listen_cs, listen->proto_module, "proto", false); /* * Hack for now: tell the server core we have new listeners. @@ -620,7 +608,7 @@ int virtual_servers_open(fr_schedule_t *sc) if (!listen || !listen->proto_module) continue; /* Skip old style */ if (listen->app->open && - listen->app->open(listen->proto_module->inst, sc, listen->proto_module->conf) < 0) { + listen->app->open(listen->proto_module->data, sc, listen->proto_module->conf) < 0) { cf_log_err(listen->proto_module->conf, "Opening I/O interface failed"); return -1; } @@ -672,7 +660,7 @@ int virtual_servers_instantiate(CONF_SECTION *config) if (!listen || !listen->proto_module) continue; /* Skip old style */ if (listen->app->instantiate && - listen->app->instantiate(listen->proto_module->inst, listen->proto_module->conf) < 0) { + listen->app->instantiate(listen->proto_module->data, listen->proto_module->conf) < 0) { cf_log_err(listen->proto_module->conf, "Instantiate failed"); return -1; } @@ -756,11 +744,11 @@ int virtual_servers_bootstrap(CONF_SECTION *config) if (!listener[j] || !listener[j]->proto_module) continue; /* Skip old style */ listen = talloc_get_type_abort(listener[j], fr_virtual_listen_t); - talloc_get_type_abort(listen->proto_module, dl_submodule_t); + talloc_get_type_abort(listen->proto_module, dl_instance_t); listen->app = (fr_app_t const *)listen->proto_module->module->common; if (listen->app->bootstrap && - listen->app->bootstrap(listen->proto_module->inst, listen->proto_module->conf) < 0) { + listen->app->bootstrap(listen->proto_module->data, listen->proto_module->conf) < 0) { cf_log_err(listen->proto_module->conf, "Bootstrap failed"); return -1; } diff --git a/src/modules/proto_radius/proto_radius.c b/src/modules/proto_radius/proto_radius.c index b6f4826c7e3..7ed02635e1b 100644 --- a/src/modules/proto_radius/proto_radius.c +++ b/src/modules/proto_radius/proto_radius.c @@ -36,7 +36,7 @@ typedef struct { CONF_SECTION *server_cs; //!< server CS for this listener - dl_submodule_t *io_submodule; //!< As provided by the transport_parse callback. + dl_instance_t *io_submodule; //!< As provided by the transport_parse callback. ///< Broken out into the app_io_* fields below for //!< convenience. @@ -45,10 +45,12 @@ typedef struct { CONF_SECTION *app_io_conf; //!< Easy access to the app_io's config section. - dl_submodule_t **process_submodule; //!< Instance of the various types + dl_instance_t **process_submodule; //!< Instance of the various types //!< only one instance per type allowed. fr_io_process_t process_by_code[FR_CODE_MAX]; //!< Lookup process entry point by code. + bool code_allowed[FR_CODE_MAX]; //!< Lookup allowed packet codes. + fr_listen_t const *listen; //!< The listener structure which describes //!< the I/O path. } proto_radius_t; @@ -69,10 +71,10 @@ static CONF_PARSER const proto_radius_config[] = { CONF_PARSER_TERMINATOR }; -/** Wrapper around dl_submodule which translates the packet-type into a submodule name +/** Wrapper around dl_instance which translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_radius). - * @param[out] out Where to write a dl_submodule_t containing the module handle and instance. + * @param[out] out Where to write a dl_instance_t containing the module handle and instance. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. * @return @@ -124,13 +126,18 @@ static int process_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_ return -1; } - return dl_submodule(ctx, out, listen_cs, dl_by_symbol(&proto_radius), name); + /* + * Parent dl_instance_t added in virtual_servers.c (listen_parse) + */ + return dl_instance(ctx, out, listen_cs, + cf_data_value(cf_data_find(listen_cs, dl_instance_t, "proto")), + name, DL_TYPE_SUBMODULE); } -/** Wrapper around dl_submodule +/** Wrapper around dl_instance * * @param[in] ctx to allocate data in (instance of proto_radius). - * @param[out] out Where to write a dl_submodule_t containing the module handle and instance. + * @param[out] out Where to write a dl_instance_t containing the module handle and instance. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. * @return @@ -140,18 +147,20 @@ static int process_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_ static int transport_parse(TALLOC_CTX *ctx, void *out, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule) { char const *name = cf_pair_value(cf_item_to_pair(ci)); - CONF_SECTION *parent_cs = cf_item_to_section(cf_parent(ci)); + CONF_SECTION *listen_cs = cf_item_to_section(cf_parent(ci)); CONF_SECTION *transport_cs; - transport_cs = cf_section_find(parent_cs, name, NULL); + transport_cs = cf_section_find(listen_cs, name, NULL); /* * Allocate an empty section if one doesn't exist * this is so defaults get parsed. */ - if (!transport_cs) transport_cs = cf_section_alloc(parent_cs, name, NULL); + if (!transport_cs) transport_cs = cf_section_alloc(listen_cs, name, NULL); - return dl_submodule(ctx, out, transport_cs, dl_by_symbol(&proto_radius), name); + return dl_instance(ctx, out, transport_cs, + cf_data_value(cf_data_find(listen_cs, dl_instance_t, "proto")), + name, DL_TYPE_SUBMODULE); } /** Decode the packet, and set the request->process function @@ -339,7 +348,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) int code; app_process = (fr_app_process_t const *)inst->process_submodule[i]->module->common; - if (app_process->instantiate && (app_process->instantiate(inst->process_submodule[i]->inst, + if (app_process->instantiate && (app_process->instantiate(inst->process_submodule[i]->data, inst->process_submodule[i]->conf) < 0)) { cf_log_err(conf, "Instantiation failed for \"%s\"", app_process->name); return -1; @@ -350,6 +359,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) */ code = fr_dict_enum_by_alias(NULL, da, cf_pair_value(cp))->value->vb_uint32; inst->process_by_code[code] = app_process->process; /* Store the process function */ + inst->code_allowed[code] = true; i++; } @@ -377,7 +387,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) * Bootstrap the I/O module */ inst->app_io = (fr_app_io_t const *) inst->io_submodule->module->common; - inst->app_io_instance = inst->io_submodule->inst; + inst->app_io_instance = inst->io_submodule->data; inst->app_io_conf = inst->io_submodule->conf; if (inst->app_io->bootstrap && (inst->app_io->bootstrap(inst->app_io_instance, inst->app_io_conf) < 0)) { @@ -392,7 +402,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) dl_t const *module = talloc_get_type_abort(inst->process_submodule[i]->module, dl_t); fr_app_process_t const *app_process = (fr_app_process_t const *)module->common; - if (app_process->bootstrap && (app_process->bootstrap(inst->process_submodule[i]->inst, + if (app_process->bootstrap && (app_process->bootstrap(inst->process_submodule[i]->data, inst->process_submodule[i]->conf) < 0)) { cf_log_err(conf, "Bootstrap failed for \"%s\"", app_process->name); return -1; diff --git a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c index 2de9e0c3b3c..36a53f30c50 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c @@ -88,9 +88,9 @@ static int _cache_entry_free(UNUSED void *ctx, void *data) */ static int mod_detach(void *instance) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); - if (driver->heap) fr_heap_delete(driver->heap); + if (driver->heap) talloc_free(driver->heap); if (driver->cache) { rbtree_walk(driver->cache, RBTREE_DELETE_ORDER, _cache_entry_free, NULL); talloc_free(driver->cache); @@ -107,7 +107,7 @@ static int mod_detach(void *instance) */ static int mod_instantiate(UNUSED rlm_cache_config_t const *config, void *instance, UNUSED CONF_SECTION *conf) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); /* * The cache. @@ -166,7 +166,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, UNUSED rlm_cache_config_t const *config, void *instance, REQUEST *request, UNUSED void *handle, uint8_t const *key, size_t key_len) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); rlm_cache_entry_t *c, my_c; @@ -207,7 +207,7 @@ static cache_status_t cache_entry_expire(UNUSED rlm_cache_config_t const *config REQUEST *request, UNUSED void *handle, uint8_t const *key, size_t key_len) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); rlm_cache_entry_t *c, my_c; if (!request) return CACHE_ERROR; @@ -236,7 +236,7 @@ static cache_status_t cache_entry_insert(rlm_cache_config_t const *config, void { cache_status_t status; - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); rlm_cache_entry_t *my_c; rad_assert(handle == request); @@ -279,7 +279,7 @@ static cache_status_t cache_entry_set_ttl(UNUSED rlm_cache_config_t const *confi REQUEST *request, UNUSED void *handle, rlm_cache_entry_t *c) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); int ret; #ifdef NDEBUG @@ -310,7 +310,7 @@ static cache_status_t cache_entry_set_ttl(UNUSED rlm_cache_config_t const *confi static uint32_t cache_entry_count(UNUSED rlm_cache_config_t const *config, void *instance, REQUEST *request, UNUSED void *handle) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); if (!request) return CACHE_ERROR; @@ -326,7 +326,7 @@ static uint32_t cache_entry_count(UNUSED rlm_cache_config_t const *config, void static int cache_acquire(void **handle, UNUSED rlm_cache_config_t const *config, void *instance, REQUEST *request) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); pthread_mutex_lock(&driver->mutex); @@ -346,7 +346,7 @@ static int cache_acquire(void **handle, UNUSED rlm_cache_config_t const *config, static void cache_release(UNUSED rlm_cache_config_t const *config, void *instance, REQUEST *request, UNUSED rlm_cache_handle_t *handle) { - rlm_cache_rbtree_t *driver = instance; + rlm_cache_rbtree_t *driver = talloc_get_type_abort(instance, rlm_cache_rbtree_t); pthread_mutex_unlock(&driver->mutex); diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index e048afb36c2..442705aebcd 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -58,7 +58,7 @@ static int cache_acquire(rlm_cache_handle_t **out, rlm_cache_t const *inst, REQU return 0; } - return inst->driver->acquire(out, &inst->config, inst->driver_inst, request); + return inst->driver->acquire(out, &inst->config, inst->driver_inst->data, request); } /** Release a handle we previously acquired @@ -69,7 +69,7 @@ static void cache_release(rlm_cache_t const *inst, REQUEST *request, rlm_cache_h if (!inst->driver->release) return; if (!handle || !*handle) return; - inst->driver->release(&inst->config, inst->driver_inst, request, *handle); + inst->driver->release(&inst->config, inst->driver_inst->data, request, *handle); *handle = NULL; } @@ -80,7 +80,7 @@ static int cache_reconnect(rlm_cache_handle_t **handle, rlm_cache_t const *inst, { rad_assert(inst->driver->reconnect); - return inst->driver->reconnect(handle, &inst->config, inst->driver_inst, request); + return inst->driver->reconnect(handle, &inst->config, inst->driver_inst->data, request); } /** Allocate a cache entry @@ -93,7 +93,7 @@ static int cache_reconnect(rlm_cache_handle_t **handle, rlm_cache_t const *inst, */ static rlm_cache_entry_t *cache_alloc(rlm_cache_t const *inst, REQUEST *request) { - if (inst->driver->alloc) return inst->driver->alloc(&inst->config, inst->driver_inst, request); + if (inst->driver->alloc) return inst->driver->alloc(&inst->config, inst->driver_inst->data, request); return talloc_zero(NULL, rlm_cache_entry_t); } @@ -188,7 +188,7 @@ static rlm_rcode_t cache_find(rlm_cache_entry_t **out, rlm_cache_t const *inst, *out = NULL; for (;;) { - ret = inst->driver->find(&c, &inst->config, inst->driver_inst, request, *handle, key, key_len); + ret = inst->driver->find(&c, &inst->config, inst->driver_inst->data, request, *handle, key, key_len); switch (ret) { case CACHE_RECONNECT: RDEBUG("Reconnecting..."); @@ -231,7 +231,7 @@ static rlm_rcode_t cache_find(rlm_cache_entry_t **out, rlm_cache_t const *inst, talloc_free(p); } - inst->driver->expire(&inst->config, inst->driver_inst, request, handle, c->key, c->key_len); + inst->driver->expire(&inst->config, inst->driver_inst->data, request, handle, c->key, c->key_len); cache_free(inst, &c); return RLM_MODULE_NOTFOUND; /* Couldn't find a non-expired entry */ } @@ -261,7 +261,7 @@ static rlm_rcode_t cache_expire(rlm_cache_t const *inst, REQUEST *request, rlm_cache_handle_t **handle, uint8_t const *key, size_t key_len) { RDEBUG("Expiring cache entry"); - for (;;) switch (inst->driver->expire(&inst->config, inst->driver_inst, request, + for (;;) switch (inst->driver->expire(&inst->config, inst->driver_inst->data, request, *handle, key, key_len)) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -299,7 +299,7 @@ static rlm_rcode_t cache_insert(rlm_cache_t const *inst, REQUEST *request, rlm_c TALLOC_CTX *pool; if ((inst->config.max_entries > 0) && inst->driver->count && - (inst->driver->count(&inst->config, inst->driver_inst, request, handle) > inst->config.max_entries)) { + (inst->driver->count(&inst->config, inst->driver_inst->data, request, handle) > inst->config.max_entries)) { RWDEBUG("Cache is full: %d entries", inst->config.max_entries); return RLM_MODULE_FAIL; } @@ -441,7 +441,7 @@ static rlm_rcode_t cache_insert(rlm_cache_t const *inst, REQUEST *request, rlm_c for (;;) { cache_status_t ret; - ret = inst->driver->insert(&inst->config, inst->driver_inst, request, *handle, c); + ret = inst->driver->insert(&inst->config, inst->driver_inst->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -475,7 +475,7 @@ static rlm_rcode_t cache_set_ttl(rlm_cache_t const *inst, REQUEST *request, if (!inst->driver->set_ttl) for (;;) { cache_status_t ret; - ret = inst->driver->insert(&inst->config, inst->driver_inst, request, *handle, c); + ret = inst->driver->insert(&inst->config, inst->driver_inst->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -497,7 +497,7 @@ static rlm_rcode_t cache_set_ttl(rlm_cache_t const *inst, REQUEST *request, for (;;) { cache_status_t ret; - ret = inst->driver->set_ttl(&inst->config, inst->driver_inst, request, *handle, c); + ret = inst->driver->set_ttl(&inst->config, inst->driver_inst->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -874,12 +874,6 @@ static int mod_detach(void *instance) */ talloc_free_children(inst); - /* - * Decrements the reference count. The driver object won't be unloaded - * until all instances of rlm_cache that use it have been destroyed. - */ - talloc_decrease_ref_count(inst->driver_handle); - return 0; } @@ -941,10 +935,11 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) /* * Load the appropriate driver for our backend */ - inst->driver_handle = dl_module(driver_cs, dl_by_symbol(&rlm_cache), name, DL_TYPE_SUBMODULE); - if (!inst->driver_handle) return -1; - - inst->driver = (cache_driver_t const *)inst->driver_handle->common; + if (dl_instance(inst, &inst->driver_inst, driver_cs, dl_instance_find(inst), name, DL_TYPE_SUBMODULE) < 0) { + cf_log_err(driver_cs, "Failed loading driver"); + return -1; + } + inst->driver = (cache_driver_t const *)inst->driver_inst->module->common; /* * Non optional fields and callbacks @@ -954,13 +949,11 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) rad_assert(inst->driver->insert); rad_assert(inst->driver->expire); - if (dl_instance_data_alloc(inst, &inst->driver_inst, inst->driver_handle, driver_cs) < 0) return -1; - if (inst->driver->instantiate && - (inst->driver->instantiate(&inst->config, inst->driver_inst, driver_cs) < 0)) return -1; + (inst->driver->instantiate(&inst->config, inst->driver_inst->data, driver_cs) < 0)) return -1; #ifndef NDEBUG - if (inst->driver_inst) module_instance_read_only(inst->driver_inst, inst->driver->name); + if (inst->driver_inst) module_instance_read_only(inst->driver_inst->data, inst->driver->name); #endif if (inst->config.ttl == 0) { diff --git a/src/modules/rlm_cache/rlm_cache.h b/src/modules/rlm_cache/rlm_cache.h index 8e4591a16d9..7aa039be42c 100644 --- a/src/modules/rlm_cache/rlm_cache.h +++ b/src/modules/rlm_cache/rlm_cache.h @@ -65,8 +65,7 @@ typedef struct rlm_cache_config_t { typedef struct rlm_cache_t { rlm_cache_config_t config; //!< Must come first because of icky hacks. - dl_t const *driver_handle; //!< Driver's dl_handle. - void *driver_inst; //!< Driver's instance data. + dl_instance_t *driver_inst; //!< Driver's instance data. cache_driver_t const *driver; //!< Driver's exported interface. vp_map_t *maps; //!< Attribute map applied to users. diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index 0d4243c101c..2c8491e0e09 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -64,13 +64,6 @@ static int _eap_method_free(rlm_eap_method_t *method) */ talloc_free_children(method); - /* - * Decrements the reference count. The submodule won't be - * unloaded until all instances of rlm_eap that use it have been - * destroyed. - */ - talloc_decrease_ref_count(method->submodule_handle); - return 0; } @@ -92,35 +85,27 @@ int eap_method_instantiate(rlm_eap_method_t **out, rlm_eap_t *inst, eap_type_t n */ MEM(method = talloc_zero(inst, rlm_eap_method_t)); talloc_set_destructor(method, _eap_method_free); - method->cs = cs; /* * Load the submodule for the specified EAP method */ - method->submodule_handle = dl_module(cs, dl_by_symbol(&rlm_eap), eap_type2name(num), DL_TYPE_SUBMODULE); - if (!method->submodule_handle) return -1; - method->submodule = (rlm_eap_submodule_t const *)method->submodule_handle->common; - - /* - * Allocate submodule instance data and parse the method's - * configuration. - */ - if (dl_instance_data_alloc(method, &method->submodule_inst, method->submodule_handle, cs) < 0) { - talloc_free(method); + if (dl_instance(method, &method->submodule_inst, cs, dl_instance_find(inst), + eap_type2name(num), DL_TYPE_SUBMODULE) < 0) { return -1; } + method->submodule = (rlm_eap_submodule_t const *)method->submodule_inst->module->common; /* * Call the instantiated function in the submodule */ if ((method->submodule->instantiate) && - ((method->submodule->instantiate)(&inst->config, method->submodule_inst, cs) < 0)) { + ((method->submodule->instantiate)(&inst->config, method->submodule_inst->data, cs) < 0)) { talloc_free(method); return -1; } #ifndef NDEBUG - if (method->submodule_inst) module_instance_read_only(method->submodule_inst, method->submodule->name); + if (method->submodule_inst->data) module_instance_read_only(method->submodule_inst->data, eap_type2name(num)); #endif *out = method; @@ -462,7 +447,7 @@ static rlm_rcode_t eap_method_select(rlm_eap_t *inst, eap_session_t *eap_session caller = request->module; request->module = method->submodule->name; - rcode = eap_session->process(method->submodule_inst, eap_session); + rcode = eap_session->process(method->submodule_inst->data, eap_session); request->module = caller; switch (rcode) { diff --git a/src/modules/rlm_eap/rlm_eap.h b/src/modules/rlm_eap/rlm_eap.h index afa96a4c3b1..fe4619e6c98 100644 --- a/src/modules/rlm_eap/rlm_eap.h +++ b/src/modules/rlm_eap/rlm_eap.h @@ -36,10 +36,7 @@ RCSIDH(rlm_eap_h, "$Id$") * */ typedef struct rlm_eap_method { - CONF_SECTION *cs; - - dl_t const *submodule_handle; //!< Submodule's dl_handle. - void *submodule_inst; //!< Submodule's instance data + dl_instance_t *submodule_inst; //!< Submodule's instance data rlm_eap_submodule_t const *submodule; //!< Submodule's exported interface. } rlm_eap_method_t; diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 6b5b0709af3..59e6c38b962 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -553,7 +553,7 @@ static int generate_sql_clients(rlm_sql_t *inst) static size_t sql_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, char const *in, void *arg) { rlm_sql_handle_t *handle = arg; - rlm_sql_t const *inst = handle->inst; + rlm_sql_t const *inst = talloc_get_type_abort(handle->inst, rlm_sql_t); size_t len = 0; while (in[0]) { @@ -795,7 +795,7 @@ static int sql_groupcmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *req UNUSED VALUE_PAIR **reply_pairs) { rlm_sql_handle_t *handle; - rlm_sql_t const *inst = instance; + rlm_sql_t const *inst = talloc_get_type_abort(instance, rlm_sql_t); rlm_sql_grouplist_t *head, *entry; /* @@ -1023,7 +1023,7 @@ finish: static int mod_detach(void *instance) { - rlm_sql_t *inst = instance; + rlm_sql_t *inst = talloc_get_type_abort(instance, rlm_sql_t); if (inst->pool) fr_pool_free(inst->pool); @@ -1037,18 +1037,12 @@ static int mod_detach(void *instance) */ talloc_free_children(inst); - /* - * Decrements the reference count. The driver object won't be unloaded - * until all instances of rlm_sql that use it have been destroyed. - */ - talloc_decrease_ref_count(inst->driver_handle); - return 0; } static int mod_bootstrap(CONF_SECTION *conf, void *instance) { - rlm_sql_t *inst = instance; + rlm_sql_t *inst = talloc_get_type_abort(instance, rlm_sql_t); CONF_SECTION *driver_cs; char const *name; @@ -1083,28 +1077,23 @@ static int mod_bootstrap(CONF_SECTION *conf, void *instance) /* * Load the driver */ - inst->driver_handle = dl_module(driver_cs, dl_by_symbol(&rlm_sql), name, DL_TYPE_SUBMODULE); - if (!inst->driver_handle) return -1; - inst->driver = (rlm_sql_driver_t const *)inst->driver_handle->common; - - /* - * Pre-allocate the driver's instance data, - * and parse the driver's configuration. - */ - if (dl_instance_data_alloc(inst, &inst->driver_inst, inst->driver_handle, driver_cs) < 0) { - error: - talloc_decrease_ref_count(inst->driver_handle); + if (dl_instance(inst, &inst->driver_inst, driver_cs, dl_instance_find(inst), name, DL_TYPE_SUBMODULE) < 0) { return -1; } + inst->driver = (rlm_sql_driver_t const *)inst->driver_inst->module->common; - rad_assert(!inst->driver_handle->common->inst_size || inst->driver_inst); + rad_assert(!inst->driver->inst_size || inst->driver_inst->data); /* * Call the driver's instantiate function (if set) */ if (inst->driver->mod_instantiate && (inst->driver->mod_instantiate(inst->config, - inst->driver_inst, - driver_cs)) < 0) return -1; + inst->driver_inst->data, + driver_cs)) < 0) { + error: + TALLOC_FREE(inst->driver_inst); + return -1; + } #ifndef NDEBUG if (inst->driver_inst) module_instance_read_only(inst->driver_inst, inst->driver->name); #endif @@ -1113,7 +1102,7 @@ static int mod_bootstrap(CONF_SECTION *conf, void *instance) * @fixme Inst should be passed to all driver callbacks * instead of being stored here. */ - inst->config->driver = inst->driver_inst; + inst->config->driver = inst->driver_inst->data; /* * Register the group comparison attribute @@ -1904,7 +1893,7 @@ release: static rlm_rcode_t mod_post_auth(void *instance, UNUSED void *thread, REQUEST *request) CC_HINT(nonnull); static rlm_rcode_t mod_post_auth(void *instance, UNUSED void *thread, REQUEST *request) { - rlm_sql_t const *inst = instance; + rlm_sql_t const *inst = talloc_get_type_abort(instance, rlm_sql_t); if (inst->config->postauth.reference_cp) { return acct_redundant(inst, request, &inst->config->postauth); diff --git a/src/modules/rlm_sql/rlm_sql.h b/src/modules/rlm_sql/rlm_sql.h index 5c56b681cba..ad02d8ce268 100644 --- a/src/modules/rlm_sql/rlm_sql.h +++ b/src/modules/rlm_sql/rlm_sql.h @@ -222,7 +222,7 @@ typedef struct rlm_sql_driver_t { struct sql_inst { rlm_sql_config_t myconfig; /* HACK */ - fr_pool_t *pool; + fr_pool_t *pool; rlm_sql_config_t *config; CONF_SECTION *cs; @@ -230,8 +230,7 @@ struct sql_inst { //!< dictionary attribute. exfile_t *ef; - dl_t const *driver_handle; //!< Driver's dl_handle. - void *driver_inst; //!< Driver's instance data. + dl_instance_t *driver_inst; //!< Driver's instance data. rlm_sql_driver_t const *driver; //!< Driver's exported interface. int (*sql_set_user)(rlm_sql_t const *inst, REQUEST *request, char const *username); diff --git a/src/modules/rlm_sqlhpwippool/rlm_sqlhpwippool.c b/src/modules/rlm_sqlhpwippool/rlm_sqlhpwippool.c index f4056fe0812..fbb36d60467 100644 --- a/src/modules/rlm_sqlhpwippool/rlm_sqlhpwippool.c +++ b/src/modules/rlm_sqlhpwippool/rlm_sqlhpwippool.c @@ -276,7 +276,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) } /* save pointers to useful "objects" */ - inst->sql_inst = (rlm_sql_t *) sql_inst->data; + inst->sql_inst = (rlm_sql_t *) sql_inst->dl_inst->data; inst->db = (rlm_sql_driver_t const *) inst->sql_inst->driver; /* check if the given instance is really a rlm_sql instance */ diff --git a/src/modules/rlm_sqlippool/rlm_sqlippool.c b/src/modules/rlm_sqlippool/rlm_sqlippool.c index 44848225bc9..9189a70341d 100644 --- a/src/modules/rlm_sqlippool/rlm_sqlippool.c +++ b/src/modules/rlm_sqlippool/rlm_sqlippool.c @@ -397,7 +397,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) inst->framed_ip_address = FR_FRAMED_IPV6_PREFIX; } - inst->sql_inst = (rlm_sql_t *) sql_inst->data; + inst->sql_inst = (rlm_sql_t *) sql_inst->dl_inst->data; if (strcmp(inst->sql_inst->driver->name, "sql") != 0) { cf_log_err(conf, "Module \"%s\" is not an instance of the rlm_sql module",