The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
dl_module.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 7369f92a77b447ede4d8b194ac7e7b7170c46d0c $
19 *
20 * @file src/lib/server/dl_module.c
21 * @brief Wrappers around dlopen to manage loading modules at runtime.
22 *
23 * @copyright 2016-2019 The FreeRADIUS server project
24 * @copyright 2016-2019 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25 */
26RCSID("$Id: 7369f92a77b447ede4d8b194ac7e7b7170c46d0c $")
27#define _DL_MODULE_PRIVATE 1
28#include <freeradius-devel/server/dl_module.h>
29
30#include <freeradius-devel/server/log.h>
31#include <freeradius-devel/server/global_lib.h>
32#include <freeradius-devel/util/debug.h>
33
34#include <freeradius-devel/util/syserror.h>
35
36#include <pthread.h>
37
38#define DL_INIT_CHECK fr_assert(dl_module_loader)
39
40/** Wrapper struct around dl_loader_t
41 *
42 * Provides space to store instance data.
43 */
45 pthread_mutex_t lock; //!< Protects the module tree when multiple threads are loading modules simultaneously.
46 fr_rb_tree_t *module_tree; //!< Module's dl handles.
47 dl_loader_t *dl_loader; //!< A list of loaded libraries, and symbol to callback mappings.
48};
49
51
52/** Name prefixes matching the types of loadable module
53 */
56 { L("process"), DL_MODULE_TYPE_PROCESS },
57 { L("proto"), DL_MODULE_TYPE_PROTO },
58 { L("rlm"), DL_MODULE_TYPE_MODULE }
59};
61
62static int8_t dl_module_cmp(void const *one, void const *two)
63{
64 dl_module_t const *a = one, *b = two;
65 int ret;
66
67 fr_assert(a->dl);
68 fr_assert(b->dl);
69
70 ret = strcmp(a->dl->name, b->dl->name);
71 return CMP(ret, 0);
72}
73
74/** Find the module's shallowest parent, or the child if no parents are found
75 *
76 * @param[in] child to locate the root for.
77 * @return
78 * - The module's shallowest parent.
79 * - NULL on error.
80 */
81static dl_module_t const *dl_module_root(dl_module_t const *child)
82{
83 dl_module_t const *next;
84
85 for (;;) {
86 next = child->parent;
87 if (!next) break;
88
89 child = next;
90 }
91
92 return child;
93}
94
95/** Return the prefix string for the deepest module
96 *
97 * This is useful for submodules which don't have a prefix of their own.
98 * In this case we need to use the prefix of the shallowest module, which
99 * will be a proto or rlm module.
100 *
101 * @param[in] module to get the prefix for.
102 * @return The prefix string for the shallowest module.
103 */
104static inline CC_HINT(always_inline)
105char const *dl_module_root_prefix_str(dl_module_t const *module)
106{
107 dl_module_t const *root = dl_module_root(module);
108
109 return fr_table_str_by_value(dl_module_type_prefix, root->type, "<INVALID>");
110}
111
112/** Call the load() function in a module's exported structure
113 *
114 * @param[in] dl to call the load function for.
115 * @param[in] symbol UNUSED.
116 * @param[in] ctx UNUSED.
117 * @return
118 * - 0 on success.
119 * - -1 on failure.
120 */
121static int dl_module_onload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
122{
123 dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
124
125 /*
126 * Clear pre-existing errors.
127 */
129
130 if (dl_module->exported->onload) {
131 int ret;
132
133 ret = dl_module->exported->onload();
134 if (ret < 0) {
135#ifndef NDEBUG
136 PERROR("Initialisation failed for module \"%s\" - onload() returned %i",
137 dl_module->exported->name, ret);
138#else
139 PERROR("Initialisation failed for module \"%s\"", dl_module->exported->name);
140#endif
141 return -1;
142 }
143 }
144
145 return 0;
146}
147
148/** Call the unload() function in a module's exported structure
149 *
150 * @param[in] dl to call the unload function for.
151 * @param[in] symbol UNUSED.
152 * @param[in] ctx UNUSED.
153 */
154static void dl_module_unload_func(dl_t const *dl, UNUSED void *symbol, UNUSED void *ctx)
155{
156 dl_module_t *dl_module = talloc_get_type_abort(dl->uctx, dl_module_t);
157
158 /*
159 * common is NULL if we couldn't find the
160 * symbol and are erroring out.
161 */
162 if (dl_module->exported && dl_module->exported->unload) dl_module->exported->unload();
163}
164
165/** Check if the magic number in the module matches the one in the library
166 *
167 * This is used to detect potential ABI issues caused by running with modules which
168 * were built for a different version of the server.
169 *
170 * @param[in] module Common fields from module's exported interface struct.
171 * @returns
172 * - 0 on success.
173 * - -1 if prefix mismatch.
174 * - -2 if version mismatch.
175 * - -3 if commit mismatch.
176 */
178{
179#ifdef HAVE_DLADDR
180 Dl_info dl_info;
181 dladdr(module, &dl_info);
182#endif
183
184 if (MAGIC_PREFIX(module->magic) != MAGIC_PREFIX(RADIUSD_MAGIC_NUMBER)) {
185#ifdef HAVE_DLADDR
186 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
187#endif
188 ERROR("Application and rlm_%s magic number (prefix) mismatch."
189 " application: %x module: %x", module->name,
191 MAGIC_PREFIX(module->magic));
192 return -1;
193 }
194
195 if (MAGIC_VERSION(module->magic) != MAGIC_VERSION(RADIUSD_MAGIC_NUMBER)) {
196#ifdef HAVE_DLADDR
197 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
198#endif
199 ERROR("Application and rlm_%s magic number (version) mismatch."
200 " application: %lx module: %lx", module->name,
201 (unsigned long) MAGIC_VERSION(RADIUSD_MAGIC_NUMBER),
202 (unsigned long) MAGIC_VERSION(module->magic));
203 return -2;
204 }
205
206 if (MAGIC_COMMIT(module->magic) != MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER)) {
207#ifdef HAVE_DLADDR
208 ERROR("Failed loading module rlm_%s from file %s", module->name, dl_info.dli_fname);
209#endif
210 ERROR("Application and rlm_%s magic number (commit) mismatch."
211 " application: %lx module: %lx", module->name,
212 (unsigned long) MAGIC_COMMIT(RADIUSD_MAGIC_NUMBER),
213 (unsigned long) MAGIC_COMMIT(module->magic));
214 return -3;
215 }
216
217 return 0;
218}
219
220/** Decrement the reference count of the dl, eventually freeing it
221 *
222 */
223static int _dl_module_free(dl_module_t *dl_module)
224{
225 /*
226 * Talloc destructors access the talloc chunk after
227 * calling the destructor, which could lead to a race
228 * if the mutex is acquired within the destructor
229 * itself. This unfortunately means that we have to
230 * free modules using a dedicated free function which
231 * locks the dl_module_loader mutex.
232 *
233 * Ensure this module is not being freed using the
234 * normal talloc hierarchy, or with talloc_free().
235 */
236 fr_assert_msg(pthread_mutex_trylock(&dl_module->loader->lock) != 0,
237 "dl_module_loader->lock not held when freeing module, "
238 "use dl_module_free() to free modules, not talloc_free");
239
240 /*
241 * Decrement refcounts, freeing at zero
242 */
243 if (--dl_module->refs > 0) return -1;
244
245 /*
246 * dl is empty if we tried to load it and failed.
247 */
248 if (dl_module->dl) {
249 if (DEBUG_ENABLED4) {
250 DEBUG4("%s unloaded. Handle address %p, symbol address %p", dl_module->dl->name,
251 dl_module->dl->handle, dl_module->exported);
252 } else {
253 DEBUG3("%s unloaded", dl_module->dl->name);
254 }
255 }
256
257 if (dl_module->in_tree) {
259 dl_module->in_tree = false;
260 }
261
262 dl_free(dl_module->dl);
263
264 return 0;
265}
266
267/** Free a dl_module (when there are no more references to it)
268 *
269 * Decrement the reference count for a module, freeing it and unloading the module if there are no
270 * more references.
271 *
272 * @note This must be used to free modules, not talloc_free().
273 *
274 * @return
275 * - 0 on success.
276 * - -1 if the module wasn't freed. This likely means there are more ferences held to it.
277 */
279{
280 int ret;
281 dl_module_loader_t *dl_module_l = dl_module->loader; /* Save this, as dl_module will be free'd */
282
283 pthread_mutex_lock(&dl_module_l->lock);
284 ret = talloc_free(dl_module);
285 pthread_mutex_unlock(&dl_module_l->lock);
286
287 return ret;
288}
289
290/** Load a module library using dlopen() or return a previously loaded module from the cache
291 *
292 * When the dl_module_t is no longer used, talloc_free() may be used to free it.
293 *
294 * When all references to the original dlhandle are freed, dlclose() will be called on the
295 * dlhandle to unload the module.
296 *
297 * @note This function is threadsafe. Multiple callers may attempt to load the same module
298 * at the same time, and the module will only be loaded once, and will not be freed
299 * until all callers have released their references to it. This is useful for dynamic/runtime
300 * loading of modules.
301 *
302 * @param[in] parent The dl_module_t of the parent module, e.g. rlm_sql for rlm_sql_postgresql.
303 * @param[in] name of the module e.g. sql for rlm_sql.
304 * @param[in] type Used to determine module name prefixes. Must be one of:
305 * - DL_MODULE_TYPE_MODULE
306 * - DL_MODULE_TYPE_PROTO
307 * - DL_MODULE_TYPE_SUBMODULE
308 * @return
309 * - Module handle holding dlhandle, and module's public interface structure.
310 * - NULL if module couldn't be loaded, or some other error occurred.
311 */
313{
314 dl_module_t *dl_module = NULL;
315 dl_t *dl = NULL;
316 char *module_name = NULL;
317 dl_module_common_t *common;
318
320
321 if (parent) {
322 module_name = talloc_typed_asprintf(NULL, "%s_%s_%s",
324 parent->exported->name, name);
325 } else {
326 module_name = talloc_typed_asprintf(NULL, "%s_%s",
328 name);
329 }
330
331 if (!module_name) {
332 fr_strerror_const("Out of memory");
333 return NULL;
334 }
335
336 talloc_bstr_tolower(module_name);
337
338 pthread_mutex_lock(&dl_module_loader->lock);
339 /*
340 * If the module's already been loaded, increment the reference count.
341 */
343 &(dl_module_t){ .dl = &(dl_t){ .name = module_name }});
344 if (dl_module) {
345 dl_module->refs++;
346
347 /*
348 * Release the lock, the caller is guaranteed to have a completely
349 * loaded module, which won't be freed out from underneath them until
350 * the reference count drops to zero.
351 */
352 pthread_mutex_unlock(&dl_module_loader->lock);
353 talloc_free(module_name);
354
355 return dl_module;
356 }
357
358 MEM(dl_module = talloc_zero(dl_module_loader, dl_module_t));
359 dl_module->name = talloc_strdup(dl_module, name);
360 dl_module->loader = dl_module_loader;
361 dl_module->parent = parent;
362 dl_module->type = type;
363 dl_module->refs = 1;
364 talloc_set_destructor(dl_module, _dl_module_free); /* Do this late */
365
366 /*
367 * Pass in dl_module as the uctx so that
368 * we can get at it in any callbacks.
369 */
370 dl = dl_by_name(dl_module_loader->dl_loader, module_name, dl_module, false);
371 if (!dl) {
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");
375 error:
376 talloc_free(module_name);
377 talloc_free(dl_module); /* Do not free dl explicitly, it's handled by the destructor */
378 pthread_mutex_unlock(&dl_module_loader->lock);
379 return NULL;
380 }
381 dl_module->dl = dl;
382
383 DEBUG3("%s loaded, checking if it's valid", module_name);
384
385 common = dlsym(dl->handle, module_name);
386 if (!common) {
387 ERROR("Could not find \"%s\" symbol in module: %s", module_name, dlerror());
388 goto error;
389 }
390 dl_module->exported = common;
391
392 /*
393 * Before doing anything else, check if it's sane.
394 */
395 if (dl_module_magic_verify(common) < 0) goto error;
396
397 DEBUG3("%s validated. Handle address %p, symbol address %p", module_name, dl, common);
398
400 PERROR("Failed calling initializers for module \"%s\"", module_name);
401 goto error;
402 }
403
404 DEBUG2("Loaded module %s", module_name);
405
406 /*
407 * Add the module to the dl cache
408 */
409 dl_module->in_tree = fr_rb_insert(dl_module_loader->module_tree, dl_module);
410 if (!dl_module->in_tree) {
411 ERROR("Failed caching module \"%s\"", module_name);
412 goto error;
413 }
414
415 /*
416 * Hold the lock for the entire module loading process.
417 *
418 * This ensures that all the global resources the module has symbol callbacks
419 * registered for, are fully populated, before something else attempts to use
420 * it.
421 */
422 pthread_mutex_unlock(&dl_module_loader->lock);
423
424 talloc_free(module_name);
425
426 return dl_module;
427}
428
430{
431 int ret = 0;
432
433 /*
434 * Lock must not be held when freeing the loader list.
435 */
436 fr_assert_msg(pthread_mutex_trylock(&dl_module_l->lock) == 0,
437 "dl_module_loader->lock held when attempting to free dL_module_loader_t");
438
439 if (fr_rb_num_elements(dl_module_l->module_tree) > 0) {
440#ifndef NDEBUG
442 void *data;
443
444 WARN("Refusing to cleanup dl loader, the following modules are still in use:");
445 for (data = fr_rb_iter_init_inorder(&iter, dl_module_l->module_tree);
446 data;
447 data = fr_rb_iter_next_inorder(&iter)) {
448 dl_module_t *module = talloc_get_type_abort(data, dl_module_t);
449
450 WARN(" %s", module->exported->name);
451 }
452#endif
453 ret = -1;
454 goto finish;
455 }
456
457 /*
458 * Do this as an explicit step, as this free can fail
459 */
460 ret = talloc_free(dl_module_l->dl_loader);
461 if (ret != 0) {
462 PWARN("dl loader not freed");
463 }
464
465finish:
466 if (ret != 0) {
467#ifndef NDEBUG
468 WARN("This may appear as a leak in talloc memory reports");
469#endif
470 } else {
471 dl_module_loader = NULL;
472 }
473
474 pthread_mutex_unlock(&dl_module_l->lock);
475 pthread_mutex_destroy(&dl_module_l->lock);
476
477 return ret;
478}
479
480char const *dl_module_search_path(void)
481{
483}
484
486{
487 return dl_module_l->dl_loader;
488}
489
490/** Wrapper to log errors
491 */
492static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
493{
494 int ret;
495
496 ret = fr_dl_dict_enum_autoload(module, symbol, user_ctx);
497 if (ret < 0) PERROR("Failed autoloading enum value for \"%s\"", module->name);
498
499 return ret;
500}
501
502/** Wrapper to log errors
503 */
504static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
505{
506 int ret;
507
508 ret = fr_dl_dict_attr_autoload(module, symbol, user_ctx);
509 if (ret < 0) PERROR("Failed autoloading attribute for \"%s\"", module->name);
510
511 return ret;
512}
513
514/** Wrapper to log errors
515 */
516static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
517{
518 int ret;
519
520 ret = fr_dl_dict_autoload(module, symbol, user_ctx);
521 if (ret < 0) PERROR("Failed autoloading dictionary for \"%s\"", module->name);
522
523 return ret;
524}
525
526/** Initialise structures needed by the dynamic linker
527 *
528 */
530{
531 if (dl_module_loader) {
532 /*
533 * Allow it to update the search path.
534 */
535 if (dl_search_path_set(dl_module_loader->dl_loader, lib_dir) < 0) {
536 return NULL;
537 }
538
539 return dl_module_loader;
540 }
541
542 dl_module_loader = talloc_zero(NULL, dl_module_loader_t);
543 if (!dl_module_loader) {
544 ERROR("Failed initialising uctx for dl_loader");
545 return NULL;
546 }
547 pthread_mutex_init(&dl_module_loader->lock, NULL);
548
550 if (!dl_module_loader) {
551 PERROR("Failed initialising dl_loader");
552 error:
553 TALLOC_FREE(dl_module_loader);
554 return NULL;
555 }
556 if (lib_dir) dl_search_path_prepend(dl_module_loader->dl_loader, lib_dir);
557
559 dl_module_cmp, NULL);
561 ERROR("Failed initialising dl->module_tree");
562 goto error;
563 }
564
567 ERROR("Failed registering load() callback");
568 goto error;
569 }
570
573 ERROR("Failed registering unload() callback");
574 goto error;
575 }
576
577 /*
578 * Register dictionary autoload callbacks
579 */
581 DL_PRIORITY_DICT_ENUM, "dict_enum", dl_dict_enum_autoload, NULL);
583 DL_PRIORITY_DICT_ATTR, "dict_attr", dl_dict_attr_autoload, NULL);
585 DL_PRIORITY_DICT, "dict", dl_dict_autoload, NULL);
588
589 /*
590 * Register library autoload callbacks for registering
591 * global configuration sections.
592 */
597
598 talloc_set_destructor(dl_module_loader, _dl_module_loader_free);
599
600 DEBUG4("Module linker search path(s)");
601 if (DEBUG_ENABLED4) {
602 char const *env;
603
604#ifdef __APPLE__
605 char buffer[PATH_MAX];
606
607 env = getenv("LD_LIBRARY_PATH");
608 if (env) {
609 DEBUG4("LD_LIBRARY_PATH : %s", env);
610 }
611 env = getenv("DYLD_LIBRARY_PATH");
612 if (env) {
613 DEBUG4("DYLB_LIBRARY_PATH : %s", env);
614 }
615 env = getenv("DYLD_FALLBACK_LIBRARY_PATH");
616 if (env) {
617 DEBUG4("DYLD_FALLBACK_LIBRARY_PATH : %s", env);
618 }
619 env = getcwd(buffer, sizeof(buffer));
620 if (env) {
621 DEBUG4("Current directory : %s", env);
622 }
623#else
624 env = getenv("LD_LIBRARY_PATH");
625 if (env) {
626 DEBUG4("LD_LIBRARY_PATH : %s", env);
627 }
628 DEBUG4("Defaults : /lib:/usr/lib");
629#endif
630 }
631
632 return dl_module_loader;
633}
static int const char char buffer[256]
Definition acutest.h:576
static dl_t * dl
Definition fuzzer.c:42
#define RCSID(id)
Definition build.h:485
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
Definition build.h:112
#define UNUSED
Definition build.h:317
#define NUM_ELEMENTS(_t)
Definition build.h:339
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition debug.h:210
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
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.
Definition dl.c:885
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.
Definition dl.c:384
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.
Definition dl.c:813
char const * dl_search_path(dl_loader_t *dl_loader)
Return current library path.
Definition dl.c:729
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.
Definition dl.c:321
int dl_search_path_set(dl_loader_t *dl_loader, char const *lib_dir)
Set the current library path.
Definition dl.c:788
int dl_free(dl_t const *dl)
"free" a dl handle, possibly actually freeing it, and unloading the library
Definition dl.c:678
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.
Definition dl.c:233
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.
Definition dl.c:470
A dynamic loader.
Definition dl.c:81
void * handle
Handle returned by dlopen.
Definition dl.h:62
void * uctx
API client's opaque data.
Definition dl.h:65
char const * name
Name of the module e.g. sql.
Definition dl.h:61
Module handle.
Definition dl.h:58
#define DL_INIT_CHECK
Definition dl_module.c:38
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.
Definition dl_module.c:81
dl_loader_t * dl_loader
A list of loaded libraries, and symbol to callback mappings.
Definition dl_module.c:47
static int _dl_module_loader_free(dl_module_loader_t *dl_module_l)
Definition dl_module.c:429
static int _dl_module_free(dl_module_t *dl_module)
Decrement the reference count of the dl, eventually freeing it.
Definition dl_module.c:223
fr_table_num_sorted_t const dl_module_type_prefix[]
Name prefixes matching the types of loadable module.
Definition dl_module.c:54
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.
Definition dl_module.c:154
static int8_t dl_module_cmp(void const *one, void const *two)
Definition dl_module.c:62
static int dl_dict_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:516
dl_loader_t * dl_loader_from_module_loader(dl_module_loader_t *dl_module_l)
Definition dl_module.c:485
fr_rb_tree_t * module_tree
Module's dl handles.
Definition dl_module.c:46
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.
Definition dl_module.c:121
pthread_mutex_t lock
Protects the module tree when multiple threads are loading modules simultaneously.
Definition dl_module.c:45
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.
Definition dl_module.c:312
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.
Definition dl_module.c:177
static int dl_dict_attr_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:504
static int dl_dict_enum_autoload(dl_t const *module, void *symbol, void *user_ctx)
Wrapper to log errors.
Definition dl_module.c:492
static char const * dl_module_root_prefix_str(dl_module_t const *module)
Return the prefix string for the deepest module.
Definition dl_module.c:105
size_t dl_module_type_prefix_len
Definition dl_module.c:60
static dl_module_loader_t * dl_module_loader
Definition dl_module.c:50
int dl_module_free(dl_module_t *dl_module)
Free a dl_module (when there are no more references to it)
Definition dl_module.c:278
char const * dl_module_search_path(void)
Definition dl_module.c:480
dl_module_loader_t * dl_module_loader_init(char const *lib_dir)
Initialise structures needed by the dynamic linker.
Definition dl_module.c:529
Wrapper struct around dl_loader_t.
Definition dl_module.c:44
bool _CONST in_tree
Definition dl_module.h:143
dl_t *_CONST dl
Dynamic loader handle.
Definition dl_module.h:122
dl_module_common_t * exported
Symbol exported by the module, containing its public functions, name and behaviour control flags.
Definition dl_module.h:128
dl_module_t const *_CONST parent
of this module.
Definition dl_module.h:124
dl_module_type_t _CONST type
of this module.
Definition dl_module.h:126
dl_module_type_t
Definition dl_module.h:65
@ DL_MODULE_TYPE_PROTO
Protocol module.
Definition dl_module.h:67
@ DL_MODULE_TYPE_SUBMODULE
Driver (or method in the case of EAP)
Definition dl_module.h:69
@ DL_MODULE_TYPE_MODULE
Standard loadable module.
Definition dl_module.h:66
@ DL_MODULE_TYPE_PROCESS
protocol processor.
Definition dl_module.h:68
#define DL_PRIORITY_BOOTSTRAP
Callback priority for bootstrap callback.
Definition dl_module.h:80
#define DL_PRIORITY_DICT_ATTR
Callback priority for attribute resolution.
Definition dl_module.h:77
#define DL_PRIORITY_DICT
Callback priorities.
Definition dl_module.h:76
dl_module_loader_t *_CONST loader
Loader that owns this dl.
Definition dl_module.h:120
#define DL_PRIORITY_LIB
Callback priority for library config.
Definition dl_module.h:79
#define DL_PRIORITY_DICT_ENUM
Callback priority for enum resolution.
Definition dl_module.h:78
unsigned int refs
Number of references to this module.
Definition dl_module.h:135
Fields common to all types of loadable modules.
Definition dl_module.h:108
void global_lib_autofree(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for freeing of "lib" symbols.
Definition global_lib.c:174
int global_lib_auto_instantiate(UNUSED dl_t const *module, void *symbol, UNUSED void *user_ctx)
Callback for creation of "lib" symbols.
Definition global_lib.c:137
#define PERROR(_fmt,...)
Definition log.h:228
#define DEBUG3(_fmt,...)
Definition log.h:266
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
Definition log.h:260
#define PWARN(_fmt,...)
Definition log.h:227
#define DEBUG4(_fmt,...)
Definition log.h:267
talloc_free(reap)
#define fr_assert(_expr)
Definition rad_assert.h:38
#define DEBUG2(fmt,...)
Definition radclient.h:43
#define WARN(fmt,...)
Definition radclient.h:47
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
Definition rb.c:781
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
Definition rb.c:824
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:850
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.
Definition rb.c:577
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
Definition rb.c:626
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
Definition rb.c:741
#define fr_rb_talloc_alloc(_ctx, _type, _data_cmp, _data_free)
Allocs a red black that verifies elements are of a specific talloc type.
Definition rb.h:205
Iterator structure for in-order traversal of an rbtree.
Definition rb.h:321
The main red black tree structure.
Definition rb.h:73
static char const * name
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:488
static void talloc_bstr_tolower(char *str)
Convert a talloced string to lowercase.
Definition talloc.h:128
static fr_slen_t parent
Definition pair.h:845
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition strerror.c:576
#define fr_strerror_const(_msg)
Definition strerror.h:223
#define MAGIC_PREFIX(_x)
Definition version.h:82
#define MAGIC_VERSION(_x)
Definition version.h:83
#define MAGIC_COMMIT(_x)
Definition version.h:84
#define RADIUSD_MAGIC_NUMBER
Definition version.h:81
static fr_slen_t data
Definition value.h:1274