From: Arran Cudbard-Bell Date: Sun, 12 May 2024 23:03:01 +0000 (-0600) Subject: Rework phase masking for lists, and add debug functions X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8541b7c74fd2ea34360d8187536f621aaf2d933c;p=thirdparty%2Ffreeradius-server.git Rework phase masking for lists, and add debug functions --- diff --git a/src/lib/io/master.c b/src/lib/io/master.c index 2e38f06a06e..8432e7dc4ca 100644 --- a/src/lib/io/master.c +++ b/src/lib/io/master.c @@ -2700,6 +2700,7 @@ static int mod_instantiate(module_inst_ctx_t const *mctx) * FIXME - Probably only want to do this for connected sockets? */ inst->clients = module_list_alloc(inst, &module_list_type_thread_local, "clients"); + module_list_mask_set(inst->clients, MODULE_INSTANCE_BOOTSTRAPPED); return 0; } diff --git a/src/lib/server/module.c b/src/lib/server/module.c index cdef176be11..8119f647f3e 100644 --- a/src/lib/server/module.c +++ b/src/lib/server/module.c @@ -542,14 +542,6 @@ typedef struct { ///< for talloc reasons. } mltl_module_instance_t; -/** This causes the module_list code to skip bootstrapping for thread-local modules - */ -static int mltl_mlg_data_add(module_instance_t *mi) -{ - mi->state |= MODULE_INSTANCE_BOOTSTRAPPED; - return 0; -} - static void mltl_mlg_data_del(module_instance_t *mi) { mltl_module_instance_t *mltl_mi = (mltl_module_instance_t *)talloc_get_type_abort(mi, module_instance_t); @@ -579,8 +571,6 @@ static void mltl_thread_data_del(module_thread_instance_t *ti) */ module_list_type_t const module_list_type_thread_local = { .inst_size = sizeof(mltl_module_instance_t), - - .data_add = mltl_mlg_data_add, .data_del = mltl_mlg_data_del, .thread = { @@ -590,6 +580,51 @@ module_list_type_t const module_list_type_thread_local = { } }; +/** Print debugging information for a module + * + * @param[in] mi Module instance to print. + */ +void module_instance_debug(module_instance_t const *mi) +{ + FR_FAULT_LOG("%s (%p) {", mi->name, mi); + FR_FAULT_LOG(" type : %s", fr_table_str_by_value(dl_module_type_prefix, mi->module->type, "")); + if (mi->parent) { + FR_FAULT_LOG(" parent : \"%s\" (%p)", mi->parent->name, mi->parent); + } + FR_FAULT_LOG(" bootstrapped : %s", mi->state & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no"); + FR_FAULT_LOG(" instantiated : %s", mi->state & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no"); + FR_FAULT_LOG(" boot : %p", mi->boot); + FR_FAULT_LOG(" data : %p", mi->data); + FR_FAULT_LOG(" conf : %p", mi->conf); + FR_FAULT_LOG("}"); +} + +/** Print the contents of a module list + * + */ +void module_list_debug(module_list_t const *ml) +{ + module_instance_t const *inst; + fr_rb_iter_inorder_t iter; + + FR_FAULT_LOG("Module list \"%s\" (%p) {", ml->name, ml); + FR_FAULT_LOG(" phase masked:"); + FR_FAULT_LOG(" bootstrap : %s", ml->mask & MODULE_INSTANCE_BOOTSTRAPPED ? "yes" : "no"); + FR_FAULT_LOG(" instantiate : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no"); + FR_FAULT_LOG(" thread : %s", ml->mask & MODULE_INSTANCE_INSTANTIATED ? "yes" : "no"); + FR_FAULT_LOG("}"); + /* + * Modules are printed in the same order + * they would be bootstrapped or inserted + * into the tree. + */ + for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree); + inst; + inst = fr_rb_iter_next_inorder(&iter)) { + module_instance_debug(inst); + } +} + /** Protect module data * * @param[in] pool to protect @@ -1176,15 +1211,15 @@ int module_instantiate(module_instance_t *instance) */ int modules_instantiate(module_list_t const *ml) { - void *instance; + void *inst; fr_rb_iter_inorder_t iter; DEBUG2("#### Instantiating %s modules ####", ml->name); - for (instance = fr_rb_iter_init_inorder(&iter, ml->name_tree); - instance; - instance = fr_rb_iter_next_inorder(&iter)) { - module_instance_t *mi = talloc_get_type_abort(instance, module_instance_t); + for (inst = fr_rb_iter_init_inorder(&iter, ml->name_tree); + inst; + inst = fr_rb_iter_next_inorder(&iter)) { + module_instance_t *mi = talloc_get_type_abort(inst, module_instance_t); if (module_instantiate(mi) < 0) return -1; } @@ -1643,6 +1678,52 @@ static int _module_list_free(module_list_t *ml) return 0; } +/** Should we bootstrap this module instance? + * + * @param[in] mi to check. + * @return + * - true if the module instance should be bootstrapped. + * - false if the module instance has already been bootstrapped. + */ +bool module_instance_skip_bootstrap(module_instance_t *mi) +{ + return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_BOOTSTRAPPED); +} + +/** Should we instantiate this module instance? + * + * @param[in] mi to check. + * @return + * - true if the module instance should be instantiated. + * - false if the module instance has already been instantiated. + */ +bool module_instance_skip_instantiate(module_instance_t *mi) +{ + return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_INSTANTIATED); +} + +/** Should we instantiate this module instance in a new thread? + * + * @param[in] mi to check. + * @return + * - true if the module instance should be instantiated in a new thread. + * - false if the module instance has already been instantiated in a new thread. + */ +bool module_instance_skip_thread_instantiate(module_instance_t *mi) +{ + return ((mi->state | mi->ml->mask) & MODULE_INSTANCE_NO_THREAD_INSTANTIATE); +} + +/** Set a new bootstrap/instantiate state for a list + * + * @param[in] ml To set the state for. + * @param[in] mask New state. + */ +void module_list_mask_set(module_list_t *ml, module_instance_state_t mask) +{ + ml->mask = mask; +} + /** Allocate a new module list * * This is used to instantiate and destroy modules in distinct phases diff --git a/src/lib/server/module.h b/src/lib/server/module.h index 7cd8f42eeac..99e69c96be2 100644 --- a/src/lib/server/module.h +++ b/src/lib/server/module.h @@ -288,7 +288,6 @@ struct module_instance_s { /** @name Module instance state * @{ */ - module_instance_state_t mask; //!< Prevent phases from being executed. module_instance_state_t state; //!< What's been done with this module so far. CONF_SECTION *conf; //!< Module's instance configuration. /** @} */ @@ -321,42 +320,6 @@ struct module_thread_instance_s { uint64_t active_callers; //! number of active callers. i.e. number of current yields }; -/** Should we bootstrap this module instance? - * - * @param[in] mi to check. - * @return - * - true if the module instance should be bootstrapped. - * - false if the module instance has already been bootstrapped. - */ -static inline bool module_instance_skip_bootstrap(module_instance_t *mi) -{ - return ((mi->state | mi->mask) & MODULE_INSTANCE_BOOTSTRAPPED); -} - -/** Should we instantiate this module instance? - * - * @param[in] mi to check. - * @return - * - true if the module instance should be instantiated. - * - false if the module instance has already been instantiated. - */ -static inline bool module_instance_skip_instantiate(module_instance_t *mi) -{ - return ((mi->state | mi->mask) & MODULE_INSTANCE_INSTANTIATED); -} - -/** Should we instantiate this module instance in a new thread? - * - * @param[in] mi to check. - * @return - * - true if the module instance should be instantiated in a new thread. - * - false if the module instance has already been instantiated in a new thread. - */ -static inline bool module_instance_skip_thread_instantiate(module_instance_t *mi) -{ - return ((mi->state | mi->mask) & MODULE_INSTANCE_NO_THREAD_INSTANTIATE); -} - /** Callback to retrieve thread-local data for a module * * @param[in] mi to add data to (use mi->ml for the module list). @@ -371,9 +334,12 @@ typedef module_thread_instance_t *(*module_list_thread_data_get_t)(module_instan * This allows modules to be instantiated and freed in phases, * i.e. proto modules before rlm modules. */ -struct module_list_s { - uint32_t last_number; //!< Last identifier assigned to a module instance. +struct module_list_s +{ char const *name; //!< Friendly list identifier. + module_instance_state_t mask; //!< Prevent phases from being executed. + + uint32_t last_number; //!< Last identifier assigned to a module instance. fr_rb_tree_t *name_tree; //!< Modules indexed by name. fr_rb_tree_t *data_tree; //!< Modules indexed by data. fr_heap_t *inst_heap; //!< Heap of module instances. @@ -413,6 +379,15 @@ int module_submodule_parse(UNUSED TALLOC_CTX *ctx, void *out, void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule) CC_HINT(warn_unused_result); /** @} */ +/** @name Debugging functions + * + * @{ + */ +void module_instance_debug(module_instance_t const *mi) CC_HINT(nonnull); + +void module_list_debug(module_list_t const *ml) CC_HINT(nonnull); + /** @} */ + /** @name Module and module thread lookup * * @{ @@ -491,6 +466,18 @@ extern module_list_type_t const module_list_type_global; //!< Initialise a glob extern module_list_type_t const module_list_type_thread_local; //!< Initialise a thread-local module, which is only used in a single thread. /** @} */ +/** @name Control which phases are skipped (if any) + * @{ + */ +bool module_instance_skip_bootstrap(module_instance_t *mi); + +bool module_instance_skip_instantiate(module_instance_t *mi); + +bool module_instance_skip_thread_instantiate(module_instance_t *mi); + +void module_list_mask_set(module_list_t *ml, module_instance_state_t mask); +/** @} */ + module_list_t *module_list_alloc(TALLOC_CTX *ctx, module_list_type_t const *type, char const *name) CC_HINT(nonnull(2,3)) CC_HINT(warn_unused_result); diff --git a/src/lib/server/module_rlm.c b/src/lib/server/module_rlm.c index c9b997054ef..a5658c93569 100644 --- a/src/lib/server/module_rlm.c +++ b/src/lib/server/module_rlm.c @@ -74,6 +74,14 @@ char const *section_type_value[MOD_COUNT] = { */ static module_list_t *rlm_modules; +/** Print information on all loaded modules + * + */ +void module_rlm_list_debug(void) +{ + module_list_debug(rlm_modules); +} + /** Initialise a module specific exfile handle * * @see exfile_init diff --git a/src/lib/server/module_rlm.h b/src/lib/server/module_rlm.h index cdc637f50b2..0cb00f71f57 100644 --- a/src/lib/server/module_rlm.h +++ b/src/lib/server/module_rlm.h @@ -47,6 +47,12 @@ static inline module_rlm_t const *module_rlm_from_module(module_t const *module) return (module_rlm_t const *)module; } +/** @name Debug functions + * @{ + */ +void module_rlm_list_debug(void); +/** @} */ + /** @name Convenience wrappers around other internal APIs to make them easier to instantiate with modules * * @{ diff --git a/src/lib/server/virtual_servers.c b/src/lib/server/virtual_servers.c index 3f8d3f44228..5a7e2faae47 100644 --- a/src/lib/server/virtual_servers.c +++ b/src/lib/server/virtual_servers.c @@ -162,6 +162,22 @@ const conf_parser_t virtual_servers_config[] = { CONF_PARSER_TERMINATOR }; +/** Print all the loaded listener instances + * + */ +void virtual_server_listen_debug(void) +{ + module_list_debug(proto_modules); +} + +/** Print all the loaded process module instances + * + */ +void virtual_server_process_debug(void) +{ + module_list_debug(process_modules); +} + /** Generic conf_parser_t func for loading drivers * */ diff --git a/src/lib/server/virtual_servers.h b/src/lib/server/virtual_servers.h index 821afe3e91c..445872ed85c 100644 --- a/src/lib/server/virtual_servers.h +++ b/src/lib/server/virtual_servers.h @@ -36,6 +36,15 @@ extern "C" { extern const conf_parser_t virtual_servers_config[]; extern const conf_parser_t virtual_servers_on_read_config[]; + +/** @name Debug functions + * @{ + */ +void virtual_server_listen_debug(void); + +void virtual_server_process_debug(void); +/** @} */ + /** @name Callbacks for dealing with transports * * @{