From 8da6cc26098c1f667d7a361a3851d714f380ca7d Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Thu, 9 May 2024 09:22:34 -0600 Subject: [PATCH] Merge dl_module_instance code with module_instance Collapsing a completely useless layer of abstraction and making everything significantly easier to understand and use. --- src/lib/io/master.c | 59 ++- src/lib/io/master.h | 2 +- src/lib/server/dl_module.c | 365 +----------------- src/lib/server/dl_module.h | 68 +--- src/lib/server/module.c | 334 +++++++++------- src/lib/server/module.h | 108 ++++-- src/lib/server/module_ctx.h | 32 +- src/lib/server/module_rlm.c | 42 +- src/lib/server/virtual_servers.c | 41 +- src/lib/unlang/compile.c | 16 +- src/lib/unlang/module.c | 34 +- src/lib/unlang/xlat_ctx.h | 21 +- src/lib/unlang/xlat_func.c | 2 +- src/lib/unlang/xlat_func.h | 2 +- src/listen/arp/proto_arp.c | 48 +-- src/listen/arp/proto_arp.h | 6 +- src/listen/bfd/proto_bfd.c | 8 +- src/listen/control/proto_control.c | 7 +- src/listen/cron/cron.c | 8 +- src/listen/cron/proto_cron.c | 11 +- src/listen/cron/proto_cron_crontab.c | 19 +- src/listen/detail/proto_detail.c | 59 ++- src/listen/detail/proto_detail.h | 2 +- src/listen/detail/proto_detail_file.c | 9 +- src/listen/detail/proto_detail_work.c | 12 +- src/listen/dhcpv4/proto_dhcpv4.c | 11 +- src/listen/dhcpv6/proto_dhcpv6.c | 11 +- src/listen/dns/proto_dns.c | 11 +- src/listen/ldap_sync/proto_ldap_sync.c | 10 +- src/listen/ldap_sync/proto_ldap_sync_ldap.c | 7 +- src/listen/load/proto_load.c | 11 +- src/listen/load/proto_load_step.c | 12 +- src/listen/radius/proto_radius.c | 11 +- src/listen/tacacs/proto_tacacs.c | 11 +- src/listen/vmps/proto_vmps.c | 11 +- src/modules/rlm_cache/rlm_cache.c | 26 +- src/modules/rlm_eap/rlm_eap.c | 14 +- src/modules/rlm_ldap/rlm_ldap.h | 2 +- src/modules/rlm_radius/rlm_radius.c | 4 +- src/modules/rlm_rest/io.c | 3 +- src/modules/rlm_rest/rlm_rest.c | 2 +- .../rlm_sql_cassandra/rlm_sql_cassandra.c | 4 +- .../drivers/rlm_sql_mysql/rlm_sql_mysql.c | 4 +- .../drivers/rlm_sql_oracle/rlm_sql_oracle.c | 2 +- .../rlm_sql_postgresql/rlm_sql_postgresql.c | 4 +- .../drivers/rlm_sql_sqlite/rlm_sql_sqlite.c | 2 +- src/modules/rlm_sql/rlm_sql.c | 2 +- src/modules/rlm_sqlcounter/rlm_sqlcounter.c | 2 +- src/modules/rlm_sqlippool/rlm_sqlippool.c | 4 +- src/modules/rlm_tacacs/rlm_tacacs.c | 4 +- src/protocols/ethernet/ethernet.c | 2 - 51 files changed, 585 insertions(+), 917 deletions(-) diff --git a/src/lib/io/master.c b/src/lib/io/master.c index 08e9fba44e..890cdfea70 100644 --- a/src/lib/io/master.c +++ b/src/lib/io/master.c @@ -143,7 +143,7 @@ struct fr_io_connection_s { fr_listen_t *child; //!< child listener (app_io) for this socket fr_io_client_t *client; //!< our local client (pending or connected). fr_io_client_t *parent; //!< points to the parent client. - dl_module_inst_t *dl_inst; //!< for submodule + module_instance_t *mi; //!< for submodule bool dead; //!< roundabout way to get the network side to close a socket bool paused; //!< event filter doesn't like resuming something that isn't paused @@ -478,7 +478,7 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, { int ret; fr_io_connection_t *connection; - dl_module_inst_t *dl_inst = NULL; + module_instance_t *mi = NULL; fr_listen_t *li; fr_client_t *radclient; @@ -493,6 +493,7 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, */ if (!nak) { char *inst_name; + char const *transport_name = inst->submodule->module->exported->name; if (inst->max_connections || client->radclient->limit.max_connections) { uint32_t max_connections = inst->max_connections ? inst->max_connections : client->radclient->limit.max_connections; @@ -510,7 +511,6 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, if ((thread->num_connections + 1) >= max_connections) { DEBUG("proto_%s - Ignoring connection from client %s - 'max_connections' limit reached.", inst->app->common.name, client->radclient->shortname); - close_and_return: if (fd >= 0) close(fd); return NULL; } @@ -518,33 +518,32 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, } /* - * FIXME - This is not at all thread safe + * FIXME - This should a 'sub' module list */ - inst_name = talloc_asprintf(NULL, "%s%"PRIu64, inst->transport, thread->client_id++); - if (dl_module_instance(NULL, &dl_inst, inst->dl_inst, - DL_MODULE_TYPE_SUBMODULE, inst->transport, inst_name) < 0) { - talloc_free(inst_name); - DEBUG("Failed to find proto_%s_%s", inst->app->common.name, inst->transport); - goto close_and_return; - } - talloc_free(inst_name); + inst_name = talloc_asprintf(NULL, "%s%"PRIu64, transport_name, thread->client_id++); + mi = module_instance_alloc(inst->submodule->ml, inst->submodule, DL_MODULE_TYPE_SUBMODULE, + inst->submodule->module->exported->name, inst_name); -/* - if (dl_module_conf_parse(dl_inst, inst->server_cs) < 0) { + if (module_instance_conf_parse(mi, inst->server_cs) < 0) { + cf_log_perr(inst->server_cs, "Failed parsing module config"); goto cleanup; } -*/ - fr_assert(dl_inst != NULL); + + /* + * FIXME - Instantiate the new module?! + */ + talloc_free(inst_name); + fr_assert(mi != NULL); } else { - dl_inst = talloc_init_const("nak"); + mi = talloc_init_const("nak"); } - MEM(connection = talloc_zero(dl_inst, fr_io_connection_t)); + MEM(connection = talloc_zero(mi, fr_io_connection_t)); MEM(connection->address = talloc_memdup(connection, address, sizeof(*address))); (void) talloc_set_name_const(connection->address, "fr_io_address_t"); connection->parent = client; - connection->dl_inst = dl_inst; + connection->mi = mi; MEM(connection->client = talloc_named(NULL, sizeof(fr_io_client_t), "fr_io_client_t")); memset(connection->client, 0, sizeof(*connection->client)); @@ -657,7 +656,7 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, li->connected = true; li->app_io = thread->child->app_io; li->thread_instance = connection; - li->app_io_instance = dl_inst->data; + li->app_io_instance = mi->data; li->track_duplicates = thread->child->app_io->track_duplicates; /* @@ -732,13 +731,13 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, &connection->address->socket.inet.src_ipaddr, connection->address->socket.inet.src_port) < 0) { DEBUG("proto_%s - Failed getting IP address", inst->app->common.name); - talloc_free(dl_inst); + talloc_free(mi); return NULL; } if (inst->app_io->open(connection->child) < 0) { DEBUG("proto_%s - Failed opening connected socket.", inst->app->common.name); - talloc_free(dl_inst); + talloc_free(mi); return NULL; } @@ -824,7 +823,7 @@ static fr_io_connection_t *fr_io_connection_alloc(fr_io_instance_t const *inst, cleanup: if (fd >= 0) close(fd); - talloc_free(dl_inst); + talloc_free(mi); return NULL; } @@ -2499,7 +2498,7 @@ static ssize_t mod_write(fr_listen_t *li, void *packet_ctx, fr_time_t request_ti */ if (radclient->use_connected && !inst->app_io->connection_set) { DEBUG("proto_%s - cannot use connected sockets as underlying 'transport = %s' does not support it.", - inst->app_io->common.name, inst->submodule->dl_inst->module->common->name); + inst->app_io->common.name, inst->submodule->module->exported->name); goto error; } @@ -2619,7 +2618,7 @@ static int mod_close(fr_listen_t *li) */ fr_network_listen_delete(connection->nr, child); - talloc_free(connection->dl_inst); + talloc_free(connection->mi); return 0; } @@ -2633,10 +2632,10 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Find and bootstrap the application IO handler. */ - inst->app_io = (fr_app_io_t const *) inst->submodule->dl_inst->module->common; + inst->app_io = (fr_app_io_t const *) inst->submodule->module->exported; - inst->app_io_conf = inst->submodule->dl_inst->conf; - inst->app_io_instance = inst->submodule->dl_inst->data; + inst->app_io_conf = inst->submodule->conf; + inst->app_io_instance = inst->submodule->data; /* * If we're not tracking duplicates then we don't need a @@ -2656,7 +2655,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } } - if (inst->app_io->common.bootstrap && (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->submodule->dl_inst)) < 0)) { + if (inst->app_io->common.bootstrap && (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->submodule)) < 0)) { cf_log_err(inst->app_io_conf, "Bootstrap failed for proto_%s", inst->app_io->common.name); return -1; } @@ -2723,7 +2722,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) fr_assert(inst->app_io != NULL); if (inst->app_io->common.instantiate && - (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->submodule->dl_inst)) < 0)) { + (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->submodule)) < 0)) { cf_log_err(conf, "Instantiation failed for \"proto_%s\"", inst->app_io->common.name); return -1; } diff --git a/src/lib/io/master.h b/src/lib/io/master.h index ad0cd325d3..6ea7ae0b52 100644 --- a/src/lib/io/master.h +++ b/src/lib/io/master.h @@ -70,7 +70,7 @@ typedef struct fr_io_track_s { * creates the listener, and adds it to the scheduler. */ typedef struct { - dl_module_inst_t const *dl_inst; //!< our parent dl_inst + module_instance_t const *mi; //!< our parent mi uint32_t max_connections; //!< maximum number of connections to allow uint32_t max_clients; //!< maximum number of dynamic clients to allow diff --git a/src/lib/server/dl_module.c b/src/lib/server/dl_module.c index 9a8a6f114a..d774ec4224 100644 --- a/src/lib/server/dl_module.c +++ b/src/lib/server/dl_module.c @@ -45,24 +45,13 @@ RCSID("$Id$") * Provides space to store instance data. */ struct dl_module_loader_s { - pthread_mutex_t lock; //!< + pthread_mutex_t lock; //!< Protects the module tree when multiple threads are loading modules simultaneously. fr_rb_tree_t *module_tree; //!< Module's dl handles. - fr_rb_tree_t *inst_data_tree; //!< Module's instance data. dl_loader_t *dl_loader; //!< A list of loaded libraries, and symbol to callback mappings. }; static dl_module_loader_t *dl_module_loader; -/** Make data to instance name resolution more efficient - * - */ -typedef struct { - void *data; //!< Module's data. - dl_module_inst_t *inst; //!< Instance wrapper struct. -} dl_module_inst_cache_t; - -static _Thread_local dl_module_inst_cache_t dl_inst_cache; - /** Name prefixes matching the types of loadable module */ fr_table_num_sorted_t const dl_module_type_prefix[] = { @@ -73,16 +62,6 @@ fr_table_num_sorted_t const dl_module_type_prefix[] = { }; size_t dl_module_type_prefix_len = NUM_ELEMENTS(dl_module_type_prefix); -static int8_t dl_module_inst_data_cmp(void const *one, void const *two) -{ - dl_module_inst_t const *a = one, *b = two; - - fr_assert(a->data); - fr_assert(b->data); - - return CMP(a->data, b->data); -} - static int8_t dl_module_cmp(void const *one, void const *two) { dl_module_t const *a = one, *b = two; @@ -113,14 +92,14 @@ static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED voi */ fr_strerror_clear(); - if (dl_module->common->onload) { + if (dl_module->exported->onload) { int ret; - ret = dl_module->common->onload(); + ret = dl_module->exported->onload(); if (ret < 0) { #ifndef NDEBUG PERROR("Initialisation failed for module \"%s\" - onload() returned %i", - dl_module->common->name, ret); + dl_module->exported->name, ret); #else PERROR("Initialisation failed for module \"%s\"", dl_module->common->name); #endif @@ -145,7 +124,7 @@ static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED vo * common is NULL if we couldn't find the * symbol and are erroring out. */ - if (dl_module->common && dl_module->common->unload) dl_module->common->unload(); + if (dl_module->exported && dl_module->exported->unload) dl_module->exported->unload(); } /** Check if the magic number in the module matches the one in the library @@ -203,168 +182,6 @@ static int dl_module_magic_verify(dl_module_common_t const *module) return 0; } -/** Return top root module, in a hierarchy of modules - * - */ -dl_module_inst_t const *dl_module_instance_root(dl_module_inst_t const *dl_inst) -{ - if (!dl_inst) return NULL; - - while (dl_inst->parent) dl_inst = dl_inst->parent; - - return dl_inst; -} - -/** Return the prefix string for the deepest module - * - * This is useful for submodules which don't have a prefix of their own. - * In this case we need to use the prefix of the shallowest module, which - * will be a proto or rlm module. - * - * @param[in] dl_inst Instance to get the prefix for. - * @return The prefix string for the shallowest module. - */ -char const *dl_module_instance_root_prefix_str(dl_module_inst_t const *dl_inst) -{ - dl_module_inst_t const *root = dl_module_instance_root(dl_inst); - - return fr_table_str_by_value(dl_module_type_prefix, root->module->type, ""); -} - -/** Lookup a module's parent - * - */ -dl_module_inst_t const *dl_module_parent_instance(dl_module_inst_t const *child) -{ - return child->parent; -} - -/** Lookup a dl_module_inst_t via instance data - * - */ -dl_module_inst_t const *dl_module_instance_by_data(void const *data) -{ - DL_INIT_CHECK; - - if (dl_inst_cache.data == data) return dl_inst_cache.inst; - - return fr_rb_find(dl_module_loader->inst_data_tree, &(dl_module_inst_t){ .data = UNCONST(void *, data) }); -} - -/** Lookup a dl_module_inst_t via a config section - * - */ -dl_module_inst_t const *dl_module_instance_by_cs(CONF_SECTION const *cs) -{ - return cf_data_value(cf_data_find(cs, dl_module_inst_t, CF_IDENT_ANY)); -} - -/** Lookup instance name via instance data - * - */ -char const *dl_module_instance_name_by_data(void const *data) -{ - dl_module_inst_t const *inst; - - inst = dl_module_instance_by_data(data); - if (!inst) return NULL; - - return inst->name; -} - -/** A convenience function for returning a parent's private data - * - * @param[in] data Private instance data for child. - * @return - * - Parent's private instance data. - * - NULL if no parent - */ -void *dl_module_parent_data_by_child_data(void const *data) -{ - dl_module_inst_t const *dl_inst; - - DL_INIT_CHECK; - - dl_inst = dl_module_instance_by_data(data); - if (!dl_inst) return NULL; - - if (!dl_inst->parent) return NULL; - - return dl_inst->parent->data; -} - -/** Detach the shallowest parent first - * - */ -static void dl_module_detach_parent(dl_module_inst_t *dl_inst) -{ - if (dl_inst->detached) return; - - if (dl_inst->parent) dl_module_detach_parent(UNCONST(dl_module_inst_t *, dl_inst->parent)); - - if (dl_inst->module->common->detach) { - dl_inst->module->common->detach(&(module_detach_ctx_t){ .inst = dl_inst }); - dl_inst->detached = true; - } -} - -static int _dl_module_instance_data_free(void *data) -{ - dl_module_inst_t *dl_inst = UNCONST(dl_module_inst_t *, dl_module_instance_by_data(data)); - - if (!dl_inst) { - ERROR("Failed resolving data %p, to dl_module_inst_t, refusing to free", data); - return -1; - } - - /* - * Ensure the shallowest parent module - * gets detached first so that it can - * still reach its children. - */ - dl_module_detach_parent(dl_inst); - - return 0; -} - -/** Allocate module instance data, and parse the module's configuration - * - * @param[in] dl_inst to allocate this instance data in. - * @param[in] module to alloc instance data for. - */ -static void dl_module_instance_data_alloc(dl_module_inst_t *dl_inst, dl_module_t const *module) -{ - void *data; - - /* - * If there is supposed to be instance data, allocate it now. - * - * If the structure is zero length then allocation will still - * succeed, and will create a talloc chunk header. - * - * This is needed so we can resolve instance data back to - * dl_module_inst_t/dl_module_t/dl_t. - */ - MEM(data = talloc_zero_array(dl_inst, uint8_t, module->common->inst_size)); - - if (!module->common->inst_type) { - talloc_set_name(data, "%s_t", module->dl->name ? module->dl->name : "config"); - } else { - talloc_set_name_const(data, module->common->inst_type); - } - dl_inst->data = data; - - /* - * Must be done before setting the destructor to ensure the - * destructor can find the dl_module_inst_t associated - * with the data. - */ - fr_assert(dl_module_loader != NULL); - fr_rb_insert(dl_module_loader->inst_data_tree, dl_inst); /* Duplicates not possible */ - - talloc_set_destructor(data, _dl_module_instance_data_free); -} - /** Decrement the reference count of the dl, eventually freeing it * */ @@ -399,7 +216,7 @@ static int _dl_module_free(dl_module_t *dl_module) if (dl_module->dl) { if (DEBUG_ENABLED4) { DEBUG4("%s unloaded. Handle address %p, symbol address %p", dl_module->dl->name, - dl_module->dl->handle, dl_module->common); + dl_module->dl->handle, dl_module->exported); } else { DEBUG3("%s unloaded", dl_module->dl->name); } @@ -429,10 +246,11 @@ static int _dl_module_free(dl_module_t *dl_module) int dl_module_free(dl_module_t *dl_module) { int ret; + dl_module_loader_t *dl_module_l = dl_module->loader; /* Save this, as dl_module will be free'd */ - pthread_mutex_lock(&dl_module->loader->lock); + pthread_mutex_lock(&dl_module_l->lock); ret = talloc_free(dl_module); - pthread_mutex_unlock(&dl_module->loader->lock); + pthread_mutex_unlock(&dl_module_l->lock); return ret; } @@ -473,7 +291,7 @@ dl_module_t *dl_module_alloc(dl_module_t const *parent, char const *name, dl_mod module_name = talloc_typed_asprintf(NULL, "%s_%s_%s", fr_table_str_by_value(dl_module_type_prefix, parent->type, ""), - parent->common->name, name); + parent->exported->name, name); } else { module_name = talloc_typed_asprintf(NULL, "%s_%s", fr_table_str_by_value(dl_module_type_prefix, type, ""), @@ -505,6 +323,7 @@ dl_module_t *dl_module_alloc(dl_module_t const *parent, char const *name, dl_mod } MEM(dl_module = talloc_zero(dl_module_loader, dl_module_t)); + dl_module->name = talloc_strdup(dl_module, name); dl_module->loader = dl_module_loader; dl_module->parent = parent; dl_module->type = type; @@ -533,7 +352,7 @@ dl_module_t *dl_module_alloc(dl_module_t const *parent, char const *name, dl_mod ERROR("Could not find \"%s\" symbol in module: %s", module_name, dlerror()); goto error; } - dl_module->common = common; + dl_module->exported = common; /* * Before doing anything else, check if it's sane. @@ -572,145 +391,6 @@ dl_module_t *dl_module_alloc(dl_module_t const *parent, char const *name, dl_mod return dl_module; } -/** 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_module_instance_free(dl_module_inst_t *dl_inst) -{ - /* - * Ensure sane free order, and that all destructors - * run before the .so/.dylib is unloaded. - * - * This *MUST* be done *BEFORE* decrementing the - * reference count on the module. - * - * It also *MUST* be done before removing this struct - * from the inst_data_tree, so the detach destructor - * can find the dl_module_inst_t associated with - * the opaque data. - */ - talloc_free_children(dl_inst); - - /* - * Remove this instance from the tracking tree. - */ - fr_assert(dl_module_loader != NULL); - fr_rb_delete(dl_module_loader->inst_data_tree, dl_inst); - - /* - * Decrements the reference count. The module object - * won't be unloaded until all instances of that module - * have been destroyed. - */ - dl_module_free(dl_inst->module); - - return 0; -} - -/** Retrieve a public symbol from a module using dlsym - * - * Convenience function to lookup/return public symbols from modules loaded - * with #dl_module_instance. - * - * @param[in] dl_inst Instance who's module we're looking for the symbol in. - * @param[in] sym_name to lookup. - * @return - * - Pointer to the public data structure. - * - NULL if no matching symbol was found. - */ -void *dl_module_instance_symbol(dl_module_inst_t const *dl_inst, char const *sym_name) -{ - if (!sym_name) return NULL; - - return dlsym(dl_inst->module->dl->handle, sym_name); -} - -/** Load a module and parse its #CONF_SECTION in one operation - * - * 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_module_inst_t containing the module - * handle and instance. - * @param[in] parent of module instance. - * @param[in] type of module to load. - * @param[in] mod_name of the module to load .e.g. 'udp' for 'proto_radius_udp' - * if the parent were 'proto_radius'. - * @param[in] inst_name The name of the instance .e.g. 'sql_aws_dc01' - * - * @return - * - 0 on success. - * - -1 on failure. - */ -int dl_module_instance(TALLOC_CTX *ctx, dl_module_inst_t **out, - dl_module_inst_t const *parent, - dl_module_type_t type, char const *mod_name, char const *inst_name) -{ - dl_module_inst_t *dl_inst; - - DL_INIT_CHECK; - - MEM(dl_inst = talloc_zero(ctx, dl_module_inst_t)); - - dl_inst->module = dl_module_alloc(parent ? parent->module : NULL, mod_name, type); - if (!dl_inst->module) { - talloc_free(dl_inst); - return -1; - } - dl_inst->name = talloc_typed_strdup(dl_inst, inst_name); - - /* - * ctx here is the main module's instance data - */ - dl_module_instance_data_alloc(dl_inst, dl_inst->module); - talloc_set_destructor(dl_inst, _dl_module_instance_free); - - dl_inst->parent = parent; - *out = dl_inst; - - return 0; -} - -/** Avoid boilerplate when setting the module instance name - * - */ -char const *dl_module_inst_name_from_conf(CONF_SECTION *conf) -{ - char const *name2; - - name2 = cf_section_name2(conf); - if (name2) return name2; - - return cf_section_name1(conf); -} - -int dl_module_conf_parse(dl_module_inst_t *dl_inst, CONF_SECTION *conf) -{ - /* - * Associate the module instance with the conf section - * *before* executing any parse rules that might need it. - */ - cf_data_add(conf, dl_inst, dl_inst->module->dl->name, false); - dl_inst->conf = conf; - - if (dl_inst->module->common->config && dl_inst->conf) { - if ((cf_section_rules_push(dl_inst->conf, dl_inst->module->common->config)) < 0 || - (cf_section_parse(dl_inst->data, dl_inst->data, dl_inst->conf) < 0)) { - cf_log_err(dl_inst->conf, "Failed evaluating configuration for module \"%s\"", - dl_inst->module->dl->name); - return -1; - } - } - - return 0; -} - static int _dl_module_loader_free(dl_module_loader_t *dl_module_l) { int ret = 0; @@ -721,18 +401,18 @@ static int _dl_module_loader_free(dl_module_loader_t *dl_module_l) fr_assert_msg(pthread_mutex_trylock(&dl_module_l->lock) == 0, "dl_module_loader->lock held when attempting to free dL_module_loader_t"); - if (fr_rb_num_elements(dl_module_l->inst_data_tree) > 0) { + if (fr_rb_num_elements(dl_module_l->module_tree) > 0) { #ifndef NDEBUG fr_rb_iter_inorder_t iter; - void *data; + void *data; - WARN("Refusing to cleanup dl loader, the following module instances are still in use:"); - for (data = fr_rb_iter_init_inorder(&iter, dl_module_l->inst_data_tree); + WARN("Refusing to cleanup dl loader, the following modules are still in use:"); + for (data = fr_rb_iter_init_inorder(&iter, dl_module_l->module_tree); data; data = fr_rb_iter_next_inorder(&iter)) { - dl_module_inst_t *dl_inst = talloc_get_type_abort(data, dl_module_inst_t); + dl_module_t *module = talloc_get_type_abort(data, dl_module_t); - WARN(" %s (%s)", dl_inst->module->dl->name, dl_inst->name); + WARN(" %s", module->exported->name); } #endif ret = -1; @@ -840,16 +520,9 @@ dl_module_loader_t *dl_module_loader_init(char const *lib_dir) } if (lib_dir) dl_search_path_prepend(dl_module_loader->dl_loader, lib_dir); - dl_module_loader->inst_data_tree = fr_rb_talloc_alloc(dl_module_loader, dl_module_inst_t, - dl_module_inst_data_cmp, NULL); - if (!dl_module_loader->inst_data_tree) { - ERROR("Failed initialising dl->inst_data_tree"); - goto error; - } - dl_module_loader->module_tree = fr_rb_talloc_alloc(dl_module_loader, dl_module_t, dl_module_cmp, NULL); - if (!dl_module_loader->inst_data_tree) { + if (!dl_module_loader->module_tree) { ERROR("Failed initialising dl->module_tree"); goto error; } diff --git a/src/lib/server/dl_module.h b/src/lib/server/dl_module.h index d702e51400..a964289e86 100644 --- a/src/lib/server/dl_module.h +++ b/src/lib/server/dl_module.h @@ -57,8 +57,6 @@ extern "C" { # define DL_EXTENSION ".so" #endif -typedef struct dl_module_instance_s dl_module_inst_t; - /** Stop people using different module/library/server versions together * */ @@ -83,31 +81,11 @@ typedef enum { typedef struct dl_module_loader_s dl_module_loader_t; -typedef struct { - dl_module_inst_t const *inst; -} module_detach_ctx_t; - -/** Module detach callback - * - * Is called just before the server exits, and after re-instantiation on HUP, - * to free the old module instance. - * - * Detach should close all handles associated with the module instance, and - * free any memory allocated during instantiate. - * - * @param[in] inst to free. - * @return - * - 0 on success. - * - -1 if detach failed. - */ -typedef int (*module_detach_t)(module_detach_ctx_t const *inst); - /** Callback to call when a module is first loaded * */ typedef int (*dl_module_onload_t)(void); - /** Callback when a module is destroyed * */ @@ -115,17 +93,14 @@ typedef void (*dl_module_unload_t)(void); /** Common fields for the interface struct modules export * + * These are just enough for the loader to be able to load and unload the module. */ #define DL_MODULE_COMMON \ struct { \ uint64_t magic; \ char const *name; \ - size_t inst_size; \ - char const *inst_type; \ - conf_parser_t const *config; \ dl_module_onload_t onload; \ dl_module_unload_t unload; \ - module_detach_t detach; \ } /** Fields common to all types of loadable modules @@ -140,6 +115,8 @@ typedef struct { */ typedef struct dl_module_s dl_module_t; struct dl_module_s { + char const * _CONST name; //!< Name of the module. The name passed to dl_module_alloc. + dl_module_loader_t * _CONST loader; //!< Loader that owns this dl. dl_t * _CONST dl; //!< Dynamic loader handle. @@ -148,7 +125,7 @@ struct dl_module_s { dl_module_type_t _CONST type; //!< of this module. - dl_module_common_t const * _CONST common; //!< Symbol exported by the module, containing its public + dl_module_common_t const * _CONST exported; //!< Symbol exported by the module, containing its public //!< functions, name and behaviour control flags. CONF_SECTION * _CONST conf; //!< The module's global configuration @@ -166,19 +143,6 @@ struct dl_module_s { bool _CONST in_tree; }; -/** A module/inst tuple - * - * Used to pass data back from dl_module_instance_parse_func - */ -struct dl_module_instance_s { - char const * _CONST name; //!< Instance name. - dl_module_t * _CONST module; //!< Module - void * _CONST data; //!< Module instance's parsed configuration. - CONF_SECTION * _CONST conf; //!< Module's instance configuration. - dl_module_inst_t const * _CONST parent; //!< Parent module's instance (if any). - bool _CONST detached; //!< Whether the detach function has been called. -}; - extern fr_table_num_sorted_t const dl_module_type_prefix[]; extern size_t dl_module_type_prefix_len; @@ -186,30 +150,6 @@ int dl_module_free(dl_module_t *dl_module); dl_module_t *dl_module_alloc(dl_module_t const *parent, char const *name, dl_module_type_t type); -dl_module_inst_t const *dl_module_instance_root(dl_module_inst_t const *dl_inst); - -char const *dl_module_instance_root_prefix_str(dl_module_inst_t const *dl_inst); - -dl_module_inst_t const *dl_module_parent_instance(dl_module_inst_t const *child); - -dl_module_inst_t const *dl_module_instance_by_data(void const *data); - -dl_module_inst_t const *dl_module_instance_by_cs(CONF_SECTION const *cs); - -char const *dl_module_instance_name_by_data(void const *data); - -void *dl_module_parent_data_by_child_data(void const *data); - -void *dl_module_instance_symbol(dl_module_inst_t const *instance, char const *sym_name); - -int dl_module_instance(TALLOC_CTX *ctx, dl_module_inst_t **out, - dl_module_inst_t const *parent, - dl_module_type_t type, char const *name, char const *inst_name); - -char const *dl_module_inst_name_from_conf(CONF_SECTION *conf); - -int dl_module_conf_parse(dl_module_inst_t *dl_inst, CONF_SECTION *conf); - char const *dl_module_search_path(void); dl_loader_t *dl_loader_from_module_loader(dl_module_loader_t *dl_module_loader); diff --git a/src/lib/server/module.c b/src/lib/server/module.c index f0bd11ed53..402d157d83 100644 --- a/src/lib/server/module.c +++ b/src/lib/server/module.c @@ -21,11 +21,12 @@ * @brief Defines functions for module (re-)initialisation. * * @copyright 2003,2006,2016 The FreeRADIUS server project - * @copyright 2016 Arran Cudbard-Bell (a.cudbardb@freeradius.org) + * @copyright 2016,2024 Arran Cudbard-Bell (a.cudbardb@freeradius.org) * @copyright 2000 Alan DeKok (aland@freeradius.org) * @copyright 2000 Alan Curry (pacman@world.std.com) */ +#include "lib/util/talloc.h" RCSID("$Id$") #include @@ -142,9 +143,9 @@ static int cmd_show_module_config(FILE *fp, UNUSED FILE *fp_err, void *ctx, UNUS { module_instance_t *mi = ctx; - fr_assert(mi->dl_inst->conf != NULL); + fr_assert(mi->conf != NULL); - (void) cf_section_write(fp, mi->dl_inst->conf, 0); + (void) cf_section_write(fp, mi->conf, 0); return 0; } @@ -222,6 +223,102 @@ static int cmd_set_module_status(UNUSED FILE *fp, FILE *fp_err, void *ctx, fr_cm return 0; } +/** Return the prefix string for the deepest module + * + * This is useful for submodules which don't have a prefix of their own. + * In this case we need to use the prefix of the shallowest module, which + * will be a proto or rlm module. + * + * @param[in] mi Instance to get the prefix for. + * @return The prefix string for the shallowest module. + */ +char const *module_instance_root_prefix_str(module_instance_t const *mi) +{ + module_instance_t const *root = module_instance_root(mi); + + return fr_table_str_by_value(dl_module_type_prefix, root->module->type, ""); +} + +/** Detach the shallowest parent first + * + */ +static void module_detach_parent(module_instance_t *mi) +{ + if (mi->detached) return; + + if (mi->parent) module_detach_parent(UNCONST(module_instance_t *, mi->parent)); + + if (mi->exported->detach) { + mi->exported->detach(&(module_detach_ctx_t){ .inst = mi }); + mi->detached = true; + } +} + +/** Allocate module instance data + * + * @param[in] mi to allocate instance data for + */ +static inline CC_HINT(always_inline) +void module_instance_data_alloc(module_instance_t *mi) +{ + dl_module_t const *module = mi->module; + void *data; + + /* + * If there is supposed to be instance data, allocate it now. + * + * If the structure is zero length then allocation will still + * succeed, and will create a talloc chunk header. + * + * This is needed so we can resolve instance data back to + * module_instance_t/dl_module_t/dl_t. + */ + MEM(data = talloc_zero_array(mi, uint8_t, mi->exported->inst_size)); + if (!mi->exported->inst_type) { + talloc_set_name(data, "%s_t", module->dl->name ? module->dl->name : "config"); + } else { + talloc_set_name_const(data, mi->exported->inst_type); + } + mi->data = data; +} + +/** Avoid boilerplate when setting the module instance name + * + */ +char const *module_instance_name_from_conf(CONF_SECTION *conf) +{ + char const *name2; + + name2 = cf_section_name2(conf); + if (name2) return name2; + + return cf_section_name1(conf); +} + +/** Covert a CONF_SECTION into parsed module instance data + * + */ +int module_instance_conf_parse(module_instance_t *mi, CONF_SECTION *conf) +{ + /* + * Associate the module instance with the conf section + * *before* executing any parse rules that might need it. + */ + cf_data_add(conf, mi, mi->module->dl->name, false); + mi->conf = conf; + + if (mi->exported->config && mi->conf) { + if ((cf_section_rules_push(mi->conf, mi->exported->config)) < 0 || + (cf_section_parse(mi->data, mi->data, mi->conf) < 0)) { + cf_log_err(mi->conf, "Failed evaluating configuration for module \"%s\"", + mi->module->dl->name); + return -1; + } + } + + return 0; +} + /** Sort module instance data first by list then by number * * The module's position in the global instance heap informs of us @@ -251,7 +348,7 @@ static int8_t module_instance_name_cmp(void const *one, void const *two) { module_instance_t const *a = one; module_instance_t const *b = two; - dl_module_inst_t const *dl_inst; + module_instance_t const *mi; int a_depth = 0, b_depth = 0; int ret; @@ -260,22 +357,22 @@ static int8_t module_instance_name_cmp(void const *one, void const *two) * at the shallowest node, and finish with * the deepest child. */ - for (dl_inst = a->dl_inst; dl_inst; dl_inst = dl_inst->parent) a_depth++; - for (dl_inst = b->dl_inst; dl_inst; dl_inst = dl_inst->parent) b_depth++; + for (mi = a; mi; mi = mi->parent) a_depth++; + for (mi = b; mi; mi = mi->parent) b_depth++; ret = CMP(a_depth, b_depth); if (ret != 0) return ret; /* - * This happens, as dl_inst is is used in + * This happens, as mi is is used in * as the loop condition above. */ #ifdef STATIC_ANALYZER - if (!fr_cond_assert(a->dl_inst)) return +1; - if (!fr_cond_assert(b->dl_inst)) return -1; + if (!fr_cond_assert(a)) return +1; + if (!fr_cond_assert(b)) return -1; #endif - ret = CMP(a->dl_inst->parent, b->dl_inst->parent); + ret = CMP(a->parent, b->parent); if (ret != 0) return ret; ret = strcmp(a->name, b->name); @@ -287,8 +384,8 @@ static int8_t module_instance_name_cmp(void const *one, void const *two) */ static int8_t module_instance_data_cmp(void const *one, void const *two) { - void const *a = (((module_instance_t const *)one)->dl_inst)->data; - void const *b = (((module_instance_t const *)two)->dl_inst)->data; + void const *a = ((module_instance_t const *)one)->data; + void const *b = ((module_instance_t const *)two)->data; return CMP(a, b); } @@ -336,13 +433,13 @@ int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, * and will be appended to the parent's instance * name. */ - mi = module_alloc(ml, module_by_data(ml, parent), DL_MODULE_TYPE_SUBMODULE, name, name); + mi = module_instance_alloc(ml, module_instance_by_data(ml, parent), DL_MODULE_TYPE_SUBMODULE, name, name); if (unlikely(mi == NULL)) { cf_log_err(submodule_cs, "Failed loading submodule"); return -1; } - if (unlikely(module_conf_parse(mi, submodule_cs) < 0)) { + if (unlikely(module_instance_conf_parse(mi, submodule_cs) < 0)) { cf_log_err(submodule_cs, "Failed parsing submodule config"); talloc_free(mi); return -1; @@ -364,7 +461,7 @@ int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, * - Module instance matching name. * - NULL if no such module exists. */ -module_instance_t *module_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name) +module_instance_t *module_instance_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name) { char const *inst_name; void *inst; @@ -381,7 +478,7 @@ module_instance_t *module_by_name(module_list_t const *ml, module_instance_t con inst = fr_rb_find(ml->name_tree, &(module_instance_t){ - .dl_inst = &(dl_module_inst_t){ .parent = parent ? parent->dl_inst : NULL }, + .parent = UNCONST(module_instance_t *, parent), .name = inst_name }); if (!inst) return NULL; @@ -389,23 +486,6 @@ module_instance_t *module_by_name(module_list_t const *ml, module_instance_t con return talloc_get_type_abort(inst, module_instance_t); } -/** Find the module's parent (if any) - * - * @param[in] child to locate the parent for. - * @return - * - The module's parent. - * - NULL on error. - */ -module_instance_t *module_parent(module_instance_t const *child) -{ - dl_module_inst_t const *parent; - - parent = dl_module_parent_instance(child->dl_inst); - if (!parent) return NULL; - - return module_by_data(child->ml, parent->data); -} - /** Find the module's shallowest parent * * @param[in] child to locate the root for. @@ -413,12 +493,12 @@ module_instance_t *module_parent(module_instance_t const *child) * - The module's shallowest parent. * - NULL on error. */ -module_instance_t *module_root(module_instance_t const *child) +module_instance_t *module_instance_root(module_instance_t const *child) { - module_instance_t *next; + module_instance_t const *next; for (;;) { - next = module_parent(child); + next = child->parent; if (!next) break; child = next; @@ -435,20 +515,19 @@ module_instance_t *module_root(module_instance_t const *child) * - Module instance matching data. * - NULL if no such module exists. */ -module_instance_t *module_by_data(module_list_t const *ml, void const *data) +module_instance_t *module_instance_by_data(module_list_t const *ml, void const *data) { module_instance_t *mi; mi = fr_rb_find(ml->data_tree, &(module_instance_t){ - .dl_inst = &(dl_module_inst_t){ .data = UNCONST(void *, data) }, + .data = UNCONST(void *, data) }); if (!mi) return NULL; return talloc_get_type_abort(mi, module_instance_t); } - /** Retrieve module/thread specific instance for a module * * @param[in] mi to find thread specific data for. @@ -477,14 +556,14 @@ module_thread_instance_t *module_thread(module_instance_t *mi) * @param[in] ml Module list module belongs to. * @param[in] data Private instance data of the module. * Same as what would be provided by - * #module_by_data. + * #module_instance_by_data. * @return * - Thread specific instance data on success. * - NULL if module has no thread instance data. */ module_thread_instance_t *module_thread_by_data(module_list_t const *ml, void const *data) { - module_instance_t *mi = module_by_data(ml, data); + module_instance_t *mi = module_instance_by_data(ml, data); module_thread_instance_t *ti; if (!mi) return NULL; @@ -539,11 +618,11 @@ static int _module_thread_inst_free(module_thread_instance_t *ti) module_list_in_sync = false; /* Help catch anything attempting to do lookups */ DEBUG4("Worker cleaning up %s thread instance data (%p/%p)", - mi->module->name, ti, ti->data); + mi->exported->name, ti, ti->data); - if (mi->module->thread_detach) { - mi->module->thread_detach(&(module_thread_inst_ctx_t const ){ - .inst = ti->mi->dl_inst, + if (mi->exported->thread_detach) { + mi->exported->thread_detach(&(module_thread_inst_ctx_t const ){ + .inst = ti->mi, .thread = ti->data, .el = ti->el }); @@ -610,25 +689,25 @@ static int module_thread_instantiate(TALLOC_CTX *ctx, module_thread_instance_t * ti->el = el; ti->mi = mi; - if (mi->module->thread_inst_size) { + if (mi->exported->thread_inst_size) { module_instance_t *rmi; - MEM(ti->data = talloc_zero_array(ti, uint8_t, mi->module->thread_inst_size)); - rmi = module_root(mi); + MEM(ti->data = talloc_zero_array(ti, uint8_t, mi->exported->thread_inst_size)); + rmi = module_instance_root(mi); /* * Fixup the type name, in case something calls * talloc_get_type_abort() on it... */ - if (!mi->module->thread_inst_type) { + if (!mi->exported->thread_inst_type) { talloc_set_name(ti->data, "%s_%s_thread_t", fr_table_str_by_value(dl_module_type_prefix, - rmi ? rmi->dl_inst->module->type : - mi->dl_inst->module->type, + rmi ? rmi->module->type : + mi->module->type, ""), - mi->module->name); + mi->exported->name); } else { - talloc_set_name_const(ti->data, mi->module->thread_inst_type); + talloc_set_name_const(ti->data, mi->exported->thread_inst_type); } } @@ -637,9 +716,9 @@ static int module_thread_instantiate(TALLOC_CTX *ctx, module_thread_instance_t * */ fr_strerror_clear(); - DEBUG4("Alloced %s thread instance data (%p/%p)", ti->mi->module->name, ti, ti->data); - if (mi->module->thread_instantiate && - mi->module->thread_instantiate(MODULE_THREAD_INST_CTX(mi->dl_inst, ti->data, el)) < 0) { + DEBUG4("Alloced %s thread instance data (%p/%p)", ti->mi->exported->name, ti, ti->data); + if (mi->exported->thread_instantiate && + mi->exported->thread_instantiate(MODULE_THREAD_INST_CTX(mi, ti->data, el)) < 0) { PERROR("Thread instantiation failed for module \"%s\"", mi->name); /* Leave module_thread_inst_list intact, other modules may need to clean up */ modules_thread_detach(ml); @@ -703,14 +782,14 @@ int modules_thread_instantiate(TALLOC_CTX *ctx, module_list_t const *ml, fr_even int module_instantiate(module_instance_t *instance) { module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t); - CONF_SECTION *cs = mi->dl_inst->conf; + CONF_SECTION *cs = mi->conf; /* * We only instantiate modules in the bootstrapped state */ if (mi->state != MODULE_INSTANCE_BOOTSTRAPPED) return 0; - if (mi->dl_inst->module->type == DL_MODULE_TYPE_MODULE) { + if (mi->module->type == DL_MODULE_TYPE_MODULE) { if (fr_command_register_hook(NULL, mi->name, mi, module_cmd_table) < 0) { PERROR("Failed registering radmin commands for module %s", mi->name); return -1; @@ -721,23 +800,23 @@ int module_instantiate(module_instance_t *instance) * Now that ALL modules are instantiated, and ALL xlats * are defined, go compile the config items marked as XLAT. */ - if (mi->module->config && (cf_section_parse_pass2(mi->dl_inst->data, - mi->dl_inst->conf) < 0)) return -1; + if (mi->exported->config && (cf_section_parse_pass2(mi->data, + mi->conf) < 0)) return -1; /* * Call the instantiate method, if any. */ - if (mi->module->instantiate) { + if (mi->exported->instantiate) { cf_log_debug(cs, "Instantiating %s_%s \"%s\"", - dl_module_instance_root_prefix_str(mi->dl_inst), - mi->dl_inst->module->common->name, + module_instance_root_prefix_str(mi), + mi->module->exported->name, mi->name); /* * Call the module's instantiation routine. */ - if (mi->module->instantiate(MODULE_INST_CTX(mi->dl_inst)) < 0) { - cf_log_err(mi->dl_inst->conf, "Instantiation failed for module \"%s\"", mi->name); + if (mi->exported->instantiate(MODULE_INST_CTX(mi)) < 0) { + cf_log_err(mi->conf, "Instantiation failed for module \"%s\"", mi->name); return -1; } @@ -800,15 +879,15 @@ int module_bootstrap(module_instance_t *mi) * in the trees if it needs to bootstrap * submodules. */ - if (mi->module->bootstrap) { - CONF_SECTION *cs = mi->dl_inst->conf; + if (mi->exported->bootstrap) { + CONF_SECTION *cs = mi->conf; cf_log_debug(cs, "Bootstrapping %s_%s \"%s\"", - dl_module_instance_root_prefix_str(mi->dl_inst), - mi->dl_inst->module->common->name, + module_instance_root_prefix_str(mi), + mi->module->exported->name, mi->name); - if (mi->module->bootstrap(MODULE_INST_CTX(mi->dl_inst)) < 0) { + if (mi->exported->bootstrap(MODULE_INST_CTX(mi)) < 0) { cf_log_err(cs, "Bootstrap failed for module \"%s\"", mi->name); return -1; } @@ -851,24 +930,20 @@ int modules_bootstrap(module_list_t const *ml) * * @param[in] ctx Where to allocate the module name. * @param[out] out Where to write a pointer to the instance name. - * @param[in] ml Module list in which to find the parent. * @param[in] parent of the module. * @param[in] inst_name module's instance name. */ -static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out, module_list_t const *ml, +static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out, module_instance_t const *parent, char const *inst_name) { fr_sbuff_t *agg; + module_instance_t const *mi; FR_SBUFF_TALLOC_THREAD_LOCAL(&agg, 64, 256); - while (parent) { - FR_SBUFF_IN_STRCPY_RETURN(agg, parent->name); + for (mi = parent; mi; mi = mi->parent) { + FR_SBUFF_IN_STRCPY_RETURN(agg, mi->name); FR_SBUFF_IN_CHAR_RETURN(agg, '.'); - - if (!parent->dl_inst->parent) break; - - parent = module_by_data(ml, parent->dl_inst->parent->data); } FR_SBUFF_IN_STRCPY_RETURN(agg, inst_name); @@ -876,7 +951,6 @@ static fr_slen_t module_instance_name(TALLOC_CTX *ctx, char **out, module_list_t MEM(*out = talloc_bstrndup(ctx, fr_sbuff_start(agg), fr_sbuff_used(agg))); return fr_sbuff_used(agg); - } /** Free module's instance data, and any xlats or paircmps @@ -895,9 +969,9 @@ static int _module_instance_free(module_instance_t *mi) if (fr_rb_node_inline_in_tree(&mi->data_node) && !fr_cond_assert(fr_rb_delete(ml->data_tree, mi))) return 1; /* - * mi->module may be NULL if we failed loading the module + * mi->exported may be NULL if we failed loading the module */ - if (mi->module && ((mi->module->flags & MODULE_TYPE_THREAD_UNSAFE) != 0)) { + if (mi->exported && ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0)) { #ifndef NDEBUG int ret; @@ -918,11 +992,13 @@ static int _module_instance_free(module_instance_t *mi) /* * Remove all xlat's registered to module instance. */ - if (mi->dl_inst && mi->dl_inst->data) { + if (mi && mi->data) { xlat_func_unregister(mi->name); - xlat_func_unregister_module(mi->dl_inst); + xlat_func_unregister_module(mi); } + module_detach_parent(mi); + /* * We need to explicitly free all children, so the module instance * destructors get executed before we unload the bytecode for the @@ -933,20 +1009,7 @@ static int _module_instance_free(module_instance_t *mi) */ talloc_free_children(mi); - return 0; -} - -/** Parse the configuration associated with a module - * - * @param[in] mi To parse the configuration for. - * @param[in] mod_conf To parse. - * @return - * - 0 on success. - * - -1 on failure. - */ -int module_conf_parse(module_instance_t *mi, CONF_SECTION *mod_conf) -{ - if (dl_module_conf_parse(mi->dl_inst, mod_conf) < 0) return -1; + dl_module_free(mi->module); return 0; } @@ -974,9 +1037,9 @@ int module_conf_parse(module_instance_t *mi, CONF_SECTION *mod_conf) * and private instance data. * - NULL on error. */ -module_instance_t *module_alloc(module_list_t *ml, - module_instance_t const *parent, - dl_module_type_t type, char const *mod_name, char const *inst_name) +module_instance_t *module_instance_alloc(module_list_t *ml, + module_instance_t const *parent, + dl_module_type_t type, char const *mod_name, char const *inst_name) { char *qual_inst_name = NULL; module_instance_t *mi; @@ -990,7 +1053,7 @@ module_instance_t *module_alloc(module_list_t *ml, * Takes the inst_name and adds qualifiers * if this is a submodule. */ - if (module_instance_name(NULL, &qual_inst_name, ml, parent, inst_name) < 0) { + if (module_instance_name(NULL, &qual_inst_name, parent, inst_name) < 0) { ERROR("Module name too long"); return NULL; } @@ -998,24 +1061,24 @@ module_instance_t *module_alloc(module_list_t *ml, /* * See if the module already exists. */ - mi = module_by_name(ml, parent, qual_inst_name); + mi = module_instance_by_name(ml, parent, qual_inst_name); if (mi) { /* * We may not have configuration data yet * for the duplicate module. */ - if (mi->dl_inst->conf) { + if (mi->conf) { ERROR("Duplicate %s_%s instance \"%s\", previous instance defined at %s[%d]", - fr_table_str_by_value(dl_module_type_prefix, mi->dl_inst->module->type, ""), - mi->dl_inst->module->common->name, + fr_table_str_by_value(dl_module_type_prefix, mi->module->type, ""), + mi->module->exported->name, qual_inst_name, - cf_filename(mi->dl_inst->conf), - cf_lineno(mi->dl_inst->conf)); + cf_filename(mi->conf), + cf_lineno(mi->conf)); } else { ERROR("Duplicate %s_%s instance \"%s\"", - fr_table_str_by_value(dl_module_type_prefix, mi->dl_inst->module->type, ""), - mi->dl_inst->module->common->name, + fr_table_str_by_value(dl_module_type_prefix, mi->module->type, ""), + mi->module->exported->name, qual_inst_name); } talloc_free(qual_inst_name); @@ -1023,23 +1086,37 @@ module_instance_t *module_alloc(module_list_t *ml, } MEM(mi = talloc_zero(parent ? (void const *)parent : (void const *)ml, module_instance_t)); - if (dl_module_instance(mi, &mi->dl_inst, parent ? parent->dl_inst : NULL, - type, mod_name, qual_inst_name) < 0) { + mi->name = talloc_typed_strdup(mi, qual_inst_name); + talloc_free(qual_inst_name); /* Avoid stealing */ + + mi->ml = ml; + mi->parent = parent; + + /* + * Increment the reference count on an already loaded module, + * or load the .so or .dylib, and run all the global callbacks. + */ + mi->module = dl_module_alloc(parent ? parent->module : NULL, mod_name, type); + if (!mi->module) { error: - mi->name = qual_inst_name; /* Assigned purely for debug log output when mi is freed */ talloc_free(mi); - talloc_free(qual_inst_name); return NULL; } - fr_assert(mi->dl_inst); - mi->module = (module_t const *)mi->dl_inst->module->common; - if (!mi->module) { + /* + * We have no way of checking if this is correct... so we hope... + */ + mi->exported = (module_t const *)mi->module->exported; + if (unlikely(mi->exported == NULL)) { ERROR("Missing public structure for \"%s\"", qual_inst_name); - talloc_free(mi); - return NULL; + goto error; } + /* + * Allocate the module instance data. + */ + module_instance_data_alloc(mi); + /* * If we're threaded, check if the module is thread-safe. * @@ -1048,11 +1125,8 @@ module_instance_t *module_alloc(module_list_t *ml, * Do this here so the destructor can trylock the mutex * correctly even if bootstrap/instantiation fails. */ - if ((mi->module->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL); - talloc_set_destructor(mi, _module_instance_free); - - mi->name = talloc_typed_strdup(mi, qual_inst_name); - talloc_free(qual_inst_name); /* Avoid stealing */ + if ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL); + talloc_set_destructor(mi, _module_instance_free); /* Set late intentionally */ mi->number = ml->last_number++; mi->ml = ml; @@ -1061,21 +1135,17 @@ module_instance_t *module_alloc(module_list_t *ml, * Remember the module for later. */ if (!fr_cond_assert(fr_rb_insert(ml->name_tree, mi))) goto error; - - /* - * Allow modules to get at their own - * module_instance_t data, for - * looking up thread specific data - * and for bootstrapping submodules. - */ - if (mi->dl_inst->data && !fr_cond_assert(fr_rb_insert(ml->data_tree, mi))) goto error; + if (!fr_cond_assert(fr_rb_insert(ml->data_tree, mi))) goto error; /* * ...and finally insert the module * into the global heap so we can * get common thread-local indexes. */ - if (fr_heap_insert(&module_global_inst_list, mi) < 0) goto error; + if (fr_heap_insert(&module_global_inst_list, mi) < 0) { + ERROR("Failed inserting into global module index"); + goto error; + } return mi; } diff --git a/src/lib/server/module.h b/src/lib/server/module.h index f725600b1b..44514ef23c 100644 --- a/src/lib/server/module.h +++ b/src/lib/server/module.h @@ -80,6 +80,27 @@ typedef unlang_action_t (*module_method_t)(rlm_rcode_t *p_result, module_ctx_t c */ typedef int (*module_instantiate_t)(module_inst_ctx_t const *mctx); +/** Wrapper structure around module_instance_t to allow us to pass more arguments into module_detach_ctx_t in future + */ +typedef struct { + module_instance_t const *inst; //!< Module instance to detach. +} module_detach_ctx_t; + +/** Module detach callback + * + * Is called just before the server exits, and after re-instantiation on HUP, + * to free the old module instance. + * + * Detach should close all handles associated with the module instance, and + * free any memory allocated during instantiate. + * + * @param[in] inst to free. + * @return + * - 0 on success. + * - -1 if detach failed. + */ +typedef int (*module_detach_t)(module_detach_ctx_t const *inst); + /** Module thread creation callback * * Called whenever a new thread is created. @@ -140,24 +161,42 @@ struct module_method_name_s { * within the module to different sections. */ struct module_s { - DL_MODULE_COMMON; //!< Common fields for all loadable modules. - - module_instantiate_t bootstrap; - module_instantiate_t instantiate; - int flags; /* flags */ - module_thread_instantiate_t thread_instantiate; - module_thread_detach_t thread_detach; - char const *thread_inst_type; - size_t thread_inst_size; + DL_MODULE_COMMON; //!< Common fields for all loadable modules. + + conf_parser_t const *config; //!< How to convert a CONF_SECTION to a module instance. + + size_t inst_size; //!< Size of the module's instance data. + char const *inst_type; //!< talloc type to assign to instance data. + + module_instantiate_t bootstrap; //!< Callback to allow the module to register any global + ///< resources like xlat functions and attributes. + module_instantiate_t instantiate; //!< Callback to allow the module to register any + ///< per-instance resources like sockets and file handles. + module_detach_t detach; //!< Clean up module resources from both the bootstrap + ///< and instantiation pahses. + + module_flags_t flags; //!< Flags that control how a module starts up and how + ///< a module is called. + + module_thread_instantiate_t thread_instantiate; //!< Callback to populate a new module thread instance data. + ///< Called once per thread. + module_thread_detach_t thread_detach; //!< Callback to free thread-specific resources associated + ///!< with a module. + + size_t thread_inst_size; //!< Size of the module's thread-specific instance data. + char const *thread_inst_type; //!< talloc type to assign to thread instance data. }; /** What state the module instance is currently in * */ typedef enum { - MODULE_INSTANCE_INIT = 0, - MODULE_INSTANCE_BOOTSTRAPPED, - MODULE_INSTANCE_INSTANTIATED + MODULE_INSTANCE_INIT = 0, //!< Module instance has been allocated, but not + ///< yet bootstrapped. + MODULE_INSTANCE_BOOTSTRAPPED, //!< Module instance has been bootstrapped, but not + ///< yet instantiated. + MODULE_INSTANCE_INSTANTIATED //!< Module instance has been bootstrapped and + ///< instantiated. } module_instance_state_t; /** Per instance data @@ -170,30 +209,39 @@ struct module_instance_s { fr_heap_index_t inst_idx; //!< Entry in the bootstrap/instantiation heap. //!< should be an identical value to the thread-specific ///< data for this module. + module_instance_state_t state; //!< What's been done with this module so far. fr_rb_node_t name_node; //!< Entry in the name tree. fr_rb_node_t data_node; //!< Entry in the data tree. module_list_t *ml; //!< Module list this instance belongs to. - uint32_t number; //!< Unique module number. + uint32_t number; //!< Unique module number. This is used to access the + ///< thread-specific module instance. char const *name; //!< Instance name e.g. user_database. - dl_module_inst_t *dl_inst; //!< Structure containing the module's instance data, - //!< configuration, and dl handle. This can be used - ///< to access the parsed configuration data for the - ///< module. + dl_module_t *module; //!< dynamic loader handle. Contains the module's + ///< dlhandle, and the functions it exports. + ///< The dl_module is reference counted so that it + ///< can be freed automatically when the last instance + ///< is freed. This will also (usually) unload the + ///< .so or .dylib. - module_t const *module; //!< Public module structure. Cached for convenience. + module_t const *exported; //!< Public module structure. Cached for convenience. ///< This exports module methods, i.e. the functions ///< which allow the module to perform actions. + ///< This is an identical address to dl_module->common, + ///< but with a different type, containing additional + ///< instance callbacks to make it easier to use. - pthread_mutex_t mutex; //!< Used prevent multiple threads entering a thread - ///< unsafe module simultaneously. + void *data; //!< Module's instance data. + CONF_SECTION *conf; //!< Module's instance configuration. - module_instance_state_t state; //!< What's been done with this module so far. + module_instance_t const *parent; //!< Parent module's instance (if any). + pthread_mutex_t mutex; //!< Used prevent multiple threads entering a thread + ///< unsafe module simultaneously. /** @name Return code overrides * @{ */ @@ -206,6 +254,8 @@ struct module_instance_s { unlang_actions_t actions; //!< default actions and retries. /** @} */ + + bool detached; //!< Whether the detach function has been called. }; /** Per thread per instance data @@ -259,14 +309,18 @@ int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, * * @{ */ -module_instance_t *module_parent(module_instance_t const *child) CC_HINT(warn_unused_result); +char const *module_instance_name_from_conf(CONF_SECTION *conf); -module_instance_t *module_root(module_instance_t const *child); CC_HINT(warn_unused_result) +int module_instance_conf_parse(module_instance_t *mi, CONF_SECTION *conf); -module_instance_t *module_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name) +char const *module_instance_root_prefix_str(module_instance_t const *mi) CC_HINT(nonnull) CC_HINT(warn_unused_result); + +module_instance_t *module_instance_root(module_instance_t const *child); CC_HINT(warn_unused_result) + +module_instance_t *module_instance_by_name(module_list_t const *ml, module_instance_t const *parent, char const *asked_name) CC_HINT(nonnull(1,3)) CC_HINT(warn_unused_result); -module_instance_t *module_by_data(module_list_t const *ml, void const *data) CC_HINT(warn_unused_result); +module_instance_t *module_instance_by_data(module_list_t const *ml, void const *data) CC_HINT(warn_unused_result); module_thread_instance_t *module_thread(module_instance_t *mi) CC_HINT(warn_unused_result); @@ -291,9 +345,7 @@ int module_bootstrap(module_instance_t *mi) CC_HINT(nonnull) CC_HINT(warn_unuse int modules_bootstrap(module_list_t const *ml) CC_HINT(nonnull) CC_HINT(warn_unused_result); -int module_conf_parse(module_instance_t *mi, CONF_SECTION *mod_cs) CC_HINT(nonnull) CC_HINT(warn_unused_result); - -module_instance_t *module_alloc(module_list_t *ml, +module_instance_t *module_instance_alloc(module_list_t *ml, module_instance_t const *parent, dl_module_type_t type, char const *mod_name, char const *inst_name) CC_HINT(nonnull(1)) CC_HINT(warn_unused_result); diff --git a/src/lib/server/module_ctx.h b/src/lib/server/module_ctx.h index aa05f83801..a926e3f9b6 100644 --- a/src/lib/server/module_ctx.h +++ b/src/lib/server/module_ctx.h @@ -28,18 +28,18 @@ */ RCSIDH(module_ctx_h, "$Id$") -#include #include #ifdef __cplusplus extern "C" { #endif +typedef struct module_instance_s module_instance_t; /** Temporary structure to hold arguments for module calls * */ typedef struct { - dl_module_inst_t const *inst; //!< Dynamic loader API handle for the module. + module_instance_t const *inst; //!< Dynamic loader API handle for the module. void *thread; //!< Thread specific instance data. void *env_data; //!< Per call environment data. void *rctx; //!< Resume ctx that a module previously set. @@ -49,14 +49,14 @@ typedef struct { * */ typedef struct { - dl_module_inst_t const *inst; //!< Dynamic loader API handle for the module. + module_instance_t const *inst; //!< Dynamic loader API handle for the module. } module_inst_ctx_t; /** Temporary structure to hold arguments for thread_instantiation calls * */ typedef struct { - dl_module_inst_t const *inst; //!< Dynamic loader API handle for the module. + module_instance_t const *inst; //!< Dynamic loader API handle for the module. ///< Must come first to allow cast between ///< module_inst_ctx. void *thread; //!< Thread instance data. @@ -64,6 +64,16 @@ typedef struct { ///< and timers against. } module_thread_inst_ctx_t; +#ifdef __cplusplus +} +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + DIAG_OFF(unused-function) /** Allocate a module calling ctx on the heap based on an instance ctx * @@ -115,12 +125,12 @@ DIAG_ON(unused-function) * which don't set the required fields. Additional arguments should be added * to this macro whenever the module_ctx_t fields are altered. * - * @param[in] _dl_inst of the module being called. + * @param[in] _mi of the module being called. * @param[in] _thread instance of the module being called. * @param[in] _env_data Call environment data. * @param[in] _rctx Resume ctx (if any). */ -#define MODULE_CTX(_dl_inst, _thread, _env_data, _rctx) &(module_ctx_t){ .inst = _dl_inst, .thread = _thread, .env_data = _env_data, .rctx = _rctx } +#define MODULE_CTX(_mi, _thread, _env_data, _rctx) &(module_ctx_t){ .inst = _mi, .thread = _thread, .env_data = _env_data, .rctx = _rctx } /** Wrapper to create a module_ctx_t as a compound literal from a module_inst_ctx_t * @@ -148,9 +158,9 @@ DIAG_ON(unused-function) * which don't set the required fields. Additional arguments should be added * to this macro whenever the module_inst_ctx_t fields are altered. * - * @param[in] _dl_inst of the module being called.. + * @param[in] _mi of the module being called.. */ -#define MODULE_INST_CTX(_dl_inst) &(module_inst_ctx_t){ .inst = _dl_inst } +#define MODULE_INST_CTX(_mi) &(module_inst_ctx_t){ .inst = _mi } /** Wrapper to create a module_thread_inst_ctx_t as a compound literal * @@ -158,15 +168,15 @@ DIAG_ON(unused-function) * which don't set the required fields. Additional arguments should be added * to this macro whenever the module_thread_inst_ctx_t fields are altered. * - * @param[in] _dl_inst of the module being called. + * @param[in] _mi of the module being called. * @param[in] _thread instance of the module being called. * @param[in] _el Thread specific event list. */ -#define MODULE_THREAD_INST_CTX(_dl_inst, _thread, _el) &(module_thread_inst_ctx_t){ .inst = _dl_inst, .thread = _thread, .el = _el } +#define MODULE_THREAD_INST_CTX(_mi, _thread, _el) &(module_thread_inst_ctx_t){ .inst = _mi, .thread = _thread, .el = _el } /** Wrapper to create a module_inst_ctx_t as a comound listeral from a module_thread_ctx_t * - * Extract the dl_module_inst_t from a module_thread_inst_ctx_t. + * Extract the module_instance_t from a module_thread_inst_ctx_t. * * @param[in] _mctx to extract module_thread_inst_ctx_t from. */ diff --git a/src/lib/server/module_rlm.c b/src/lib/server/module_rlm.c index 59b2cecafd..e9983a3555 100644 --- a/src/lib/server/module_rlm.c +++ b/src/lib/server/module_rlm.c @@ -184,7 +184,7 @@ int module_rlm_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, ch * instantiation order issues. */ inst_name = cf_pair_value(cp); - mi = module_by_name(rlm_modules, NULL, inst_name); + mi = module_instance_by_name(rlm_modules, NULL, inst_name); if (!mi) { cf_log_err(cp, "Unknown module instance \"%s\"", inst_name); @@ -206,7 +206,7 @@ int module_rlm_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, ch parent = tmp; } while (true); - if (unlikely(module_instantiate(module_by_name(rlm_modules, NULL, inst_name)) < 0)) return -1; + if (unlikely(module_instantiate(module_instance_by_name(rlm_modules, NULL, inst_name)) < 0)) return -1; } /* @@ -218,14 +218,14 @@ int module_rlm_sibling_section_find(CONF_SECTION **out, CONF_SECTION *module, ch /* * Check the module instances are of the same type. */ - if (strcmp(cf_section_name1(mi->dl_inst->conf), cf_section_name1(module)) != 0) { + if (strcmp(cf_section_name1(mi->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(mi->dl_inst->conf), cf_section_name1(module)); + cf_section_name1(mi->conf), cf_section_name1(module)); return -1; } - *out = cf_section_find(mi->dl_inst->conf, name, NULL); + *out = cf_section_find(mi->conf, name, NULL); return 1; } @@ -458,13 +458,13 @@ module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_e * Module names are allowed to contain '.' * so we search for the bare module name first. */ - mi = module_by_name(rlm_modules, NULL, name); + mi = module_instance_by_name(rlm_modules, NULL, name); if (mi) { virtual_server_method_t const *allowed_list; if (!method) return mi; - mrlm = module_rlm_from_module(mi->module); + mrlm = module_rlm_from_module(mi->exported); /* * We're not searching for a named method, OR the @@ -614,7 +614,7 @@ module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_e do { *p = '\0'; - mi = module_by_name(rlm_modules, NULL, inst_name); + mi = module_instance_by_name(rlm_modules, NULL, inst_name); if (mi) break; /* @@ -633,7 +633,7 @@ module_instance_t *module_rlm_by_name_and_method(module_method_t *method, call_e return NULL; } - mrlm = module_rlm_from_module(mi->module); + mrlm = module_rlm_from_module(mi->exported); /* * We have a module, but the caller doesn't care about @@ -784,7 +784,7 @@ module_thread_instance_t *module_rlm_thread_by_data(void const *data) module_instance_t *module_rlm_by_name(module_instance_t const *parent, char const *asked_name) { - return module_by_name(rlm_modules, parent, asked_name); + return module_instance_by_name(rlm_modules, parent, asked_name); } /** Create a virtual module. @@ -798,7 +798,7 @@ static int module_rlm_bootstrap_virtual(CONF_SECTION *cs) { char const *name; bool all_same; - module_t const *last = NULL; + module_t const *last = NULL; CONF_ITEM *sub_ci = NULL; CONF_PAIR *cp; module_instance_t *mi; @@ -831,14 +831,14 @@ static int module_rlm_bootstrap_virtual(CONF_SECTION *cs) /* * Ensure that the module doesn't exist. */ - mi = module_by_name(rlm_modules, NULL, name); + mi = module_instance_by_name(rlm_modules, NULL, name); if (mi) { ERROR("Duplicate module \"%s\" in file %s[%d] and file %s[%d]", name, cf_filename(cs), cf_lineno(cs), - cf_filename(mi->dl_inst->conf), - cf_lineno(mi->dl_inst->conf)); + cf_filename(mi->conf), + cf_lineno(mi->conf)); return -1; } @@ -876,8 +876,8 @@ static int module_rlm_bootstrap_virtual(CONF_SECTION *cs) if (all_same) { if (!last) { - last = mi->module; - } else if (last != mi->module) { + last = mi->exported; + } else if (last != mi->exported) { last = NULL; all_same = false; } @@ -1039,16 +1039,15 @@ int modules_rlm_bootstrap(CONF_SECTION *root) continue; } - mi = module_alloc(rlm_modules, NULL, DL_MODULE_TYPE_MODULE, name, dl_module_inst_name_from_conf(subcs)); + mi = module_instance_alloc(rlm_modules, NULL, DL_MODULE_TYPE_MODULE, name, module_instance_name_from_conf(subcs)); if (unlikely(mi == NULL)) { cf_log_perr(subcs, "Failed loading module"); return -1; } - if (module_conf_parse(mi, subcs) < 0) { + if (module_instance_conf_parse(mi, subcs) < 0) { cf_log_perr(subcs, "Failed parsing module config"); - error: talloc_free(mi); return -1; } @@ -1057,7 +1056,10 @@ int modules_rlm_bootstrap(CONF_SECTION *root) * Compile the default "actions" subsection, which includes retries. */ actions = cf_section_find(subcs, "actions", NULL); - if (actions && unlang_compile_actions(&mi->actions, actions, (mi->module->flags & MODULE_TYPE_RETRY) != 0)) goto error; + if (actions && unlang_compile_actions(&mi->actions, actions, (mi->exported->flags & MODULE_TYPE_RETRY) != 0)) { + talloc_free(mi); + return -1; + } } /* diff --git a/src/lib/server/virtual_servers.c b/src/lib/server/virtual_servers.c index 72ded9ebc6..b1b056ae45 100644 --- a/src/lib/server/virtual_servers.c +++ b/src/lib/server/virtual_servers.c @@ -222,14 +222,17 @@ static int namespace_on_read(TALLOC_CTX *ctx, UNUSED void *out, UNUSED void *par * * The instance name is the virtual server name. */ - mi = module_alloc(process_modules, NULL, DL_MODULE_TYPE_PROCESS, - module_name, dl_module_inst_name_from_conf(server_cs)); + mi = module_instance_alloc(process_modules, NULL, DL_MODULE_TYPE_PROCESS, + module_name, module_instance_name_from_conf(server_cs)); talloc_free(module_name); if (mi == NULL) { + error: cf_log_perr(ci, "Failed loading process module"); return -1; } - process = (fr_process_module_t const *)mi->dl_inst->module->common; + if (unlikely(module_instance_conf_parse(mi, mi->conf) < 0)) goto error; + + process = (fr_process_module_t const *)mi->module->exported; if (!*(process->dict)) { cf_log_err(ci, "Process module is invalid - missing namespace dictionary"); talloc_free(mi); @@ -311,7 +314,7 @@ static int namespace_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *paren * fixups here. */ server->process_mi = mi; - server->process_module = (fr_process_module_t const *)mi->dl_inst->module->common; + server->process_module = (fr_process_module_t const *)mi->module->exported; *(module_instance_t const **)out = mi; @@ -324,7 +327,7 @@ static int namespace_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *paren process_cs = cf_section_alloc(server_cs, server_cs, namespace, NULL); } - if (module_conf_parse(mi, process_cs) < 0) { + if (module_instance_conf_parse(mi, process_cs) < 0) { cf_log_perr(ci, "Failed bootstrapping process module"); cf_data_remove(server_cs, module_instance_t, "process_module"); cf_data_remove(server_cs, fr_dict_t, "dict"); @@ -336,7 +339,7 @@ static int namespace_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *paren * Pull the list of sections we need to compile out of * the process module's public struct. */ - add_compile_list(server->process_mi->dl_inst->conf, server->process_module->compile_list, namespace); + add_compile_list(server->process_mi->conf, server->process_module->compile_list, namespace); return 0; } @@ -441,23 +444,19 @@ static int listen_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, if (!inst_name) inst_name = mod_name; MEM(qual_inst_name = talloc_asprintf(NULL, "%s.%s", cf_section_name2(server_cs), inst_name)); - mi = module_alloc(proto_modules, NULL, DL_MODULE_TYPE_PROTO, mod_name, qual_inst_name); + mi = module_instance_alloc(proto_modules, NULL, DL_MODULE_TYPE_PROTO, mod_name, qual_inst_name); talloc_free(qual_inst_name); if (!mi) { + error: cf_log_err(listener_cs, "Failed loading listener"); return -1; } + if (unlikely(module_instance_conf_parse(mi, listener_cs) < 0)) goto error; if (DEBUG_ENABLED4) cf_log_debug(ci, "Loading %s listener into %p", inst_name, out); - if (module_conf_parse(mi, listener_cs) < 0) { - cf_log_perr(ci, "Failed parsing config for listener"); - talloc_free(mi); - return -1; - } - listener->proto_mi = mi; - listener->proto_module = (fr_app_t const *)listener->proto_mi->dl_inst->module->common; + listener->proto_module = (fr_app_t const *)listener->proto_mi->module->exported; cf_data_add(listener_cs, mi, "proto_module", false); return 0; @@ -1364,9 +1363,9 @@ int virtual_servers_open(fr_schedule_t *sc) * to create the fr_listen_t structure. */ if (listener->proto_module->open && - listener->proto_module->open(listener->proto_mi->dl_inst->data, sc, - listener->proto_mi->dl_inst->conf) < 0) { - cf_log_err(listener->proto_mi->dl_inst->conf, + listener->proto_module->open(listener->proto_mi->data, sc, + listener->proto_mi->conf) < 0) { + cf_log_err(listener->proto_mi->conf, "Opening %s I/O interface failed", listener->proto_module->common.name); return -1; @@ -1440,7 +1439,7 @@ int virtual_servers_instantiate(void) fr_dict_t const *dict; fr_virtual_server_t const *vs = virtual_servers[i]; fr_process_module_t const *process = (fr_process_module_t const *) - vs->process_mi->dl_inst->module->common; + vs->process_mi->module->exported; listeners = virtual_servers[i]->listeners; listener_cnt = talloc_array_length(listeners); @@ -1457,7 +1456,7 @@ int virtual_servers_instantiate(void) fr_assert(listener->proto_module != NULL); if (module_instantiate(listener->proto_mi) < 0) { - cf_log_perr(listener->proto_mi->dl_inst->conf, + cf_log_perr(listener->proto_mi->conf, "Failed instantiating listener"); return -1; } @@ -1469,7 +1468,7 @@ int virtual_servers_instantiate(void) * Complete final instantiation of the process module */ if (module_instantiate(virtual_servers[i]->process_mi) < 0) { - cf_log_perr(virtual_servers[i]->process_mi->dl_inst->conf, + cf_log_perr(virtual_servers[i]->process_mi->conf, "Failed instantiating process module"); return -1; } @@ -1489,7 +1488,7 @@ int virtual_servers_instantiate(void) fr_assert(parse_rules.attr.dict_def != NULL); if (virtual_server_compile_sections(server_cs, process->compile_list, &parse_rules, - vs->process_mi->dl_inst->data) < 0) { + vs->process_mi->data) < 0) { return -1; } } diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index fe65fdea4b..e173569659 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -4526,7 +4526,7 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, CONF_ITEM *ci, module_instance_t *inst, module_method_t method, call_env_method_t const *method_env, char const *realname) { - module_rlm_t const *mrlm = module_rlm_from_module(inst->module); + module_rlm_t const *mrlm = module_rlm_from_module(inst->exported); unlang_t *c; unlang_module_t *single; @@ -4537,7 +4537,7 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, (unlang_ctx->rules->attr.dict_def != fr_dict_internal()) && !fr_dict_compatible(*(mrlm->dict), unlang_ctx->rules->attr.dict_def)) { cf_log_err(ci, "The \"%s\" module can only be used with 'namespace = %s'. It cannot be used with 'namespace = %s'.", - inst->module->name, + inst->module->exported->name, fr_dict_root(*mrlm->dict)->name, fr_dict_root(unlang_ctx->rules->attr.dict_def)->name); return NULL; @@ -4548,7 +4548,7 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, * component. */ if (!method) { - cf_log_err(ci, "Failed compiling %s - no method matching calling section found", inst->module->name); + cf_log_err(ci, "Failed compiling %s - no method matching calling section found", inst->name); return NULL; } @@ -4580,16 +4580,16 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, if (method_env) { fr_assert_msg(method_env->inst_size, "Method environment for module %s, method %s %s declared, " "but no inst_size set", - inst->module->name, unlang_ctx->section_name1, unlang_ctx->section_name2); + inst->name, unlang_ctx->section_name1, unlang_ctx->section_name2); if (!unlang_ctx->rules) { - cf_log_err(ci, "Failed compiling %s - no rules", inst->module->name); + cf_log_err(ci, "Failed compiling %s - no rules", inst->name); goto error; } single->call_env = call_env_alloc(single, single->self.name, method_env, - unlang_ctx->rules, inst->dl_inst->conf, + unlang_ctx->rules, inst->conf, unlang_ctx->section_name1, unlang_ctx->section_name2, - single->instance->dl_inst->data); + single->instance->data); if (!single->call_env) { error: talloc_free(c); @@ -4603,7 +4603,7 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, */ if (cf_item_is_section(ci) && !unlang_compile_actions(&c->actions, cf_item_to_section(ci), - (inst->module->flags & MODULE_TYPE_RETRY) != 0)) goto error; + (inst->exported->flags & MODULE_TYPE_RETRY) != 0)) goto error; return c; } diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index 929ecbc1ef..02e8614430 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -46,8 +46,8 @@ typedef struct { unlang_module_fd_event_t fd_read; //!< Function to call when FD is readable. unlang_module_fd_event_t fd_write; //!< Function to call when FD is writable. unlang_module_fd_event_t fd_error; //!< Function to call when FD has errored. - dl_module_inst_t *dl_inst; //!< Module instance to pass to callbacks. - ///< Use dl_inst->data to get instance data. + module_instance_t *mi; //!< Module instance to pass to callbacks. + ///< Use mi->data to get instance data. void *thread; //!< Thread specific module instance. void *env_data; //!< Per call environment data. void const *rctx; //!< rctx data to pass to callbacks. @@ -69,7 +69,7 @@ static void unlang_event_fd_read_handler(UNUSED fr_event_list_t *el, int fd, UNU fr_assert(ev->fd == fd); - ev->fd_read(MODULE_CTX(ev->dl_inst, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); + ev->fd_read(MODULE_CTX(ev->mi, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); } /** Frees an unlang event, removing it from the request's event loop @@ -106,7 +106,7 @@ static void unlang_module_event_timeout_handler(UNUSED fr_event_list_t *el, fr_t { unlang_module_event_t *ev = talloc_get_type_abort(ctx, unlang_module_event_t); - ev->timeout(MODULE_CTX(ev->dl_inst, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, now); + ev->timeout(MODULE_CTX(ev->mi, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, now); talloc_free(ev); } @@ -145,7 +145,7 @@ int unlang_module_timeout_add(request_t *request, unlang_module_timeout_t callba .request = request, .fd = -1, .timeout = callback, - .dl_inst = mc->instance->dl_inst, + .mi = mc->instance, .thread = state->thread, .env_data = state->env_data, .rctx = rctx @@ -196,7 +196,7 @@ static void unlang_event_fd_write_handler(UNUSED fr_event_list_t *el, int fd, UN unlang_module_event_t *ev = talloc_get_type_abort(ctx, unlang_module_event_t); fr_assert(ev->fd == fd); - ev->fd_write(MODULE_CTX(ev->dl_inst, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); + ev->fd_write(MODULE_CTX(ev->mi, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); } /** Call the callback registered for an I/O error event @@ -214,7 +214,7 @@ static void unlang_event_fd_error_handler(UNUSED fr_event_list_t *el, int fd, fr_assert(ev->fd == fd); - ev->fd_error(MODULE_CTX(ev->dl_inst, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); + ev->fd_error(MODULE_CTX(ev->mi, ev->thread, ev->env_data, UNCONST(void *, ev->rctx)), ev->request, fd); } @@ -268,7 +268,7 @@ int unlang_module_fd_add(request_t *request, ev->fd_read = read; ev->fd_write = write; ev->fd_error = error; - ev->dl_inst = mc->instance->dl_inst; + ev->mi = mc->instance; ev->thread = state->thread; ev->env_data = state->env_data; ev->rctx = rctx; @@ -537,7 +537,7 @@ unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); return resume(p_result, - MODULE_CTX(mc->instance->dl_inst, module_thread(mc->instance)->data, + MODULE_CTX(mc->instance, module_thread(mc->instance)->data, state->env_data, rctx), request); } @@ -601,7 +601,7 @@ unlang_action_t unlang_module_yield(request_t *request, */ static inline CC_HINT(always_inline) void safe_lock(module_instance_t *mi) { - if ((mi->module->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_lock(&mi->mutex); + if ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_lock(&mi->mutex); } /* @@ -609,7 +609,7 @@ static inline CC_HINT(always_inline) void safe_lock(module_instance_t *mi) */ static inline CC_HINT(always_inline) void safe_unlock(module_instance_t *mi) { - if ((mi->module->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_unlock(&mi->mutex); + if ((mi->exported->flags & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_unlock(&mi->mutex); } /** Send a signal (usually stop) to a request @@ -637,7 +637,7 @@ static void unlang_module_signal(request_t *request, unlang_stack_frame_t *frame caller = request->module; request->module = mc->instance->name; safe_lock(mc->instance); - if (!(action & state->sigmask)) state->signal(MODULE_CTX(mc->instance->dl_inst, state->thread->data, state->env_data, state->rctx), request, action); + if (!(action & state->sigmask)) state->signal(MODULE_CTX(mc->instance, state->thread->data, state->env_data, state->rctx), request, action); safe_unlock(mc->instance); request->module = caller; @@ -726,7 +726,7 @@ static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *re * Lock is noop unless instance->mutex is set. */ safe_lock(mc->instance); - ua = resume(&state->rcode, MODULE_CTX(mc->instance->dl_inst, state->thread->data, + ua = resume(&state->rcode, MODULE_CTX(mc->instance, state->thread->data, state->env_data, state->rctx), request); safe_unlock(mc->instance); @@ -734,7 +734,7 @@ static unlang_action_t unlang_module_resume(rlm_rcode_t *p_result, request_t *re switch (ua) { case UNLANG_ACTION_STOP_PROCESSING: - RWARN("Module %s or worker signalled to stop processing request", mc->instance->module->name); + RWARN("Module %s or worker signalled to stop processing request", mc->instance->module->exported->name); if (state->p_result) *state->p_result = state->rcode; state->thread->active_callers--; *p_result = state->rcode; @@ -895,7 +895,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, fr_assert(mc); RDEBUG4("[%i] %s - %s (%s)", stack_depth_current(request), __FUNCTION__, - mc->instance->name, mc->instance->module->name); + mc->instance->module->exported->name, mc->instance->name); state->p_result = NULL; @@ -955,7 +955,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, request->module = mc->instance->name; safe_lock(mc->instance); /* Noop unless instance->mutex set */ ua = mc->method(&state->rcode, - MODULE_CTX(mc->instance->dl_inst, state->thread->data, state->env_data, NULL), + MODULE_CTX(mc->instance, state->thread->data, state->env_data, NULL), request); safe_unlock(mc->instance); @@ -967,7 +967,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, * must have been blocked. */ case UNLANG_ACTION_STOP_PROCESSING: - RWARN("Module %s became unblocked", mc->instance->module->name); + RWARN("Module %s became unblocked", mc->instance->name); if (state->p_result) *state->p_result = state->rcode; *p_result = state->rcode; request->module = state->previous_module; diff --git a/src/lib/unlang/xlat_ctx.h b/src/lib/unlang/xlat_ctx.h index abcd2266c4..fe53a67be6 100644 --- a/src/lib/unlang/xlat_ctx.h +++ b/src/lib/unlang/xlat_ctx.h @@ -25,7 +25,7 @@ */ RCSIDH(xlat_ctx_h, "$Id$") -#include + #ifdef __cplusplus extern "C" { @@ -35,41 +35,48 @@ extern "C" { typedef struct xlat_exp_s xlat_exp_t; typedef struct xlat_exp_head_s xlat_exp_head_t; +/* Break dependency loop with module_ctx.h */ +typedef struct xlat_ctx_s xlat_ctx_t; +typedef struct xlat_inst_ctx_s xlat_inst_ctx_t; +typedef struct xlat_thread_inst_ctx_s xlat_thread_inst_ctx_t; + +#include + /** An xlat calling ctx * * This provides optional arguments to xlat functions. */ -typedef struct { +struct xlat_ctx_s { void const *inst; //!< xlat instance data. void *thread; //!< xlat threadinstance data. module_ctx_t const *mctx; //!< Synthesised module calling ctx. void *env_data; //!< Expanded call env data. void *rctx; //!< Resume context. -} xlat_ctx_t; +}; /** An xlat instantiation ctx * * This provides optional arguments to xlat functions. */ -typedef struct { +struct xlat_inst_ctx_s { void *inst; //!< xlat instance data to populate. xlat_exp_t *ex; //!< Tokenized expression to use in expansion. module_inst_ctx_t const *mctx; //!< Synthesised module calling ctx. void *uctx; //!< Passed to the registration function. -} xlat_inst_ctx_t; +}; /** An xlat thread instantiation ctx * * This provides optional arguments to xlat functions. */ -typedef struct { +struct xlat_thread_inst_ctx_s { void const *inst; //!< xlat instance data. void *thread; //!< xlat thread instance data to populate. xlat_exp_t const *ex; //!< Tokenized expression to use in expansion. module_ctx_t const *mctx; //!< Synthesised module calling ctx. fr_event_list_t *el; //!< To register any I/O handlers or timers against. void *uctx; //!< Passed to the registration function. -} xlat_thread_inst_ctx_t; +}; /** Wrapper to create a xlat_ctx_t as a compound literal * diff --git a/src/lib/unlang/xlat_func.c b/src/lib/unlang/xlat_func.c index 2ef35b08de..f36b449147 100644 --- a/src/lib/unlang/xlat_func.c +++ b/src/lib/unlang/xlat_func.c @@ -542,7 +542,7 @@ void xlat_func_unregister(char const *name) talloc_free(c); /* Should also remove from tree */ } -void xlat_func_unregister_module(dl_module_inst_t const *inst) +void xlat_func_unregister_module(module_instance_t const *inst) { xlat_t *c; fr_rb_iter_inorder_t iter; diff --git a/src/lib/unlang/xlat_func.h b/src/lib/unlang/xlat_func.h index 5d12174bf4..f71de8995b 100644 --- a/src/lib/unlang/xlat_func.h +++ b/src/lib/unlang/xlat_func.h @@ -112,7 +112,7 @@ void _xlat_func_thread_instantiate_set(xlat_t const *xlat, void *uctx); void xlat_func_unregister(char const *name); -void xlat_func_unregister_module(dl_module_inst_t const *inst); +void xlat_func_unregister_module(module_instance_t const *inst); /** @hidecallgraph */ int xlat_func_init(void); diff --git a/src/listen/arp/proto_arp.c b/src/listen/arp/proto_arp.c index eafd71b6d7..8f3935592f 100644 --- a/src/listen/arp/proto_arp.c +++ b/src/listen/arp/proto_arp.c @@ -181,23 +181,23 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf li->default_message_size = FR_ARP_PACKET_SIZE; li->num_messages = inst->num_messages; - li->app_io = inst->app_io; - li->app_io_instance = inst->app_io_instance; + li->app_io = (fr_app_io_t const *)inst->io_submodule->module->exported; + li->app_io_instance = inst->io_submodule->data; if (li->app_io->common.thread_inst_size) { li->thread_instance = talloc_zero_array(NULL, uint8_t, li->app_io->common.thread_inst_size); - talloc_set_name(li->thread_instance, "proto_%s_thread_t", inst->app_io->common.name); + talloc_set_name(li->thread_instance, "proto_%s_thread_t", li->app_io->common.name); } /* * Open the raw socket. */ - if (inst->app_io->open(li) < 0) { + if (li->app_io->open(li) < 0) { talloc_free(li); return -1; } fr_assert(li->fd >= 0); - li->name = inst->app_io->get_name(li); + li->name = li->app_io->get_name(li); /* * Watch the directory for changes. @@ -224,16 +224,6 @@ static int mod_open(void *instance, fr_schedule_t *sc, UNUSED CONF_SECTION *conf static int mod_instantiate(module_inst_ctx_t const *mctx) { proto_arp_t *inst = talloc_get_type_abort(mctx->inst->data, proto_arp_t); - CONF_SECTION *conf = mctx->inst->conf; - /* - * Instantiate the I/O module. But DON'T instantiate the - * work submodule. We leave that until later. - */ - if (inst->app_io->common.instantiate && - (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { - cf_log_err(conf, "Instantiation failed for \"%s\"", inst->app_io->common.name); - return -1; - } if (!inst->num_messages) inst->num_messages = 256; @@ -256,7 +246,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_arp_t *inst = talloc_get_type_abort(mctx->inst->data, proto_arp_t); CONF_SECTION *conf = mctx->inst->conf; - dl_module_inst_t *parent_inst; + module_instance_t *parent_inst; /* * Ensure that the server CONF_SECTION is always set. @@ -264,33 +254,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) inst->server_cs = cf_item_to_section(cf_parent(conf)); inst->cs = conf; - parent_inst = cf_data_value(cf_data_find(inst->cs, dl_module_inst_t, "proto_arp")); + parent_inst = cf_data_value(cf_data_find(inst->cs, module_instance_t, "proto_arp")); fr_assert(parent_inst); - if (dl_module_instance(inst->cs, &inst->io_submodule->dl_inst, - parent_inst, - DL_MODULE_TYPE_SUBMODULE, "ethernet", dl_module_inst_name_from_conf(inst->cs)) < 0) { - cf_log_perr(inst->cs, "Failed to load proto_arp_ethernet"); - return -1; - } - - if (dl_module_conf_parse(inst->io_submodule->dl_inst, inst->cs) < 0) { - TALLOC_FREE(inst->io_submodule); - return -1; - } - - /* - * Bootstrap the I/O module - */ - inst->app_io = (fr_app_io_t const *) inst->io_submodule->dl_inst->module->common; - inst->app_io_instance = inst->io_submodule->dl_inst->data; - inst->app_io_conf = conf; - - if (inst->app_io->common.bootstrap && (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { - cf_log_err(inst->app_io_conf, "Bootstrap failed for \"%s\"", inst->app_io->common.name); - return -1; - } - return 0; } diff --git a/src/listen/arp/proto_arp.h b/src/listen/arp/proto_arp.h index 9d84fadc6a..97c243014c 100644 --- a/src/listen/arp/proto_arp.h +++ b/src/listen/arp/proto_arp.h @@ -34,11 +34,7 @@ typedef struct { ///< callback. Broken out into the ///< app_io_* fields below for convenience. - CONF_SECTION *app_io_conf; //!< for the APP IO - fr_app_io_t const *app_io; //!< Easy access to the app_io handle. - void *app_io_instance; //!< Easy access to the app_io instance. - - dl_module_inst_t *app_process; //!< app_process pointer + module_instance_t *app_process; //!< app_process pointer void *process_instance; //!< app_process instance fr_dict_t *dict; //!< root dictionary diff --git a/src/listen/bfd/proto_bfd.c b/src/listen/bfd/proto_bfd.c index c3983cc776..b8a0604ce8 100644 --- a/src/listen/bfd/proto_bfd.c +++ b/src/listen/bfd/proto_bfd.c @@ -341,7 +341,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -377,9 +377,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); - + inst->io.mi = mctx->inst; server = inst->io.server_cs; inst->peers = cf_data_value(cf_data_find(server, fr_rb_tree_t, "peers")); @@ -485,7 +483,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/listen/control/proto_control.c b/src/listen/control/proto_control.c index f53ad59e69..91daa9946d 100644 --- a/src/listen/control/proto_control.c +++ b/src/listen/control/proto_control.c @@ -115,7 +115,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -163,13 +163,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } fr_app_t proto_control = { diff --git a/src/listen/cron/cron.c b/src/listen/cron/cron.c index b546c9ac1d..84f673ce2f 100644 --- a/src/listen/cron/cron.c +++ b/src/listen/cron/cron.c @@ -67,10 +67,10 @@ fr_dict_autoload_t proto_cron_dict[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_cron). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -263,10 +263,10 @@ static fr_table_ptr_sorted_t time_names[] = { }; static size_t time_names_len = NUM_ELEMENTS(time_names); -/** Wrapper around dl_instance which checks the syntax of a cron job +/** Checks the syntax of a cron job * * @param[in] ctx to allocate data in (instance of proto_cron). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. diff --git a/src/listen/cron/proto_cron.c b/src/listen/cron/proto_cron.c index c0cc546f34..4bccfae9f7 100644 --- a/src/listen/cron/proto_cron.c +++ b/src/listen/cron/proto_cron.c @@ -57,10 +57,10 @@ static conf_parser_t const proto_cron_config[] = { CONF_PARSER_TERMINATOR }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_cron). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -197,7 +197,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } /** Bootstrap the application @@ -242,13 +242,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } diff --git a/src/listen/cron/proto_cron_crontab.c b/src/listen/cron/proto_cron_crontab.c index 03d6dfd8cf..cde00debda 100644 --- a/src/listen/cron/proto_cron_crontab.c +++ b/src/listen/cron/proto_cron_crontab.c @@ -269,10 +269,10 @@ static fr_table_ptr_sorted_t time_names[] = { }; static size_t time_names_len = NUM_ELEMENTS(time_names); -/** Wrapper around dl_instance which checks the syntax of a cron job +/** Checks the syntax of a cron job * * @param[in] ctx to allocate data in (instance of proto_cron). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -681,20 +681,9 @@ static char const *mod_name(fr_listen_t *li) static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_cron_crontab_t *inst = talloc_get_type_abort(mctx->inst->data, proto_cron_crontab_t); - CONF_SECTION *conf = mctx->inst->data; - dl_module_inst_t const *dl_inst; - - /* - * Find the dl_module_inst_t holding our instance data - * so we can find out what the parent of our instance - * was. - */ - dl_inst = dl_module_instance_by_data(inst); - fr_assert(dl_inst); - - inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_cron_t); - inst->cs = conf; + inst->parent = talloc_get_type_abort(mctx->inst->parent->data, proto_cron_t); + inst->cs = mctx->inst->conf; return 0; } diff --git a/src/listen/detail/proto_detail.c b/src/listen/detail/proto_detail.c index 1d4d040d75..7c132ca1b7 100644 --- a/src/listen/detail/proto_detail.c +++ b/src/listen/detail/proto_detail.c @@ -29,6 +29,8 @@ #include #include "proto_detail.h" +#include "lib/server/dl_module.h" +#include "lib/server/module.h" extern fr_app_t proto_detail; static int type_parse(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule); @@ -98,10 +100,10 @@ fr_dict_attr_autoload_t proto_detail_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_detail). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -407,7 +409,7 @@ static int mod_open(void *instance, fr_schedule_t *sc, CONF_SECTION *conf) * Testing: allow it to read a "detail.work" file * directly. */ - if (strcmp(inst->io_submodule->dl_inst->module->dl->name, "proto_detail_work") == 0) { + if (strcmp(inst->io_submodule->module->dl->name, "proto_detail_work") == 0) { if (!fr_schedule_listen_add(sc, li)) { talloc_free(li); return -1; @@ -463,7 +465,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) * work submodule. We leave that until later. */ if (inst->app_io->common.instantiate && - (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { + (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule)) < 0)) { cf_log_err(conf, "Instantiation failed for \"%s\"", inst->app_io->common.name); return -1; } @@ -487,7 +489,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * If the IO is "file" and not the worker, instantiate the worker now. */ - if (strcmp(inst->io_submodule->dl_inst->module->dl->name, "proto_detail_work") != 0) { + if (strcmp(inst->io_submodule->module->dl->name, "proto_detail_work") != 0) { if (inst->work_io->common.instantiate && (inst->work_io->common.instantiate(MODULE_INST_CTX(inst->work_submodule)) < 0)) { cf_log_err(inst->work_io_conf, "Instantiation failed for \"%s\"", inst->work_io->common.name); @@ -530,11 +532,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Bootstrap the I/O module */ - inst->app_io = (fr_app_io_t const *) inst->io_submodule->dl_inst->module->common; - inst->app_io_instance = inst->io_submodule->dl_inst->data; - inst->app_io_conf = inst->io_submodule->dl_inst->conf; + inst->app_io = (fr_app_io_t const *) inst->io_submodule->module->exported; + inst->app_io_instance = inst->io_submodule->data; + inst->app_io_conf = inst->io_submodule->conf; - if (inst->app_io->common.bootstrap && (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { + if (inst->app_io->common.bootstrap && (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule)) < 0)) { cf_log_err(inst->app_io_conf, "Bootstrap failed for \"%s\"", inst->app_io->common.name); return -1; } @@ -542,14 +544,14 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * If we're not loading the work submodule directly, then try to load it here. */ - if (strcmp(inst->io_submodule->dl_inst->module->dl->name, "proto_detail_work") != 0) { + if (strcmp(inst->io_submodule->module->dl->name, "proto_detail_work") != 0) { CONF_SECTION *transport_cs; - dl_module_inst_t *parent_inst; + module_instance_t *parent_inst; inst->work_submodule = NULL; transport_cs = cf_section_find(inst->cs, "work", NULL); - parent_inst = cf_data_value(cf_data_find(inst->cs, dl_module_inst_t, "proto_detail")); + parent_inst = cf_data_value(cf_data_find(inst->cs, module_instance_t, "proto_detail")); fr_assert(parent_inst); if (!transport_cs) { @@ -561,31 +563,28 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) } } - if (dl_module_instance(parent_inst, &inst->work_submodule, - parent_inst, - DL_MODULE_TYPE_SUBMODULE, "work", dl_module_inst_name_from_conf(transport_cs)) < 0) { + /* + * This *should* get bootstrapped at some point after this module + * as it's inserted into the three the caller is iterating over. + * + * We might want to revisit this, and use a linked list of modules + * to iterate over instead of a tree, so we can add this to the end + * of that list. + */ + inst->work_submodule = module_instance_alloc(parent_inst->ml, parent_inst, DL_MODULE_TYPE_SUBMODULE, + "work", module_instance_name_from_conf(transport_cs)); + if (inst->work_submodule == NULL) { + error: cf_log_perr(inst->cs, "Failed to load proto_detail_work"); - return -1; - } - - if (dl_module_conf_parse(inst->work_submodule, transport_cs) < 0) { TALLOC_FREE(inst->work_submodule); return -1; } - /* - * Boot strap the work module. - */ - inst->work_io = (fr_app_io_t const *) inst->work_submodule->module->common; + if (module_instance_conf_parse(inst->work_submodule, transport_cs) < 0) goto error; + + inst->work_io = (fr_app_io_t const *) inst->work_submodule->module->exported; inst->work_io_instance = inst->work_submodule->data; inst->work_io_conf = inst->work_submodule->conf; - - if (inst->work_io->common.bootstrap && - (inst->work_io->common.bootstrap(MODULE_INST_CTX(inst->work_submodule)) < 0)) { - cf_log_err(inst->work_io_conf, "Bootstrap failed for \"%s\"", inst->work_io->common.name); - TALLOC_FREE(inst->work_submodule); - return -1; - } } return 0; diff --git a/src/listen/detail/proto_detail.h b/src/listen/detail/proto_detail.h index 795e1f8de7..be402500d8 100644 --- a/src/listen/detail/proto_detail.h +++ b/src/listen/detail/proto_detail.h @@ -49,7 +49,7 @@ typedef struct { CONF_SECTION *app_io_conf; //!< Easy access to the app_io's config section. // proto_detail_app_io_t *app_io_private; //!< Internal interface for proto_radius. - dl_module_inst_t *work_submodule; //!< the worker + module_instance_t *work_submodule; //!< the worker fr_app_io_t const *work_io; //!< Easy access to the app_io handle. void *work_io_instance; //!< Easy access to the app_io instance. diff --git a/src/listen/detail/proto_detail_file.c b/src/listen/detail/proto_detail_file.c index 2917240841..52fccaa31c 100644 --- a/src/listen/detail/proto_detail_file.c +++ b/src/listen/detail/proto_detail_file.c @@ -626,7 +626,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_detail_file_t *inst = talloc_get_type_abort(mctx->inst->data, proto_detail_file_t); CONF_SECTION *conf = mctx->inst->conf; - dl_module_inst_t const *dl_inst; + module_instance_t const *mi; char *p; #ifdef __linux__ @@ -652,12 +652,11 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) #endif /* - * Find the dl_module_inst_t holding our instance data + * Find the module_instance_t holding our instance data * so we can find out what the parent of our instance * was. */ - dl_inst = dl_module_instance_by_data(mctx->inst->data); - fr_assert(dl_inst); + mi = mctx->inst; #ifndef __linux__ /* @@ -667,7 +666,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) #endif FR_INTEGER_BOUND_CHECK("poll_interval", inst->poll_interval, <=, 3600); - inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_detail_t); + inst->parent = talloc_get_type_abort(mi->parent->data, proto_detail_t); inst->cs = conf; inst->directory = p = talloc_strdup(inst, inst->filename); diff --git a/src/listen/detail/proto_detail_work.c b/src/listen/detail/proto_detail_work.c index 4cf913d6e6..dc615b06a2 100644 --- a/src/listen/detail/proto_detail_work.c +++ b/src/listen/detail/proto_detail_work.c @@ -864,17 +864,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_detail_work_t *inst = talloc_get_type_abort(mctx->inst->data, proto_detail_work_t); CONF_SECTION *cs = mctx->inst->conf; - dl_module_inst_t const *dl_inst; + module_instance_t const *mi = mctx->inst; - /* - * Find the dl_module_inst_t holding our instance data - * so we can find out what the parent of our instance - * was. - */ - dl_inst = dl_module_instance_by_data(mctx->inst->data); - fr_assert(dl_inst); - - inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_detail_t); + inst->parent = talloc_get_type_abort(mi->parent->data, proto_detail_t); inst->cs = cs; if (inst->track_progress) { diff --git a/src/listen/dhcpv4/proto_dhcpv4.c b/src/listen/dhcpv4/proto_dhcpv4.c index 0d5f5af813..21e90cf51a 100644 --- a/src/listen/dhcpv4/proto_dhcpv4.c +++ b/src/listen/dhcpv4/proto_dhcpv4.c @@ -101,10 +101,10 @@ fr_dict_attr_autoload_t proto_dhcpv4_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_dhcpv4). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -387,7 +387,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -437,13 +437,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/listen/dhcpv6/proto_dhcpv6.c b/src/listen/dhcpv6/proto_dhcpv6.c index 701c9e2889..5482d823c5 100644 --- a/src/listen/dhcpv6/proto_dhcpv6.c +++ b/src/listen/dhcpv6/proto_dhcpv6.c @@ -101,10 +101,10 @@ fr_dict_attr_autoload_t proto_dhcpv6_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_dhcpv6). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -368,7 +368,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } /** Bootstrap the application @@ -417,13 +417,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/listen/dns/proto_dns.c b/src/listen/dns/proto_dns.c index cc232fbd31..fbf4fe258f 100644 --- a/src/listen/dns/proto_dns.c +++ b/src/listen/dns/proto_dns.c @@ -82,10 +82,10 @@ fr_dict_attr_autoload_t proto_dns_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_dns). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -317,7 +317,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } /** Bootstrap the application @@ -360,13 +360,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/listen/ldap_sync/proto_ldap_sync.c b/src/listen/ldap_sync/proto_ldap_sync.c index f55987cb5b..032657a767 100644 --- a/src/listen/ldap_sync/proto_ldap_sync.c +++ b/src/listen/ldap_sync/proto_ldap_sync.c @@ -257,7 +257,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) * Instantiate the I/O module. */ if (inst->app_io->common.instantiate && - (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { + (inst->app_io->common.instantiate(MODULE_INST_CTX(inst->io_submodule)) < 0)) { cf_log_err(conf, "Instantiation failed for \"%s\"", inst->app_io->common.name); return -1; } @@ -382,12 +382,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * Bootstrap the I/O module */ - inst->app_io = (fr_app_io_t const *) inst->io_submodule->dl_inst->module->common; - inst->app_io_instance = inst->io_submodule->dl_inst->data; - inst->app_io_conf = inst->io_submodule->dl_inst->conf; + inst->app_io = (fr_app_io_t const *) inst->io_submodule->module->exported; + inst->app_io_instance = inst->io_submodule->data; + inst->app_io_conf = inst->io_submodule->conf; if (inst->app_io->common.bootstrap && - (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule->dl_inst)) < 0)) { + (inst->app_io->common.bootstrap(MODULE_INST_CTX(inst->io_submodule)) < 0)) { cf_log_err(inst->app_io_conf, "Bootstrap failed for \"%s\"", inst->app_io->common.name); return -1; } diff --git a/src/listen/ldap_sync/proto_ldap_sync_ldap.c b/src/listen/ldap_sync/proto_ldap_sync_ldap.c index 38f2d8280a..04c077f13d 100644 --- a/src/listen/ldap_sync/proto_ldap_sync_ldap.c +++ b/src/listen/ldap_sync/proto_ldap_sync_ldap.c @@ -1309,12 +1309,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_ldap_sync_ldap_t *inst = talloc_get_type_abort(mctx->inst->data, proto_ldap_sync_ldap_t); CONF_SECTION *conf = mctx->inst->conf; - dl_module_inst_t const *dl_inst; + module_instance_t const *mi = mctx->inst; - dl_inst = dl_module_instance_by_data(inst); - fr_assert(dl_inst); - - inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_ldap_sync_t); + inst->parent = talloc_get_type_abort(mi->parent->data, proto_ldap_sync_t); inst->cs = conf; if (inst->recv_buff_is_set) { diff --git a/src/listen/load/proto_load.c b/src/listen/load/proto_load.c index 6147687c05..daa5c8137b 100644 --- a/src/listen/load/proto_load.c +++ b/src/listen/load/proto_load.c @@ -57,10 +57,10 @@ static conf_parser_t const proto_load_config[] = { CONF_PARSER_TERMINATOR }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_load). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -207,7 +207,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } /** Bootstrap the application @@ -253,13 +253,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } diff --git a/src/listen/load/proto_load_step.c b/src/listen/load/proto_load_step.c index aeaa122096..9c84bf5f6c 100644 --- a/src/listen/load/proto_load_step.c +++ b/src/listen/load/proto_load_step.c @@ -341,17 +341,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) { proto_load_step_t *inst = talloc_get_type_abort(mctx->inst->data, proto_load_step_t); CONF_SECTION *conf = mctx->inst->conf; - dl_module_inst_t const *dl_inst; + module_instance_t const *mi = mctx->inst; - /* - * Find the dl_module_inst_t holding our instance data - * so we can find out what the parent of our instance - * was. - */ - dl_inst = dl_module_instance_by_data(inst); - fr_assert(dl_inst); - - inst->parent = talloc_get_type_abort(dl_inst->parent->data, proto_load_t); + inst->parent = talloc_get_type_abort(mi->parent->data, proto_load_t); inst->cs = conf; FR_INTEGER_BOUND_CHECK("start_pps", inst->load.start_pps, >=, 10); diff --git a/src/listen/radius/proto_radius.c b/src/listen/radius/proto_radius.c index 623d9a1af3..aa39b98fca 100644 --- a/src/listen/radius/proto_radius.c +++ b/src/listen/radius/proto_radius.c @@ -105,13 +105,13 @@ fr_dict_attr_autoload_t proto_radius_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * If we found a Packet-Type = Access-Request CONF_PAIR for example, here's we'd load * the proto_radius_auth module. * * @param[in] ctx to allocate data in (instance of proto_radius). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -459,7 +459,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -515,13 +515,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } /** Get the authentication vector. diff --git a/src/listen/tacacs/proto_tacacs.c b/src/listen/tacacs/proto_tacacs.c index ee67b111b4..131b76b80e 100644 --- a/src/listen/tacacs/proto_tacacs.c +++ b/src/listen/tacacs/proto_tacacs.c @@ -91,13 +91,13 @@ fr_dict_attr_autoload_t proto_tacacs_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * If we found a Packet-Type = Authentication-Start CONF_PAIR for example, here's we'd load * the proto_tacacs_auth module. * * @param[in] ctx to allocate data in (instance of proto_tacacs). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -474,7 +474,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -520,13 +520,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/listen/vmps/proto_vmps.c b/src/listen/vmps/proto_vmps.c index b4a865d46f..9a88706d39 100644 --- a/src/listen/vmps/proto_vmps.c +++ b/src/listen/vmps/proto_vmps.c @@ -87,10 +87,10 @@ fr_dict_attr_autoload_t proto_vmps_dict_attr[] = { { NULL } }; -/** Wrapper around dl_instance which translates the packet-type into a submodule name +/** Translates the packet-type into a submodule name * * @param[in] ctx to allocate data in (instance of proto_vmps). - * @param[out] out Where to write a dl_module_inst_t containing the module handle and instance. + * @param[out] out Where to write a module_instance_t containing the module handle and instance. * @param[in] parent Base structure address. * @param[in] ci #CONF_PAIR specifying the name of the type module. * @param[in] rule unused. @@ -336,7 +336,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) /* * Instantiate the master io submodule */ - return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.instantiate(MODULE_INST_CTX(inst->io.mi)); } @@ -384,13 +384,12 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) /* * We will need this for dynamic clients and connected sockets. */ - inst->io.dl_inst = dl_module_instance_by_data(inst); - fr_assert(inst != NULL); + inst->io.mi = mctx->inst; /* * Bootstrap the master IO handler. */ - return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.dl_inst)); + return fr_master_app_io.common.bootstrap(MODULE_INST_CTX(inst->io.mi)); } static int mod_load(void) diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index e2192ab223..2b41615425 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -116,7 +116,7 @@ static int cache_key_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rul * function, depending on whether the driver calls a custom parsing function. */ if (unlikely((ret = func(ctx, &key_tmpl, t_rules, ci, section_name1, section_name2, - inst->driver_submodule->dl_inst->data, rule)) < 0)) return ret; + inst->driver_submodule->data, rule)) < 0)) return ret; *((tmpl_t **)out) = key_tmpl; /* @@ -157,7 +157,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_submodule->dl_inst->data, request); + return inst->driver->acquire(out, &inst->config, inst->driver_submodule->data, request); } /** Release a handle we previously acquired @@ -168,7 +168,7 @@ static void cache_release(rlm_cache_t const *inst, request_t *request, rlm_cache if (!inst->driver->release) return; if (!handle || !*handle) return; - inst->driver->release(&inst->config, inst->driver_submodule->dl_inst->data, request, *handle); + inst->driver->release(&inst->config, inst->driver_submodule->data, request, *handle); *handle = NULL; } @@ -179,7 +179,7 @@ static int cache_reconnect(rlm_cache_handle_t **handle, rlm_cache_t const *inst, { fr_assert(inst->driver->reconnect); - return inst->driver->reconnect(handle, &inst->config, inst->driver_submodule->dl_inst->data, request); + return inst->driver->reconnect(handle, &inst->config, inst->driver_submodule->data, request); } /** Allocate a cache entry @@ -192,7 +192,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_t *request) { - if (inst->driver->alloc) return inst->driver->alloc(&inst->config, inst->driver_submodule->dl_inst->data, request); + if (inst->driver->alloc) return inst->driver->alloc(&inst->config, inst->driver_submodule->data, request); return talloc_zero(NULL, rlm_cache_entry_t); } @@ -283,7 +283,7 @@ static unlang_action_t cache_find(rlm_rcode_t *p_result, rlm_cache_entry_t **out *out = NULL; for (;;) { - ret = inst->driver->find(&c, &inst->config, inst->driver_submodule->dl_inst->data, request, *handle, key); + ret = inst->driver->find(&c, &inst->config, inst->driver_submodule->data, request, *handle, key); switch (ret) { case CACHE_RECONNECT: RDEBUG2("Reconnecting..."); @@ -317,7 +317,7 @@ static unlang_action_t cache_find(rlm_rcode_t *p_result, rlm_cache_entry_t **out fr_box_time(request->packet->timestamp)); expired: - inst->driver->expire(&inst->config, inst->driver_submodule->dl_inst->data, request, handle, key); + inst->driver->expire(&inst->config, inst->driver_submodule->data, request, handle, key); cache_free(inst, &c); RETURN_MODULE_NOTFOUND; /* Couldn't find a non-expired entry */ } @@ -347,7 +347,7 @@ static unlang_action_t cache_expire(rlm_rcode_t *p_result, rlm_cache_handle_t **handle, fr_value_box_t const *key) { RDEBUG2("Expiring cache entry"); - for (;;) switch (inst->driver->expire(&inst->config, inst->driver_submodule->dl_inst->data, request, *handle, key)) { + for (;;) switch (inst->driver->expire(&inst->config, inst->driver_submodule->data, request, *handle, key)) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; FALL_THROUGH; @@ -384,7 +384,7 @@ static unlang_action_t cache_insert(rlm_rcode_t *p_result, TALLOC_CTX *pool; if ((inst->config.max_entries > 0) && inst->driver->count && - (inst->driver->count(&inst->config, inst->driver_submodule->dl_inst->data, request, handle) > inst->config.max_entries)) { + (inst->driver->count(&inst->config, inst->driver_submodule->data, request, handle) > inst->config.max_entries)) { RWDEBUG("Cache is full: %d entries", inst->config.max_entries); RETURN_MODULE_FAIL; } @@ -523,7 +523,7 @@ skip_maps: for (;;) { cache_status_t ret; - ret = inst->driver->insert(&inst->config, inst->driver_submodule->dl_inst->data, request, *handle, c); + ret = inst->driver->insert(&inst->config, inst->driver_submodule->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -557,7 +557,7 @@ static unlang_action_t cache_set_ttl(rlm_rcode_t *p_result, if (!inst->driver->set_ttl) for (;;) { cache_status_t ret; - ret = inst->driver->insert(&inst->config, inst->driver_submodule->dl_inst->data, request, *handle, c); + ret = inst->driver->insert(&inst->config, inst->driver_submodule->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -579,7 +579,7 @@ static unlang_action_t cache_set_ttl(rlm_rcode_t *p_result, for (;;) { cache_status_t ret; - ret = inst->driver->set_ttl(&inst->config, inst->driver_submodule->dl_inst->data, request, *handle, c); + ret = inst->driver->set_ttl(&inst->config, inst->driver_submodule->data, request, *handle, c); switch (ret) { case CACHE_RECONNECT: if (cache_reconnect(handle, inst, request) == 0) continue; @@ -1462,7 +1462,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) rlm_cache_t *inst = talloc_get_type_abort(mctx->inst->data, rlm_cache_t ); xlat_t *xlat; - inst->driver = (rlm_cache_driver_t const *)inst->driver_submodule->dl_inst->module->common; + inst->driver = (rlm_cache_driver_t const *)inst->driver_submodule->module->exported; /* * Non optional fields and callbacks diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index eadf9012b1..3775f0aa68 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -118,7 +118,7 @@ fr_dict_attr_autoload_t rlm_eap_dict_attr[] = { static unlang_action_t mod_authenticate(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) CC_HINT(nonnull); static unlang_action_t mod_authorize(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request) CC_HINT(nonnull); -/** Wrapper around dl_instance which loads submodules based on type = foo pairs +/** Loads submodules based on type = foo pairs * * @param[in] ctx to allocate data in (instance of rlm_eap_t). * @param[out] out Where to write child conf section to. @@ -180,8 +180,8 @@ static int submodule_parse(TALLOC_CTX *ctx, void *out, void *parent, CONF_SECTION *eap_cs = cf_item_to_section(cf_parent(ci)); module_inst_ctx_t *mctx = MODULE_INST_CTX( - ((dl_module_inst_t *)cf_data_value(cf_data_find(eap_cs, - dl_module_inst_t, "rlm_eap")))); + ((module_instance_t *)cf_data_value(cf_data_find(eap_cs, + module_instance_t, "rlm_eap")))); WARN("Ignoring EAP method %s because we don't have OpenSSL support", name); } return 0; @@ -689,7 +689,7 @@ static unlang_action_t eap_method_select(rlm_rcode_t *p_result, module_ctx_t con (rlm_eap_submodule_t const *)inst->type_identity_submodule[i]->module; eap_type_t ret; - ret = submodule->type_identity(inst->type_identity_submodule[i]->dl_inst->data, + ret = submodule->type_identity(inst->type_identity_submodule[i]->data, eap_session->identity, talloc_array_length(eap_session->identity) - 1); if (ret != FR_EAP_METHOD_INVALID) { @@ -1100,7 +1100,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) if (!submodule_inst) continue; /* Skipped as we don't have SSL support */ - submodule = (rlm_eap_submodule_t const *)submodule_inst->dl_inst->module->common; + submodule = (rlm_eap_submodule_t const *)submodule_inst->module->exported; /* * Add the methods the submodule provides @@ -1123,9 +1123,9 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) * Check for duplicates */ if (inst->methods[method].submodule) { - CONF_SECTION *conf = inst->methods[method].submodule_inst->dl_inst->conf; + CONF_SECTION *conf = inst->methods[method].submodule_inst->conf; - cf_log_err(submodule_inst->dl_inst->conf, + cf_log_err(submodule_inst->conf, "Duplicate EAP-Type %s. Conflicting entry %s[%u]", eap_type2name(method), cf_filename(conf), cf_lineno(conf)); diff --git a/src/modules/rlm_ldap/rlm_ldap.h b/src/modules/rlm_ldap/rlm_ldap.h index d86e8f687a..0ae07cc940 100644 --- a/src/modules/rlm_ldap/rlm_ldap.h +++ b/src/modules/rlm_ldap/rlm_ldap.h @@ -189,7 +189,7 @@ typedef enum { * */ typedef struct { - dl_module_inst_t const *dlinst; + module_instance_t const *dlinst; rlm_ldap_t const *inst; fr_ldap_map_exp_t expanded; fr_ldap_query_t *query; diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index c04c443728..948be03baf 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -344,7 +344,7 @@ static void mod_radius_signal(module_ctx_t const *mctx, request_t *request, fr_s if (!io->signal) return; - io->signal(MODULE_CTX(inst->io_submodule->dl_inst, + io->signal(MODULE_CTX(inst->io_submodule, module_thread(inst->io_submodule)->data, mctx->env_data, mctx->rctx), request, action); } @@ -442,7 +442,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul * return another code which indicates what happened to * the request... */ - ua = inst->io->enqueue(&rcode, &rctx, inst->io_submodule->dl_inst->data, + ua = inst->io->enqueue(&rcode, &rctx, inst->io_submodule->data, module_thread(inst->io_submodule)->data, request); if (ua != UNLANG_ACTION_YIELD) { fr_assert(rctx == NULL); diff --git a/src/modules/rlm_rest/io.c b/src/modules/rlm_rest/io.c index 050cff9c25..fd52816284 100644 --- a/src/modules/rlm_rest/io.c +++ b/src/modules/rlm_rest/io.c @@ -55,13 +55,12 @@ void rest_io_module_signal(module_ctx_t const *mctx, request_t *request, UNUSED */ void rest_io_xlat_signal(xlat_ctx_t const *xctx, request_t *request, fr_signal_t action) { - rlm_rest_t *mod_inst = talloc_get_type_abort(xctx->mctx->inst->data, rlm_rest_t); rlm_rest_thread_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_rest_thread_t); rlm_rest_xlat_rctx_t *our_rctx = talloc_get_type_abort(xctx->rctx, rlm_rest_xlat_rctx_t); fr_curl_io_request_t *randle = talloc_get_type_abort(our_rctx->handle, fr_curl_io_request_t); - rest_io_module_signal(MODULE_CTX(dl_module_instance_by_data(mod_inst), + rest_io_module_signal(MODULE_CTX(xctx->mctx->inst, t, xctx->mctx->env_data, randle), diff --git a/src/modules/rlm_rest/rlm_rest.c b/src/modules/rlm_rest/rlm_rest.c index 7dbe316f97..51f1c2dc73 100644 --- a/src/modules/rlm_rest/rlm_rest.c +++ b/src/modules/rlm_rest/rlm_rest.c @@ -627,7 +627,7 @@ static xlat_action_t rest_xlat(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out, * * @todo We could extract the User-Name and password from the URL string. */ - ret = rest_request_config(MODULE_CTX(dl_module_instance_by_data(inst), t, xctx->env_data, NULL), + ret = rest_request_config(MODULE_CTX(xctx->mctx->inst, t, xctx->env_data, NULL), section, request, randle, section->request.method, section->request.body, uri_vb->vb_strvalue, in_vb ? in_vb->vb_strvalue : NULL); diff --git a/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c b/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c index 0c4627fd45..8d6da1ab54 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_cassandra/rlm_sql_cassandra.c @@ -386,7 +386,7 @@ static int _sql_socket_destructor(rlm_sql_cassandra_conn_t *conn) static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, fr_time_delta_t timeout) { rlm_sql_cassandra_conn_t *conn; - rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_cassandra_t); + rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_cassandra_t); MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_cassandra_conn_t)); talloc_set_destructor(conn, _sql_socket_destructor); @@ -435,7 +435,7 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co static sql_rcode_t sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, char const *query) { rlm_sql_cassandra_conn_t *conn = handle->conn; - rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_cassandra_t); + rlm_sql_cassandra_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_cassandra_t); CassStatement *statement; CassFuture *future; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c index f0c744683b..b14fc5af48 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c @@ -191,7 +191,7 @@ static int mod_load(void) static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t const *config, fr_time_delta_t timeout) { - rlm_sql_mysql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_mysql_t); + rlm_sql_mysql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_mysql_t); rlm_sql_mysql_conn_t *conn; unsigned int connect_timeout = (unsigned int)fr_time_delta_to_sec(timeout); @@ -634,7 +634,7 @@ static size_t sql_warnings(TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen static size_t sql_error(TALLOC_CTX *ctx, sql_log_entry_t out[], size_t outlen, rlm_sql_handle_t *handle, rlm_sql_config_t const *config) { - rlm_sql_mysql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_mysql_t); + rlm_sql_mysql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_mysql_t); rlm_sql_mysql_conn_t *conn = talloc_get_type_abort(handle->conn, rlm_sql_mysql_conn_t); char const *error; size_t i = 0; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c index 13b3f8b2b7..267c612aa2 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_oracle/rlm_sql_oracle.c @@ -276,7 +276,7 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t co { char errbuff[512]; - rlm_sql_oracle_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_oracle_t); + rlm_sql_oracle_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_oracle_t); rlm_sql_oracle_conn_t *conn; MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_oracle_conn_t)); diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c index 40612d83b3..ee26f06a7c 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c @@ -235,7 +235,7 @@ static int _sql_socket_destructor(rlm_sql_postgres_conn_t *conn) static int CC_HINT(nonnull) sql_socket_init(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t const *config, UNUSED fr_time_delta_t timeout) { - rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_postgresql_t); + rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_postgresql_t); rlm_sql_postgres_conn_t *conn; MEM(conn = handle->conn = talloc_zero(handle, rlm_sql_postgres_conn_t)); @@ -265,7 +265,7 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ char const *query) { rlm_sql_postgres_conn_t *conn = handle->conn; - rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_postgresql_t); + rlm_sql_postgresql_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_postgresql_t); fr_time_delta_t timeout = config->query_timeout; fr_time_t start; int sockfd; diff --git a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c index 3ca6339988..8d3d44208b 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c @@ -397,7 +397,7 @@ static sql_rcode_t CC_HINT(nonnull) sql_socket_init(rlm_sql_handle_t *handle, rl UNUSED fr_time_delta_t timeout) { rlm_sql_sqlite_conn_t *conn; - rlm_sql_sqlite_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->dl_inst->data, rlm_sql_sqlite_t); + rlm_sql_sqlite_t *inst = talloc_get_type_abort(handle->inst->driver_submodule->data, rlm_sql_sqlite_t); int status; diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 2227552b11..7986477480 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -1772,7 +1772,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) rlm_sql_escape_uctx_t *uctx; inst->name = mctx->inst->name; /* Need this for functions in sql.c */ - inst->driver = (rlm_sql_driver_t const *)inst->driver_submodule->module; /* Public symbol exported by the submodule */ + inst->driver = (rlm_sql_driver_t const *)inst->driver_submodule->module->exported; /* Public symbol exported by the submodule */ /* * Register the group comparison attribute diff --git a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c index c73cb6ef67..da73b8ac03 100644 --- a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c +++ b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c @@ -507,7 +507,7 @@ static int mod_bootstrap(module_inst_ctx_t const *mctx) return -1; } - if (!talloc_get_type(sql_inst->dl_inst->data, rlm_sql_t)) { + if (!talloc_get_type(sql_inst->data, rlm_sql_t)) { cf_log_err(conf, "\"%s\" is not an instance of rlm_sql", inst->sql_name); return -1; } diff --git a/src/modules/rlm_sqlippool/rlm_sqlippool.c b/src/modules/rlm_sqlippool/rlm_sqlippool.c index 1561166f23..d7de3eb016 100644 --- a/src/modules/rlm_sqlippool/rlm_sqlippool.c +++ b/src/modules/rlm_sqlippool/rlm_sqlippool.c @@ -254,7 +254,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) return -1; } - inst->sql = (rlm_sql_t *) sql->dl_inst->data; + inst->sql = (rlm_sql_t *) sql->data; if (strcmp(talloc_get_name(inst->sql), "rlm_sql_t") != 0) { cf_log_err(conf, "Module \"%s\" is not an instance of the rlm_sql module", @@ -606,7 +606,7 @@ static int call_env_parse(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rule */ sql_inst = module_rlm_by_name(NULL, inst->sql_name); if (!sql_inst) return -1; - sql = talloc_get_type_abort(sql_inst->dl_inst->data, rlm_sql_t); + sql = talloc_get_type_abort(sql_inst->data, rlm_sql_t); /* * Set the sql module instance data as the uctx for escaping diff --git a/src/modules/rlm_tacacs/rlm_tacacs.c b/src/modules/rlm_tacacs/rlm_tacacs.c index 29c8a8cd13..87d4146270 100644 --- a/src/modules/rlm_tacacs/rlm_tacacs.c +++ b/src/modules/rlm_tacacs/rlm_tacacs.c @@ -141,7 +141,7 @@ static void mod_tacacs_signal(module_ctx_t const *mctx, request_t *request, fr_s if (!io->signal) return; - io->signal(MODULE_CTX(inst->io_submodule->dl_inst, + io->signal(MODULE_CTX(inst->io_submodule, module_thread(inst->io_submodule)->data, mctx->env_data, mctx->rctx), request, action); } @@ -175,7 +175,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul * return another code which indicates what happened to * the request... */ - ua = inst->io->enqueue(&rcode, &rctx, inst->io_submodule->dl_inst->data, + ua = inst->io->enqueue(&rcode, &rctx, inst->io_submodule->data, module_thread(inst->io_submodule)->data, request); if (ua != UNLANG_ACTION_YIELD) { fr_assert(rctx == NULL); diff --git a/src/protocols/ethernet/ethernet.c b/src/protocols/ethernet/ethernet.c index 0d464e019e..45774a04e8 100644 --- a/src/protocols/ethernet/ethernet.c +++ b/src/protocols/ethernet/ethernet.c @@ -403,8 +403,6 @@ extern fr_proto_lib_t const libfreeradius_ethernet; fr_proto_lib_t const libfreeradius_ethernet = { .magic = MODULE_MAGIC_INIT, .name = "ethernet", - .inst_size = sizeof(fr_ethernet_proto_ctx_t), - .opt_group = PROTO_OPT_GROUP_CUSTOM | PROTO_OPT_GROUP_L2, .decode = fr_ethernet_decode, -- 2.47.3