26RCSID(
"$Id: b8a7cdf56fb897b8a00015f3b82d36ba2a8d7951 $")
 
   27#define _DL_MODULE_PRIVATE 1 
   28#include <freeradius-devel/server/dl_module.h> 
   30#include <freeradius-devel/server/log.h> 
   31#include <freeradius-devel/server/global_lib.h> 
   32#include <freeradius-devel/util/debug.h> 
   34#include <freeradius-devel/util/syserror.h> 
   38#define DL_INIT_CHECK fr_assert(dl_module_loader) 
   70        ret = strcmp(a->
dl->
name, b->dl->name);
 
 
  104static inline CC_HINT(always_inline)
 
  133                ret = dl_module->
exported->onload();
 
  136                        PERROR(
"Initialisation failed for module \"%s\" - onload() returned %i",
 
  139                        PERROR(
"Initialisation failed for module \"%s\"", dl_module->
exported->name);
 
 
  181        dladdr(module, &dl_info);
 
  186                ERROR(
"Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
 
  188                ERROR(
"Application and rlm_%s magic number (prefix) mismatch." 
  189                      "  application: %x module: %x", module->name,
 
  197                ERROR(
"Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
 
  199                ERROR(
"Application and rlm_%s magic number (version) mismatch." 
  200                      "  application: %lx module: %lx", module->name,
 
  208                ERROR(
"Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
 
  210                ERROR(
"Application and rlm_%s magic number (commit) mismatch." 
  211                      "  application: %lx module: %lx", module->name,
 
 
  237                      "dl_module_loader->lock not held when freeing module, " 
  238                      "use dl_module_free() to free modules, not talloc_free");
 
  243        if (--dl_module->
refs > 0) 
return -1;
 
  250                        DEBUG4(
"%s unloaded.  Handle address %p, symbol address %p", dl_module->
dl->
name,
 
 
  283        pthread_mutex_lock(&dl_module_l->
lock);
 
  285        pthread_mutex_unlock(&dl_module_l->
lock);
 
 
  316        char                            *module_name = NULL;
 
  343                               &(
dl_module_t){ .dl = &(dl_t){ .name = module_name }});
 
  359        dl_module->name = talloc_strdup(dl_module, 
name);
 
  361        dl_module->parent = 
parent;
 
  362        dl_module->type = 
type;
 
  372                PERROR(
"Failed to link to module \"%s\"", module_name);
 
  373                ERROR(
"Make sure it (and all its dependent libraries!) are in the search path" 
  374                      " of your system's ld");
 
  383        DEBUG3(
"%s loaded, checking if it's valid", module_name);
 
  385        common = dlsym(
dl->
handle, module_name);
 
  387                ERROR(
"Could not find \"%s\" symbol in module: %s", module_name, dlerror());
 
  390        dl_module->exported = common;
 
  397        DEBUG3(
"%s validated.  Handle address %p, symbol address %p", module_name, 
dl, common);
 
  400                PERROR(
"Failed calling initializers for module \"%s\"", module_name);
 
  404        DEBUG2(
"Loaded module %s", module_name);
 
  410        if (!dl_module->in_tree) {
 
  411                ERROR(
"Failed caching module \"%s\"", module_name);
 
 
  437                      "dl_module_loader->lock held when attempting to free dL_module_loader_t");
 
  444                WARN(
"Refusing to cleanup dl loader, the following modules are still in use:");
 
  448                        dl_module_t *
module = talloc_get_type_abort(data, dl_module_t);
 
  450                        WARN(
"  %s", module->exported->name);
 
  462                PWARN(
"dl loader not freed");
 
  468                WARN(
"This may appear as a leak in talloc memory reports");
 
  474        pthread_mutex_unlock(&dl_module_l->
lock);
 
  475        pthread_mutex_destroy(&dl_module_l->
lock);
 
 
  492        if (ret < 0) 
PERROR(
"Failed autoloading enum value for \"%s\"", module->
name);
 
 
  504        if (ret < 0) 
PERROR(
"Failed autoloading attribute for \"%s\"", module->
name);
 
 
  516        if (ret < 0) 
PERROR(
"Failed autoloading dictionary for \"%s\"", module->
name);
 
 
  539                ERROR(
"Failed initialising uctx for dl_loader");
 
  546                PERROR(
"Failed initialising dl_loader");
 
  556                ERROR(
"Failed initialising dl->module_tree");
 
  562                ERROR(
"Failed registering load() callback");
 
  568                ERROR(
"Failed registering unload() callback");
 
  595        DEBUG4(
"Module linker search path(s)");
 
  602                env = getenv(
"LD_LIBRARY_PATH");
 
  604                        DEBUG4(
"LD_LIBRARY_PATH            : %s", env);
 
  606                env = getenv(
"DYLD_LIBRARY_PATH");
 
  608                        DEBUG4(
"DYLB_LIBRARY_PATH          : %s", env);
 
  610                env = getenv(
"DYLD_FALLBACK_LIBRARY_PATH");
 
  612                        DEBUG4(
"DYLD_FALLBACK_LIBRARY_PATH : %s", env);
 
  616                        DEBUG4(
"Current directory          : %s", env);
 
  619                env = getenv(
"LD_LIBRARY_PATH");
 
  621                        DEBUG4(
"LD_LIBRARY_PATH  : %s", env);
 
  623                DEBUG4(
"Defaults         : /lib:/usr/lib");
 
 
static int const char char buffer[256]
#define L(_str)
Helper for initialising arrays of string literals.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
int fr_dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
void fr_dl_dict_autofree(dl_t const *module, void *symbol, void *user_ctx)
int fr_dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
int fr_dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
dl_loader_t * dl_loader_init(TALLOC_CTX *ctx, void *uctx, bool uctx_free, bool defer_symbol_init)
Initialise structures needed by the dynamic linker.
int dl_symbol_free_cb_register(dl_loader_t *dl_loader, unsigned int priority, char const *symbol, dl_unload_t func, void *uctx)
Register a callback to execute when a dl with a particular symbol is unloaded.
int dl_search_path_prepend(dl_loader_t *dl_loader, char const *lib_dir)
Append a new search path component to the library search path.
char const * dl_search_path(dl_loader_t *dl_loader)
Return current library path.
int dl_symbol_init_cb_register(dl_loader_t *dl_loader, unsigned int priority, char const *symbol, dl_onload_t func, void *uctx)
Register a callback to execute when a dl with a particular symbol is first loaded.
int dl_search_path_set(dl_loader_t *dl_loader, char const *lib_dir)
Set the current library path.
int dl_free(dl_t const *dl)
"free" a dl handle, possibly actually freeing it, and unloading the library
int dl_symbol_init(dl_loader_t *dl_loader, dl_t const *dl)
Walk over the registered init callbacks, searching for the symbols they depend on.
dl_t * dl_by_name(dl_loader_t *dl_loader, char const *name, void *uctx, bool uctx_free)
Search for a dl's shared object in various locations.
void * handle
Handle returned by dlopen.
void * uctx
API client's opaque data.
char const  * name
Name of the module e.g. sql.
static dl_module_t const * dl_module_root(dl_module_t const *child)
Find the module's shallowest parent, or the child if no parents are found.
dl_loader_t * dl_loader
A list of loaded libraries, and symbol to callback mappings.
static int _dl_module_loader_free(dl_module_loader_t *dl_module_l)
static int _dl_module_free(dl_module_t *dl_module)
Decrement the reference count of the dl, eventually freeing it.
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
Call the unload() function in a module's exported structure.
static int8_t dl_module_cmp(void const *one, void const *two)
static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
fr_rb_tree_t * module_tree
Module's dl handles.
static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
Call the load() function in a module's exported structure.
pthread_mutex_t lock
Protects the module tree when multiple threads are loading modules simultaneously.
dl_module_t * dl_module_alloc(dl_module_t const *parent, char const *name, dl_module_type_t type)
Load a module library using dlopen() or return a previously loaded module from the cache.
static int dl_module_magic_verify(dl_module_common_t const *module)
Check if the magic number in the module matches the one in the library.
static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
static char const * dl_module_root_prefix_str(dl_module_t const *module)
Return the prefix string for the deepest module.
size_t dl_module_type_prefix_len
static dl_module_loader_t * dl_module_loader
int dl_module_free(dl_module_t *dl_module)
Free a dl_module (when there are no more references to it)
char const * dl_module_search_path(void)
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Wrapper struct around dl_loader_t.
dl_t *_CONST dl
Dynamic loader handle.
dl_module_common_t * exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
dl_module_t const  *_CONST parent
of this module.
dl_module_type_t _CONST type
of this module.
@ DL_MODULE_TYPE_PROTO
Protocol module.
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
@ DL_MODULE_TYPE_PROCESS
protocol processor.
#define DL_PRIORITY_BOOTSTRAP
Callback priority for bootstrap callback.
#define DL_PRIORITY_DICT_ATTR
Callback priority for attribute resolution.
#define DL_PRIORITY_DICT
Callback priorities.
dl_module_loader_t *_CONST loader
Loader that owns this dl.
#define DL_PRIORITY_LIB
Callback priority for library config.
#define DL_PRIORITY_DICT_ENUM
Callback priority for enum resolution.
unsigned int refs
Number of references to this module.
Fields common to all types of loadable modules.
void global_lib_autofree(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for freeing of "lib" symbols.
int global_lib_auto_instantiate(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for creation of "lib" symbols.
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
#define fr_rb_talloc_alloc(_ctx, _type, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Iterator structure for in-order traversal of an rbtree.
The main red black tree structure.
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in a lexicographically sorted array of name to num mappings.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
static void talloc_bstr_tolower(char *str)
Convert a talloced string to lowercase.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
#define fr_strerror_const(_msg)
#define MAGIC_VERSION(_x)
#define RADIUSD_MAGIC_NUMBER