]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Rework phase masking for lists, and add debug functions
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 12 May 2024 23:03:01 +0000 (17:03 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 13 May 2024 13:42:00 +0000 (07:42 -0600)
src/lib/io/master.c
src/lib/server/module.c
src/lib/server/module.h
src/lib/server/module_rlm.c
src/lib/server/module_rlm.h
src/lib/server/virtual_servers.c
src/lib/server/virtual_servers.h

index 2e38f06a06e08218ff2c37941fedb0ce9ccb3a46..8432e7dc4ca5d2bfbf0f04060721ccca67b85033 100644 (file)
@@ -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;
 }
index cdef176be114b69e8a6cb11a7c6f1fd667a94452..8119f647f3e4ba01d8062d3a1695143f255ace90 100644 (file)
@@ -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, "<invalid>"));
+       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
index 7cd8f42eeacf357497a8a65017192a7361252b8d..99e69c96be2dfff6823e09b3b3ccc5bfb272e74d 100644 (file)
@@ -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);
 
index c9b997054ef4def67deb5335abe9538b1cc13e8b..a5658c93569e73089d33439a28cd1513f766fe1f 100644 (file)
@@ -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
index cdc637f50b2be38ef402b55f44d890b0f8486617..0cb00f71f57222a825552144e8eb51dc5a45381a 100644 (file)
@@ -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
  *
  * @{
index 3f8d3f44228ec97dd62f896fbcc0580412459d48..5a7e2faae47b1ad6df6a479079a7d8684675aba7 100644 (file)
@@ -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
  *
  */
index 821afe3e91ca19c45e2a2830f388539f5d3bb4e4..445872ed85c009efd9066bda7df5fb339f5d7ccd 100644 (file)
@@ -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
  *
  * @{