the main function now creates structures containing the parent instance, the instance, and the module handle.
/** 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
}
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);
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.
* @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)
*
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;
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.
fr_event_timer_delete(el, &ev);
}
- fr_heap_delete(el->times);
+ talloc_free(el->times);
close(el->kq);
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;
fr_exit(1);
}
- fr_heap_delete(hp);
+ talloc_free(hp);
return 0;
}
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;
}
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;
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;
/*
* 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;
char const *radlib_dir;
-
/** Symbol dependent initialisation callback
*
* Call this function when the module is loaded for the first time.
*/
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
*/
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;
}
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
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;
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
/*
* 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;
}
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;
}
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;
}
CONF_DATA const *cd;
- module_instance_t *inst;
+ module_instance_t *mod_inst;
char const *inst_name;
#define FIND_SIBLING_CF_KEY "find_sibling"
* 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;
/*
/*
* 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;
}
*/
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;
* 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);
{
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
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
*/
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);
}
*/
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;
}
}
*/
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;
}
*
* 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;
}
*/
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
/** 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);
}
/*
* 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;
}
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;
/*
* 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
connection_close_internal(pool, NULL, this);
}
- fr_heap_delete(pool->heap);
+ talloc_free(pool->heap);
fr_pool_trigger_exec(pool, NULL, "stop");
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;
* %{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;
*(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);
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;
*/
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.
/*
* 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");
* 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;
* 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;
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;
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;
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
};
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;
* - 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) {
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.
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;
}
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;
}
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;
}
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.
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;
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
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
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
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;
*/
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++;
}
* 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)) {
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;
*/
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);
*/
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.
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;
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;
{
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);
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
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;
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);
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);
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
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;
}
{
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
*/
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);
}
*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...");
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 */
}
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;
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;
}
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;
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;
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;
*/
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;
}
/*
* 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
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) {
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.
*/
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;
}
*/
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;
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) {
*
*/
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;
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]) {
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;
/*
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);
*/
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;
/*
* 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
* @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
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);
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;
//!< 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);
}
/* 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 */
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",