Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
loader.c File Reference

Module Loader. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <dirent.h>
#include "asterisk/dlinkedlists.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/io.h"
#include "asterisk/lock.h"
#include "asterisk/vector.h"
#include "asterisk/app.h"
#include "asterisk/test.h"
#include "asterisk/cli.h"
#include <dlfcn.h>
#include "asterisk/md5.h"
#include "asterisk/utils.h"
Include dependency graph for loader.c:

Go to the source code of this file.

Data Structures

struct  ast_module
 
struct  ast_module_user
 
struct  load_order
 
struct  load_order_entry
 
struct  load_results_map
 
struct  load_retries
 
struct  loadupdate
 
struct  module_list
 
struct  module_load_word
 
struct  module_user_list
 
struct  reload_queue
 
struct  reload_queue_item
 
struct  updaters
 

Macros

#define AST_MODULE_LOAD_UNKNOWN_STRING   "Unknown" /* Status string for unknown load status */
 
#define RTLD_LOCAL   0
 
#define RTLD_NOW   0
 
#define STR_APPEND_TEXT(txt, str)
 

Functions

struct ast_module__ast_module_ref (struct ast_module *mod, const char *file, int line, const char *func)
 
struct ast_module__ast_module_running_ref (struct ast_module *mod, const char *file, int line, const char *func)
 
void __ast_module_shutdown_ref (struct ast_module *mod, const char *file, int line, const char *func)
 
void __ast_module_unref (struct ast_module *mod, const char *file, int line, const char *func)
 
struct ast_module_user__ast_module_user_add (struct ast_module *mod, struct ast_channel *chan)
 
void __ast_module_user_hangup_all (struct ast_module *mod)
 
void __ast_module_user_remove (struct ast_module *mod, struct ast_module_user *u)
 
static struct load_order_entryadd_to_load_order (const char *resource, struct load_order *load_order, int required, int preload, int builtin)
 
static int alpha_module_list_create (struct module_vector *alpha_module_list)
 
int ast_load_resource (const char *resource_name)
 Load a module. More...
 
int ast_loader_register (int(*v)(void))
 Add a procedure to be run when modules have been updated. More...
 
int ast_loader_unregister (int(*v)(void))
 Remove a procedure to be run when modules are updated. More...
 
int ast_module_check (const char *name)
 Check if module exists. More...
 
char * ast_module_helper (const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
 Match modules names for the Asterisk cli. More...
 
const char * ast_module_name (const struct ast_module *mod)
 Get the name of a module. More...
 
void ast_module_register (const struct ast_module_info *info)
 
enum ast_module_reload_result ast_module_reload (const char *name)
 Reload asterisk modules. More...
 
const char * ast_module_support_level_to_string (enum ast_module_support_level support_level)
 
void ast_module_unregister (const struct ast_module_info *info)
 
void ast_process_pending_reloads (void)
 Process reload requests received during startup. More...
 
int ast_unload_resource (const char *resource_name, enum ast_module_unload_mode force)
 Unload a module. More...
 
int ast_update_module_list (int(*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level), const char *like)
 Ask for a list of modules, descriptions, use counts and status. More...
 
int ast_update_module_list_condition (int(*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level, void *data, const char *condition), const char *like, void *data, const char *condition)
 Ask for a list of modules, descriptions, use counts and status. More...
 
int ast_update_module_list_data (int(*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level, void *data), const char *like, void *data)
 Ask for a list of modules, descriptions, use counts and status. More...
 
void ast_update_use_count (void)
 Notify when usecount has been changed. More...
 
 AST_VECTOR (module_vector, struct ast_module *)
 
static struct ast_modulefind_resource (const char *resource, int do_lock)
 
static char * get_name_from_resource (const char *resource)
 
static unsigned int inspect_module (const struct ast_module *mod)
 
static int is_module_loaded (const char *resource_name)
 Check to see if the given resource is loaded. More...
 
static int key_matches (const unsigned char *key1, const unsigned char *key2)
 
static struct ast_moduleload_dlopen (const char *resource_in, const char *so_ext, const char *filename, int flags, unsigned int suppress_logging)
 
static int load_dlopen_missing (struct ast_str **list, struct ast_vector_string *deps)
 
static struct ast_moduleload_dynamic_module (const char *resource_in, unsigned int suppress_logging)
 
int load_modules (void)
 
static enum ast_module_load_result load_resource (const char *resource_name, unsigned int suppress_logging, struct module_vector *module_priorities, int required, int preload)
 
static int load_resource_list (struct load_order *load_order, int *mod_count)
 
static int loader_builtin_init (struct load_order *load_order)
 
static int loader_config_init (struct load_order *load_order)
 
static const char * loadresult2str (enum ast_module_load_result result)
 
static void logged_dlclose (const char *name, void *lib)
 dlclose(), with failure logging. More...
 
static int module_deps_missing_recursive (struct ast_module *mod, struct module_vector *missingdeps)
 Recursively find required dependencies that are not running. More...
 
static int module_deps_process_reqlist (struct ast_module *mod, struct ast_vector_string *vec, struct ast_vector_const_string *missing, int ref_enhancers, int isoptional)
 
static int module_deps_reference (struct ast_module *mod, struct ast_vector_const_string *missing)
 
static void module_destroy (struct ast_module *mod)
 
static void module_load_error (const char *fmt,...)
 
static void module_load_helper (const char *word)
 
static int module_load_helper_on_file (const char *dir_name, const char *filename, void *obj)
 
static int module_matches_helper_type (struct ast_module *mod, enum ast_module_helper_type type)
 
static int module_post_register (struct ast_module *mod)
 
static int module_reffed_deps_add (struct ast_module *mod, struct ast_module *dep, struct ast_vector_const_string *missing)
 
static int module_reffed_deps_add_dep_enhancers (struct ast_module *mod, struct ast_module *dep, struct ast_vector_const_string *missing)
 
static int module_vector_cmp (struct ast_module *a, struct ast_module *b)
 
static int module_vector_strcasecmp (struct ast_module *a, struct ast_module *b)
 
int modules_shutdown (void)
 
static int printdigest (const unsigned char *d)
 
static void publish_load_message (const char *name, enum ast_module_load_result result)
 
static void publish_load_message_type (const char *type, const char *name, const char *status)
 
static void publish_reload_message (const char *name, enum ast_module_reload_result result)
 
static void publish_unload_message (const char *name, const char *status)
 
static void queue_reload_request (const char *module)
 
static int resource_list_recursive_decline (struct module_vector *resources, struct ast_module *mod, struct ast_str **printmissing)
 
static size_t resource_name_baselen (const char *name)
 
static int resource_name_match (const char *name1, size_t baselen1, const char *name2)
 
static enum ast_module_load_result start_resource (struct ast_module *mod)
 
static enum ast_module_load_result start_resource_attempt (struct ast_module *mod, int *count)
 
static int start_resource_list (struct module_vector *resources, int *mod_count)
 
static void unload_dynamic_module (struct ast_module *mod)
 
static int verify_key (const unsigned char *key)
 

Variables

static char buildopt_sum [33] = AST_BUILDOPT_SUM
 
static struct module_list builtin_module_list
 
static int do_full_reload = 0
 
static const unsigned char expected_key []
 
static const struct load_results_map load_results []
 
static unsigned int loader_ready
 
static struct module_list module_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static int modules_loaded
 Internal flag to indicate all modules have been initially loaded. More...
 
static struct reload_queue reload_queue = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static ast_mutex_t reloadlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct ast_module *volatile resource_being_loaded
 
static struct ast_strstartup_error_builder
 
static struct ast_vector_string startup_errors
 
const char * support_level_map []
 
static struct updaters updaters = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 

Detailed Description

Module Loader.

Author
Mark Spencer marks[email protected][email protected][email protected]digiu[email protected]m.co[email protected]m
Kevin P. Fleming kpfle[email protected]ming[email protected]@digi[email protected]um.c[email protected]om
Luigi Rizzo rizzo[email protected]@ici[email protected]r.org
  • See ModMngMnt

Definition in file loader.c.

Macro Definition Documentation

◆ AST_MODULE_LOAD_UNKNOWN_STRING

#define AST_MODULE_LOAD_UNKNOWN_STRING   "Unknown" /* Status string for unknown load status */

Definition at line 351 of file loader.c.

Referenced by loadresult2str().

◆ RTLD_LOCAL

#define RTLD_LOCAL   0

Definition at line 124 of file loader.c.

Referenced by load_dlopen(), and load_dynamic_module().

◆ RTLD_NOW

#define RTLD_NOW   0

Definition at line 120 of file loader.c.

Referenced by load_dynamic_module().

◆ STR_APPEND_TEXT

#define STR_APPEND_TEXT (   txt,
  str 
)
Value:
ast_str_append(str, 0, "%s%s", \
ast_str_strlen(*(str)) > 0 ? ", " : "", \
txt)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * str
Definition: app_jack.c:147
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688

Used with AST_VECTOR_CALLBACK_VOID to create a comma separated list of module names for error messages.

Definition at line 144 of file loader.c.

Referenced by load_dlopen_missing(), resource_list_recursive_decline(), and start_resource_list().

Function Documentation

◆ __ast_module_ref()

struct ast_module* __ast_module_ref ( struct ast_module mod,
const char *  file,
int  line,
const char *  func 
)

Definition at line 2698 of file loader.c.

References __ao2_ref(), ast_atomic_fetchadd_int(), ast_update_use_count(), NULL, ast_module::ref_debug, and ast_module::usecount.

Referenced by __ast_module_running_ref(), and __ast_module_shutdown_ref().

2699 {
2700  if (!mod) {
2701  return NULL;
2702  }
2703 
2704  if (mod->ref_debug) {
2705  __ao2_ref(mod->ref_debug, +1, "", file, line, func);
2706  }
2707 
2708  ast_atomic_fetchadd_int(&mod->usecount, +1);
2710 
2711  return mod;
2712 }
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
int usecount
Definition: loader.c:300
#define NULL
Definition: resample.c:96
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition: astobj2.c:498
void * ref_debug
Definition: loader.c:296

◆ __ast_module_running_ref()

struct ast_module* __ast_module_running_ref ( struct ast_module mod,
const char *  file,
int  line,
const char *  func 
)

Definition at line 2714 of file loader.c.

References __ast_module_ref(), ast_module::flags, NULL, and ast_module::running.

2716 {
2717  if (!mod || !mod->flags.running) {
2718  return NULL;
2719  }
2720 
2721  return __ast_module_ref(mod, file, line, func);
2722 }
unsigned int running
Definition: loader.c:320
#define NULL
Definition: resample.c:96
struct ast_module * __ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
Definition: loader.c:2698
struct ast_module::@398 flags

◆ __ast_module_shutdown_ref()

void __ast_module_shutdown_ref ( struct ast_module mod,
const char *  file,
int  line,
const char *  func 
)

Definition at line 2724 of file loader.c.

References __ast_module_ref(), ast_module::flags, and ast_module::keepuntilshutdown.

2725 {
2726  if (!mod || mod->flags.keepuntilshutdown) {
2727  return;
2728  }
2729 
2730  __ast_module_ref(mod, file, line, func);
2731  mod->flags.keepuntilshutdown = 1;
2732 }
unsigned int keepuntilshutdown
Definition: loader.c:324
struct ast_module * __ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
Definition: loader.c:2698
struct ast_module::@398 flags

◆ __ast_module_unref()

void __ast_module_unref ( struct ast_module mod,
const char *  file,
int  line,
const char *  func 
)

Definition at line 2734 of file loader.c.

References __ao2_ref(), ast_atomic_fetchadd_int(), ast_update_use_count(), ast_module::ref_debug, and ast_module::usecount.

2735 {
2736  if (!mod) {
2737  return;
2738  }
2739 
2740  if (mod->ref_debug) {
2741  __ao2_ref(mod->ref_debug, -1, "", file, line, func);
2742  }
2743 
2744  ast_atomic_fetchadd_int(&mod->usecount, -1);
2746 }
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
int usecount
Definition: loader.c:300
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition: astobj2.c:498
void * ref_debug
Definition: loader.c:296

◆ __ast_module_user_add()

struct ast_module_user* __ast_module_user_add ( struct ast_module mod,
struct ast_channel chan 
)

Definition at line 800 of file loader.c.

References ao2_ref, ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_update_use_count(), ast_module_user::chan, NULL, ast_module::ref_debug, ast_module::usecount, and ast_module::users.

Referenced by ast_func_read(), ast_func_read2(), ast_func_write(), and pbx_exec().

801 {
802  struct ast_module_user *u;
803 
804  u = ast_calloc(1, sizeof(*u));
805  if (!u) {
806  return NULL;
807  }
808 
809  u->chan = chan;
810 
811  AST_LIST_LOCK(&mod->users);
812  AST_LIST_INSERT_HEAD(&mod->users, u, entry);
813  AST_LIST_UNLOCK(&mod->users);
814 
815  if (mod->ref_debug) {
816  ao2_ref(mod->ref_debug, +1);
817  }
818 
820 
822 
823  return u;
824 }
struct module_user_list users
Definition: loader.c:302
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int usecount
Definition: loader.c:300
#define NULL
Definition: resample.c:96
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_channel * chan
Definition: loader.c:128
void * ref_debug
Definition: loader.c:296
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Definition: search.h:40

◆ __ast_module_user_hangup_all()

void __ast_module_user_hangup_all ( struct ast_module mod)

Definition at line 853 of file loader.c.

References ao2_ref, ast_atomic_fetchadd_int(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_update_use_count(), ast_module_user::chan, ast_module::ref_debug, ast_module::usecount, and ast_module::users.

Referenced by ast_unload_resource().

854 {
855  struct ast_module_user *u;
856 
857  AST_LIST_LOCK(&mod->users);
858  while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
859  if (u->chan) {
861  }
862 
863  if (mod->ref_debug) {
864  ao2_ref(mod->ref_debug, -1);
865  }
866 
868  ast_free(u);
869  }
870  AST_LIST_UNLOCK(&mod->users);
871 
873 }
struct module_user_list users
Definition: loader.c:302
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int usecount
Definition: loader.c:300
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ao2_ref(o, delta)
Definition: astobj2.h:464
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_channel * chan
Definition: loader.c:128
void * ref_debug
Definition: loader.c:296
#define ast_free(a)
Definition: astmm.h:182
Definition: search.h:40

◆ __ast_module_user_remove()

void __ast_module_user_remove ( struct ast_module mod,
struct ast_module_user u 
)

Definition at line 826 of file loader.c.

References ao2_ref, ast_atomic_fetchadd_int(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_update_use_count(), ast_module::ref_debug, ast_module::usecount, and ast_module::users.

Referenced by ast_func_read(), ast_func_read2(), ast_func_write(), and pbx_exec().

827 {
828  if (!u) {
829  return;
830  }
831 
832  AST_LIST_LOCK(&mod->users);
833  u = AST_LIST_REMOVE(&mod->users, u, entry);
834  AST_LIST_UNLOCK(&mod->users);
835  if (!u) {
836  /*
837  * Was not in the list. Either a bad pointer or
838  * __ast_module_user_hangup_all() has been called.
839  */
840  return;
841  }
842 
843  if (mod->ref_debug) {
844  ao2_ref(mod->ref_debug, -1);
845  }
846 
848  ast_free(u);
849 
851 }
struct module_user_list users
Definition: loader.c:302
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int usecount
Definition: loader.c:300
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:855
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void * ref_debug
Definition: loader.c:296
#define ast_free(a)
Definition: astmm.h:182
Definition: search.h:40

◆ add_to_load_order()

static struct load_order_entry* add_to_load_order ( const char *  resource,
struct load_order load_order,
int  required,
int  preload,
int  builtin 
)
static

Definition at line 1842 of file loader.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdup, load_order_entry::builtin, NULL, order, load_order_entry::preload, load_order_entry::required, load_order_entry::resource, resource_name_baselen(), and resource_name_match().

Referenced by loader_builtin_init(), and loader_config_init().

1843 {
1844  struct load_order_entry *order;
1845  size_t resource_baselen = resource_name_baselen(resource);
1846 
1847  AST_LIST_TRAVERSE(load_order, order, entry) {
1848  if (!resource_name_match(resource, resource_baselen, order->resource)) {
1849  /* Make sure we have the proper setting for the required field
1850  (we might have both load= and required= lines in modules.conf) */
1851  order->required |= required;
1852  order->preload |= preload;
1853  return order;
1854  }
1855  }
1856 
1857  order = ast_calloc(1, sizeof(*order));
1858  if (!order) {
1859  return NULL;
1860  }
1861 
1862  order->resource = ast_strdup(resource);
1863  if (!order->resource) {
1864  ast_free(order);
1865 
1866  return NULL;
1867  }
1868  order->required = required;
1869  order->preload = preload;
1870  order->builtin = builtin;
1871  AST_LIST_INSERT_TAIL(load_order, order, entry);
1872 
1873  return order;
1874 }
Definition: loader.c:1832
static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
Definition: loader.c:928
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int required
Definition: loader.c:1834
char * resource
Definition: loader.c:1833
integer order
Definition: analys.c:66
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
int builtin
Definition: loader.c:1836
int preload
Definition: loader.c:1835
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static size_t resource_name_baselen(const char *name)
Definition: loader.c:917
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Definition: search.h:40

◆ alpha_module_list_create()

static int alpha_module_list_create ( struct module_vector *  alpha_module_list)
static

Definition at line 2550 of file loader.c.

References AST_DLLIST_TRAVERSE, AST_VECTOR_ADD_SORTED, AST_VECTOR_INIT, and module_vector_strcasecmp().

Referenced by ast_update_module_list(), ast_update_module_list_condition(), and ast_update_module_list_data().

2551 {
2552  struct ast_module *cur;
2553 
2554  if (AST_VECTOR_INIT(alpha_module_list, 32)) {
2555  return -1;
2556  }
2557 
2559  if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
2560  return -1;
2561  }
2562  }
2563 
2564  return 0;
2565 }
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
static int module_vector_strcasecmp(struct ast_module *a, struct ast_module *b)
Definition: loader.c:366
Definition: search.h:40

◆ ast_load_resource()

int ast_load_resource ( const char *  resource_name)

Load a module.

Parameters
resource_nameThe name of the module to load.

This function is run by the PBX to load the modules. It performs all loading and initialization tasks. Basically, to load a module, just give it the name of the module and it will do the rest.

Returns
See possible enum values for ast_module_load_result.

Definition at line 1819 of file loader.c.

References AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, ast_test_suite_event_notify, load_resource(), and NULL.

Referenced by ast_ari_asterisk_load_module(), handle_load(), and manager_moduleload().

1820 {
1821  int res;
1823  res = load_resource(resource_name, 0, NULL, 0, 0);
1824  if (!res) {
1825  ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1826  }
1828 
1829  return res;
1830 }
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
#define NULL
Definition: resample.c:96
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging, struct module_vector *module_priorities, int required, int preload)
Definition: loader.c:1763

◆ ast_loader_register()

int ast_loader_register ( int(*)(void)  updater)

Add a procedure to be run when modules have been updated.

Parameters
updaterThe function to run when modules have been updated.

This function adds the given function to a linked list of functions to be run when the modules are updated.

Return values
0on success
-1on failure.

Definition at line 2666 of file loader.c.

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_malloc, tmp(), and loadupdate::updater.

2667 {
2668  struct loadupdate *tmp;
2669 
2670  if (!(tmp = ast_malloc(sizeof(*tmp))))
2671  return -1;
2672 
2673  tmp->updater = v;
2677 
2678  return 0;
2679 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int(* updater)(void)
Definition: loader.c:625
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int tmp()
Definition: bt_open.c:389
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
Definition: search.h:40

◆ ast_loader_unregister()

int ast_loader_unregister ( int(*)(void)  updater)

Remove a procedure to be run when modules are updated.

Parameters
updaterThe updater function to unregister.

This removes the given function from the updater list.

Return values
0on success
-1on failure.

Definition at line 2681 of file loader.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and loadupdate::updater.

2682 {
2683  struct loadupdate *cur;
2684 
2687  if (cur->updater == v) {
2689  break;
2690  }
2691  }
2694 
2695  return cur ? 0 : -1;
2696 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int(* updater)(void)
Definition: loader.c:625
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ ast_module_check()

int ast_module_check ( const char *  name)

Check if module exists.

Check if module with the name given is loaded.

Definition at line 2653 of file loader.c.

References ast_strlen_zero, find_resource(), and NULL.

Referenced by ast_ari_asterisk_get_module(), ast_ari_asterisk_load_module(), ast_ari_asterisk_reload_module(), ast_ari_asterisk_unload_module(), AST_TEST_DEFINE(), ifmodule_read(), and manager_modulecheck().

2654 {
2655  struct ast_module *cur;
2656 
2657  if (ast_strlen_zero(name))
2658  return 0; /* FALSE */
2659 
2660  cur = find_resource(name, 1);
2661 
2662  return (cur != NULL);
2663 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
static const char name[]
Definition: cdr_mysql.c:74

◆ ast_module_helper()

char* ast_module_helper ( const char *  line,
const char *  word,
int  pos,
int  state,
int  rpos,
enum ast_module_helper_type  type 
)

Match modules names for the Asterisk cli.

Parameters
lineUnused by this function, but this should be the line we are matching.
wordThe partial name to match.
posThe position the word we are completing is in.
stateThe possible match to return.
rposThe position we should be matching. This should be the same as pos.
typeThe type of action that will be performed by CLI.
Return values
Apossible completion of the partial match.
NULLif no matches were found.

Definition at line 1374 of file loader.c.

References AST_DLLIST_LOCK, AST_DLLIST_TRAVERSE, AST_DLLIST_UNLOCK, AST_MODULE_HELPER_LOAD, ast_strdup, module_load_helper(), module_matches_helper_type(), NULL, and ast_module::resource.

Referenced by handle_debug(), handle_load(), handle_modlist(), handle_reload(), handle_trace(), and handle_unload().

1375 {
1376  struct ast_module *mod;
1377  int which = 0;
1378  int wordlen = strlen(word);
1379  char *ret = NULL;
1380 
1381  if (pos != rpos) {
1382  return NULL;
1383  }
1384 
1385  if (type == AST_MODULE_HELPER_LOAD) {
1387 
1388  return NULL;
1389  }
1390 
1393  if (!module_matches_helper_type(mod, type)) {
1394  continue;
1395  }
1396 
1397  if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
1398  ret = ast_strdup(mod->resource);
1399  break;
1400  }
1401  }
1403 
1404  return ret;
1405 }
static const char type[]
Definition: chan_ooh323.c:109
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
Definition: loader.c:1299
static void module_load_helper(const char *word)
Definition: loader.c:1361
Definition: search.h:40
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
short word

◆ ast_module_name()

const char* ast_module_name ( const struct ast_module mod)

Get the name of a module.

Parameters
modA pointer to the module.
Returns
the name of the module
Return values
NULLif mod or mod->info is NULL

Definition at line 615 of file loader.c.

References ast_module::info, ast_module_info::name, and NULL.

Referenced by acf_retrieve_docs(), ast_register_application2(), resource_list_recursive_decline(), start_resource_list(), and unload_dynamic_module().

616 {
617  if (!mod || !mod->info) {
618  return NULL;
619  }
620 
621  return mod->info->name;
622 }
#define NULL
Definition: resample.c:96
const char * name
Definition: module.h:350
const struct ast_module_info * info
Definition: loader.c:294

◆ ast_module_register()

void ast_module_register ( const struct ast_module_info info)

Definition at line 659 of file loader.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_find, ao2_link, ao2_ref, ao2_t_alloc_options, ast_debug, AST_DLLIST_INSERT_TAIL, AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, AST_LIST_HEAD_INIT, ast_opt_ref_debug, ast_std_calloc(), AST_VECTOR_INIT, ast_module::builtin, builtin_module_list, ast_module::enhances, ast_module::flags, ast_module::info, sip_to_pjsip::info(), loader_ready, ast_module_info::name, NULL, OBJ_SEARCH_KEY, ast_module::optional_modules, ast_module::ref_debug, ast_module::reffed_deps, ast_module::requires, ast_module::resource, resource_being_loaded, ast_module_info::self, and ast_module::users.

Referenced by get_name_from_resource(), and loader_builtin_init().

660 {
661  struct ast_module *mod;
662 
663  if (!loader_ready) {
664  mod = ast_std_calloc(1, sizeof(*mod) + strlen(info->name) + 1);
665  if (!mod) {
666  /* We haven't even reached main() yet, if we can't
667  * allocate memory at this point just give up. */
668  fprintf(stderr, "Allocation failure during startup.\n");
669  exit(2);
670  }
671  strcpy(mod->resource, info->name); /* safe */
672  mod->info = info;
673  mod->flags.builtin = 1;
675 
676  /* ast_module_register for built-in modules is run again during module preload. */
677  return;
678  }
679 
680  /*
681  * This lock protects resource_being_loaded as well as the module
682  * list. Normally we already have a lock on module_list when we
683  * begin the load but locking again from here prevents corruption
684  * if an asterisk module is dlopen'ed from outside the module loader.
685  */
687  mod = resource_being_loaded;
688  if (!mod) {
690  return;
691  }
692 
693  ast_debug(5, "Registering module %s\n", info->name);
694 
695  /* This tells load_dynamic_module that we're registered. */
697 
698  mod->info = info;
699  if (ast_opt_ref_debug) {
701  }
702  AST_LIST_HEAD_INIT(&mod->users);
703  AST_VECTOR_INIT(&mod->requires, 0);
705  AST_VECTOR_INIT(&mod->enhances, 0);
706  AST_VECTOR_INIT(&mod->reffed_deps, 0);
707 
710 
711  /* give the module a copy of its own handle, for later use in registrations and the like */
712  *((struct ast_module **) &(info->self)) = mod;
713 
714 #if defined(HAVE_PERMANENT_DLOPEN)
715  if (mod->flags.builtin != 1) {
716  struct info_list_obj *obj_tmp = ao2_find(info_list, info->name,
718 
719  if (!obj_tmp) {
720  obj_tmp = info_list_obj_alloc(info->name, info);
721  if (obj_tmp) {
722  ao2_link(info_list, obj_tmp);
723  ao2_ref(obj_tmp, -1);
724  }
725  } else {
726  ao2_ref(obj_tmp, -1);
727  }
728  }
729 #endif
730 }
static unsigned int loader_ready
Definition: loader.c:150
struct module_user_list users
Definition: loader.c:302
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
static struct module_list builtin_module_list
Definition: loader.c:364
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
Definition: astobj2.h:404
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_DLLIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
struct ast_vector_string enhances
Definition: loader.c:309
const char * name
Definition: module.h:350
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
struct ast_module * self
Definition: module.h:342
const struct ast_module_info * info
Definition: loader.c:294
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_vector_string optional_modules
Definition: loader.c:307
struct ast_vector_string requires
Definition: loader.c:305
def info(msg)
void * ref_debug
Definition: loader.c:296
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
static struct ast_module *volatile resource_being_loaded
Definition: loader.c:650
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
void * ast_std_calloc(size_t nmemb, size_t size) attribute_malloc
Definition: astmm.c:1756
unsigned int builtin
Definition: loader.c:326
Definition: search.h:40
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
struct module_vector reffed_deps
Vector holding pointers to modules we have a reference to.
Definition: loader.c:317
#define ast_opt_ref_debug
Definition: options.h:135
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ ast_module_reload()

enum ast_module_reload_result ast_module_reload ( const char *  name)

Reload asterisk modules.

Parameters
namethe name of the module to reload

This function reloads the specified module, or if no modules are specified, it will reload all loaded modules.

Note
Modules are reloaded using their reload() functions, not unloading them and loading them again.
Return values
Theast_module_reload_result status of the module load request

Definition at line 1562 of file loader.c.

References ast_config_AST_CONFIG_DIR, AST_DLLIST_LOCK, AST_DLLIST_TRAVERSE, AST_DLLIST_UNLOCK, ast_lastreloadtime, ast_lock_path(), AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log, AST_LOG_WARNING, AST_MODULE_LOAD_SUCCESS, AST_MODULE_RELOAD_ERROR, AST_MODULE_RELOAD_IN_PROGRESS, AST_MODULE_RELOAD_NOT_FOUND, AST_MODULE_RELOAD_NOT_IMPLEMENTED, AST_MODULE_RELOAD_QUEUED, AST_MODULE_RELOAD_SUCCESS, AST_MODULE_RELOAD_UNINITIALIZED, ast_mutex_trylock, ast_mutex_unlock, ast_opt_lock_confdir, ast_sd_notify(), ast_tvnow(), ast_unlock_path(), ast_verb, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, LOG_WARNING, publish_reload_message(), queue_reload_request(), ast_module_info::reload, reloadlock, ast_module::resource, resource_name_baselen(), resource_name_match(), and ast_module::running.

Referenced by action_reload(), action_updateconfig(), ast_ari_asterisk_reload_module(), ast_process_pending_reloads(), handle_cli_moh_reload(), handle_core_reload(), handle_reload(), manager_moduleload(), and monitor_sig_flags().

1563 {
1564  struct ast_module *cur;
1566  size_t name_baselen = name ? resource_name_baselen(name) : 0;
1567 
1568  /* If we aren't fully booted, we just pretend we reloaded but we queue this
1569  up to run once we are booted up. */
1570  if (!modules_loaded) {
1573  goto module_reload_exit;
1574  }
1575 
1576  if (ast_mutex_trylock(&reloadlock)) {
1577  ast_verb(3, "The previous reload command didn't finish yet\n");
1579  goto module_reload_exit;
1580  }
1581  ast_sd_notify("RELOAD=1");
1583 
1584  if (ast_opt_lock_confdir) {
1585  int try;
1586  int lockres;
1587  for (try = 1, lockres = AST_LOCK_TIMEOUT; try < 6 && (lockres == AST_LOCK_TIMEOUT); try++) {
1589  if (lockres == AST_LOCK_TIMEOUT) {
1590  ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
1591  }
1592  }
1593  if (lockres != AST_LOCK_SUCCESS) {
1594  ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
1596  goto module_reload_done;
1597  }
1598  }
1599 
1602  const struct ast_module_info *info = cur->info;
1603 
1604  if (name && resource_name_match(name, name_baselen, cur->resource)) {
1605  continue;
1606  }
1607 
1608  if (!cur->flags.running || cur->flags.declined) {
1609  if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1611  }
1612  if (!name) {
1613  continue;
1614  }
1615  break;
1616  }
1617 
1618  if (!info->reload) { /* cannot be reloaded */
1619  if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1621  }
1622  if (!name) {
1623  continue;
1624  }
1625  break;
1626  }
1627  ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
1628  if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
1630  } else if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1632  }
1633  if (name) {
1634  break;
1635  }
1636  }
1638 
1639  if (ast_opt_lock_confdir) {
1641  }
1642 module_reload_done:
1644  ast_sd_notify("READY=1");
1645 
1646 module_reload_exit:
1648  return res;
1649 }
const char * description
Definition: module.h:352
unsigned int running
Definition: loader.c:320
ast_module_reload_result
Possible return types for ast_module_reload.
Definition: module.h:109
#define LOG_WARNING
Definition: logger.h:274
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static void publish_reload_message(const char *name, enum ast_module_reload_result result)
Definition: loader.c:1554
#define AST_LOG_WARNING
Definition: logger.h:279
static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
Definition: loader.c:928
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
int ast_unlock_path(const char *path)
Unlock a path.
Definition: main/app.c:2473
#define ast_verb(level,...)
Definition: logger.h:463
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: main/app.c:2457
#define ast_log
Definition: astobj2.c:42
#define ast_mutex_trylock(a)
Definition: lock.h:189
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
int ast_sd_notify(const char *state)
a wrapper for sd_notify(): notify systemd of any state changes.
Definition: io.c:392
static int modules_loaded
Internal flag to indicate all modules have been initially loaded.
Definition: loader.c:291
struct timeval ast_lastreloadtime
Definition: asterisk.c:337
unsigned int declined
Definition: loader.c:322
int(* reload)(void)
Definition: module.h:346
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
def info(msg)
static size_t resource_name_baselen(const char *name)
Definition: loader.c:917
static const char name[]
Definition: cdr_mysql.c:74
static void queue_reload_request(const char *module)
Definition: loader.c:1432
static ast_mutex_t reloadlock
Definition: loader.c:631
Definition: search.h:40
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define ast_opt_lock_confdir
Definition: options.h:133
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ast_module_support_level_to_string()

const char* ast_module_support_level_to_string ( enum ast_module_support_level  support_level)

Definition at line 2755 of file loader.c.

Referenced by identify_module(), modlist_modentry(), and process_module_list().

2756 {
2758 }
const char * support_level_map[]
Definition: loader.c:2748
enum ast_module_support_level support_level
Definition: module.h:416

◆ ast_module_unregister()

void ast_module_unregister ( const struct ast_module_info info)

Definition at line 768 of file loader.c.

References ast_debug, AST_DLLIST_LOCK, AST_DLLIST_REMOVE_CURRENT, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END, AST_DLLIST_UNLOCK, ast_module::info, module_destroy(), ast_module_info::name, NULL, and ast_module::usecount.

Referenced by get_name_from_resource().

769 {
770  struct ast_module *mod = NULL;
771 
772  /* it is assumed that the users list in the module structure
773  will already be empty, or we cannot have gotten to this
774  point
775  */
778  if (mod->info == info) {
780  break;
781  }
782  }
785 
786  if (mod && !mod->usecount) {
787  /*
788  * We are intentionally leaking mod if usecount is not zero.
789  * This is necessary if the module is being forcefully unloaded.
790  * In addition module_destroy is not safe to run after exit()
791  * is called. ast_module_unregister is run during cleanup of
792  * the process when libc releases each module's shared object
793  * library.
794  */
795  ast_debug(5, "Unregistering module %s\n", info->name);
796  module_destroy(mod);
797  }
798 }
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static void module_destroy(struct ast_module *mod)
Definition: loader.c:744
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: dlinkedlists.h:887
int usecount
Definition: loader.c:300
#define AST_DLLIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: dlinkedlists.h:752
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * name
Definition: module.h:350
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
Closes a safe loop traversal block.
Definition: dlinkedlists.h:920
Definition: search.h:40
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45

◆ ast_process_pending_reloads()

void ast_process_pending_reloads ( void  )

Process reload requests received during startup.

This function requests that the loader execute the pending reload requests that were queued during server startup.

Note
This function will do nothing if the server has not completely started up. Once called, the reload queue is emptied, and further invocations will have no affect.

Definition at line 1407 of file loader.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log, ast_module_reload(), item, LOG_NOTICE, reload_queue_item::module, and NULL.

Referenced by asterisk_daemon().

1408 {
1409  struct reload_queue_item *item;
1410 
1411  modules_loaded = 1;
1412 
1414 
1415  if (do_full_reload) {
1416  do_full_reload = 0;
1418  ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
1420  return;
1421  }
1422 
1423  while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1424  ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
1425  ast_module_reload(item->module);
1426  ast_free(item);
1427  }
1428 
1430 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
enum ast_module_reload_result ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:1562
static struct aco_type item
Definition: test_config.c:1463
#define NULL
Definition: resample.c:96
char module[0]
Definition: loader.c:635
#define ast_log
Definition: astobj2.c:42
static int modules_loaded
Internal flag to indicate all modules have been initially loaded.
Definition: loader.c:291
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
static int do_full_reload
Definition: loader.c:638
Definition: search.h:40

◆ ast_unload_resource()

int ast_unload_resource ( const char *  resource_name,
enum  ast_module_unload_mode 
)

Unload a module.

Parameters
resource_nameThe name of the module to unload.
ast_module_unload_modeThe force flag. This should be set using one of the AST_FORCE flags.

This function unloads a module. It will only unload modules that are not in use (usecount not zero), unless AST_FORCE_FIRM or AST_FORCE_HARD is specified. Setting AST_FORCE_FIRM or AST_FORCE_HARD will unload the module regardless of consequences (NOT RECOMMENDED).

Return values
0on success.
-1on error.

Definition at line 1229 of file loader.c.

References __ast_module_user_hangup_all(), AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, AST_FORCE_FIRM, ast_log, ast_test_suite_event_notify, ast_update_use_count(), ast_verb, ast_module::declined, error(), find_resource(), ast_module::flags, ast_module::info, LOG_WARNING, publish_unload_message(), ast_module::resource, ast_module::running, ast_module_info::unload, unload_dynamic_module(), and ast_module::usecount.

Referenced by ast_ari_asterisk_unload_module(), handle_unload(), manager_moduleload(), and unload_module().

1230 {
1231  struct ast_module *mod;
1232  int res = -1;
1233  int error = 0;
1234 
1236 
1237  if (!(mod = find_resource(resource_name, 0))) {
1239  ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
1240  return -1;
1241  }
1242 
1243  if (!mod->flags.running || mod->flags.declined) {
1244  ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
1245  error = 1;
1246  }
1247 
1248  if (!error && (mod->usecount > 0)) {
1249  if (force)
1250  ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
1251  resource_name, mod->usecount);
1252  else {
1253  ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
1254  mod->usecount);
1255  error = 1;
1256  }
1257  }
1258 
1259  if (!error) {
1260  /* Request any channels attached to the module to hangup. */
1262 
1263  ast_verb(1, "Unloading %s\n", mod->resource);
1264  res = mod->info->unload();
1265  if (res) {
1266  ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
1267  if (force <= AST_FORCE_FIRM) {
1268  error = 1;
1269  } else {
1270  ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
1271  }
1272  }
1273 
1274  if (!error) {
1275  /*
1276  * Request hangup on any channels that managed to get attached
1277  * while we called the module unload function.
1278  */
1280  sched_yield();
1281  }
1282  }
1283 
1284  if (!error)
1285  mod->flags.running = mod->flags.declined = 0;
1286 
1288 
1289  if (!error) {
1290  unload_dynamic_module(mod);
1291  ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
1293  publish_unload_message(resource_name, "Success");
1294  }
1295 
1296  return res;
1297 }
unsigned int running
Definition: loader.c:320
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
void __ast_module_user_hangup_all(struct ast_module *mod)
Definition: loader.c:853
#define LOG_WARNING
Definition: logger.h:274
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static void publish_unload_message(const char *name, const char *status)
Definition: loader.c:1544
int usecount
Definition: loader.c:300
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
const struct ast_module_info * info
Definition: loader.c:294
int(* unload)(void)
Definition: module.h:348
unsigned int declined
Definition: loader.c:322
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
static void unload_dynamic_module(struct ast_module *mod)
Definition: loader.c:1010
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
int error(const char *format,...)
Definition: utils/frame.c:999
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45

◆ ast_update_module_list()

int ast_update_module_list ( int(*)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level)  modentry,
const char *  like 
)

Ask for a list of modules, descriptions, use counts and status.

Parameters
modentryA callback to an updater function.
likeFor each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.
Returns
the number of modules loaded

Definition at line 2567 of file loader.c.

References alpha_module_list_create(), AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_module_info::description, ast_module::flags, ast_module::info, ast_module::resource, ast_module::running, ast_module_info::support_level, and ast_module::usecount.

Referenced by ast_var_Modules(), and handle_modlist().

2571 {
2572  int total_mod_loaded = 0;
2573  struct module_vector alpha_module_list;
2574 
2576 
2577  if (!alpha_module_list_create(&alpha_module_list)) {
2578  int idx;
2579 
2580  for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2581  struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2582 
2583  total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
2584  cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
2585  }
2586  }
2587 
2589  AST_VECTOR_FREE(&alpha_module_list);
2590 
2591  return total_mod_loaded;
2592 }
const char * description
Definition: module.h:352
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
unsigned int running
Definition: loader.c:320
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
int usecount
Definition: loader.c:300
const struct ast_module_info * info
Definition: loader.c:294
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int alpha_module_list_create(struct module_vector *alpha_module_list)
Definition: loader.c:2550
struct ast_module::@398 flags
enum ast_module_support_level support_level
Definition: module.h:416
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_update_module_list_condition()

int ast_update_module_list_condition ( int(*)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level, void *data, const char *condition)  modentry,
const char *  like,
void *  data,
const char *  condition 
)

Ask for a list of modules, descriptions, use counts and status.

Parameters
modentryA callback to an updater function
like
dataData passed into the callback for manipulation
conditionThe condition to meet

For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.

Returns
the number of conditions met
Since
13.5.0

Definition at line 2622 of file loader.c.

References alpha_module_list_create(), AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_module_info::description, ast_module::flags, ast_module::info, ast_module::resource, ast_module::running, ast_module_info::support_level, and ast_module::usecount.

Referenced by ast_ari_asterisk_get_module().

2628 {
2629  int conditions_met = 0;
2630  struct module_vector alpha_module_list;
2631 
2633 
2634  if (!alpha_module_list_create(&alpha_module_list)) {
2635  int idx;
2636 
2637  for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2638  struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2639 
2640  conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
2641  cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
2642  condition);
2643  }
2644  }
2645 
2647  AST_VECTOR_FREE(&alpha_module_list);
2648 
2649  return conditions_met;
2650 }
const char * description
Definition: module.h:352
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
unsigned int running
Definition: loader.c:320
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
int usecount
Definition: loader.c:300
const struct ast_module_info * info
Definition: loader.c:294
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int alpha_module_list_create(struct module_vector *alpha_module_list)
Definition: loader.c:2550
struct ast_module::@398 flags
enum ast_module_support_level support_level
Definition: module.h:416
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_update_module_list_data()

int ast_update_module_list_data ( int(*)(const char *module, const char *description, int usecnt, const char *status, const char *like, enum ast_module_support_level support_level, void *data)  modentry,
const char *  like,
void *  data 
)

Ask for a list of modules, descriptions, use counts and status.

Parameters
modentryA callback to an updater function
like
dataData passed into the callback for manipulation

For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module.

Returns
the number of modules loaded
Since
13.5.0

Definition at line 2594 of file loader.c.

References alpha_module_list_create(), AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_SIZE, ast_module_info::description, ast_module::flags, ast_module::info, ast_module::resource, ast_module::running, ast_module_info::support_level, and ast_module::usecount.

Referenced by ast_ari_asterisk_list_modules().

2599 {
2600  int total_mod_loaded = 0;
2601  struct module_vector alpha_module_list;
2602 
2604 
2605  if (!alpha_module_list_create(&alpha_module_list)) {
2606  int idx;
2607 
2608  for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
2609  struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
2610 
2611  total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
2612  cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
2613  }
2614  }
2615 
2617  AST_VECTOR_FREE(&alpha_module_list);
2618 
2619  return total_mod_loaded;
2620 }
const char * description
Definition: module.h:352
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
unsigned int running
Definition: loader.c:320
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
int usecount
Definition: loader.c:300
const struct ast_module_info * info
Definition: loader.c:294
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int alpha_module_list_create(struct module_vector *alpha_module_list)
Definition: loader.c:2550
struct ast_module::@398 flags
enum ast_module_support_level support_level
Definition: module.h:416
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ ast_update_use_count()

void ast_update_use_count ( void  )

Notify when usecount has been changed.

This function calulates use counts and notifies anyone trying to keep track of them. It should be called whenever your module's usecount changes.

Note
The ast_module_user_* functions take care of calling this function for you.

Definition at line 2528 of file loader.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and loadupdate::updater.

Referenced by __ast_module_ref(), __ast_module_unref(), __ast_module_user_add(), __ast_module_user_hangup_all(), __ast_module_user_remove(), ast_unload_resource(), handle_request_do(), ooh323_hangup(), ooh323_new(), ooh323c_call_thread(), sip_request_call(), start_resource(), and unistim_new().

2529 {
2530  /* Notify any module monitors that the use count for a
2531  resource has changed */
2532  struct loadupdate *m;
2533 
2536  m->updater();
2538 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int(* updater)(void)
Definition: loader.c:625
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40

◆ AST_VECTOR()

AST_VECTOR ( module_vector  ,
struct ast_module  
)

◆ find_resource()

static struct ast_module * find_resource ( const char *  resource,
int  do_lock 
)
static

Definition at line 937 of file loader.c.

References AST_DLLIST_LOCK, AST_DLLIST_TRAVERSE, AST_DLLIST_UNLOCK, ast_module::resource, resource_name_baselen(), and resource_name_match().

Referenced by ast_module_check(), ast_unload_resource(), load_dlopen_missing(), load_resource(), loader_config_init(), module_deps_missing_recursive(), module_deps_process_reqlist(), module_load_helper_on_file(), and module_vector_cmp().

938 {
939  struct ast_module *cur;
940  size_t resource_baselen = resource_name_baselen(resource);
941 
942  if (do_lock) {
944  }
945 
947  if (!resource_name_match(resource, resource_baselen, cur->resource)) {
948  break;
949  }
950  }
951 
952  if (do_lock) {
954  }
955 
956  return cur;
957 }
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
Definition: loader.c:928
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
static size_t resource_name_baselen(const char *name)
Definition: loader.c:917
Definition: search.h:40
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45

◆ get_name_from_resource()

static char* get_name_from_resource ( const char *  resource)
static

Definition at line 157 of file loader.c.

References ao2_alloc, ao2_find, ao2_ref, AO2_STRING_FIELD_CMP_FN, ast_calloc, ast_copy_string(), ast_free, ast_module_register(), ast_module_unregister(), ast_shutdown_final(), sip_to_pjsip::info(), len(), name, NULL, and OBJ_SEARCH_KEY.

Referenced by load_modules().

158 {
159  int len;
160  const char *last_three;
161  char *mod_name;
162 
163  if (!resource) {
164  return NULL;
165  }
166 
167  len = strlen(resource);
168  if (len > 3) {
169  last_three = &resource[len-3];
170  if (!strcasecmp(last_three, ".so")) {
171  mod_name = ast_calloc(1, len - 2);
172  if (mod_name) {
173  ast_copy_string(mod_name, resource, len - 2);
174  return mod_name;
175  } else {
176  /* Unable to allocate memory. */
177  return NULL;
178  }
179  }
180  }
181 
182  /* Resource is the name - happens when manually unloading a module. */
183  mod_name = ast_calloc(1, len + 1);
184  if (mod_name) {
185  ast_copy_string(mod_name, resource, len + 1);
186  return mod_name;
187  }
188 
189  /* Unable to allocate memory. */
190  return NULL;
191 }
#define NULL
Definition: resample.c:96
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char resource[0]
Definition: loader.c:333

◆ inspect_module()

static unsigned int inspect_module ( const struct ast_module mod)
static

Definition at line 1651 of file loader.c.

References ast_strlen_zero, buildopt_sum, ast_module_info::buildopt_sum, ast_module_info::description, ast_module::info, ast_module_info::key, module_load_error(), ast_module::resource, and verify_key().

Referenced by load_resource().

1652 {
1653  if (!mod->info->description) {
1654  module_load_error("Module '%s' does not provide a description.\n", mod->resource);
1655  return 1;
1656  }
1657 
1658  if (!mod->info->key) {
1659  module_load_error("Module '%s' does not provide a license key.\n", mod->resource);
1660  return 1;
1661  }
1662 
1663  if (verify_key((unsigned char *) mod->info->key)) {
1664  module_load_error("Module '%s' did not provide a valid license key.\n", mod->resource);
1665  return 1;
1666  }
1667 
1668  if (!ast_strlen_zero(mod->info->buildopt_sum) &&
1669  strcmp(buildopt_sum, mod->info->buildopt_sum)) {
1670  module_load_error("Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
1671  module_load_error("Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
1672  return 1;
1673  }
1674 
1675  return 0;
1676 }
const char * description
Definition: module.h:352
static int verify_key(const unsigned char *key)
Definition: loader.c:900
#define ast_strlen_zero(foo)
Definition: strings.h:52
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
const struct ast_module_info * info
Definition: loader.c:294
static char buildopt_sum[33]
Definition: loader.c:138
const char * key
Definition: module.h:359
char resource[0]
Definition: loader.c:333
const char buildopt_sum[33]
Definition: module.h:363

◆ is_module_loaded()

static int is_module_loaded ( const char *  resource_name)
static

Check to see if the given resource is loaded.

Parameters
resource_nameName of the resource, including .so suffix.
Returns
False (0) if module is not loaded.
True (non-zero) if module is loaded.

Definition at line 991 of file loader.c.

References ast_config_AST_MODULE_DIR, ast_module::lib, logged_dlclose(), and PATH_MAX.

Referenced by unload_dynamic_module().

992 {
993  char fn[PATH_MAX] = "";
994  void *lib;
995 
996  snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
997  resource_name);
998 
999  lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
1000 
1001  if (lib) {
1002  logged_dlclose(resource_name, lib);
1003  return 1;
1004  }
1005 
1006  return 0;
1007 }
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
static void logged_dlclose(const char *name, void *lib)
dlclose(), with failure logging.
Definition: loader.c:962
#define PATH_MAX
Definition: asterisk.h:40
void * lib
Definition: loader.c:298

◆ key_matches()

static int key_matches ( const unsigned char *  key1,
const unsigned char *  key2 
)
static

Definition at line 888 of file loader.c.

Referenced by verify_key().

889 {
890  int x;
891 
892  for (x = 0; x < 16; x++) {
893  if (key1[x] != key2[x])
894  return 0;
895  }
896 
897  return 1;
898 }

◆ load_dlopen()

static struct ast_module* load_dlopen ( const char *  resource_in,
const char *  so_ext,
const char *  filename,
int  flags,
unsigned int  suppress_logging 
)
static

Definition at line 1070 of file loader.c.

References ast_assert, ast_calloc, ast_free, ast_str_buffer(), ast_str_create, ast_str_strlen(), ast_strdupa, c, ast_module::enhances, ast_module::lib, load_dlopen_missing(), logged_dlclose(), module_load_error(), module_post_register(), NULL, ast_module::optional_modules, ast_module::requires, ast_module::resource, RTLD_LOCAL, S_OR, and unload_dynamic_module().

Referenced by load_dynamic_module().

1072 {
1073  struct ast_module *mod;
1074 
1076 
1077  mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1);
1078  if (!mod) {
1079  return NULL;
1080  }
1081 
1082  sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */
1083 
1084  resource_being_loaded = mod;
1085  mod->lib = dlopen(filename, flags);
1086 #if defined(HAVE_PERMANENT_DLOPEN)
1087  manual_mod_reg(mod->lib, mod->resource);
1088 #endif
1089  if (resource_being_loaded) {
1090  struct ast_str *list;
1091  int c = 0;
1092  const char *dlerror_msg = ast_strdupa(S_OR(dlerror(), ""));
1093 
1095  if (mod->lib) {
1096  module_load_error("Module '%s' did not register itself during load\n", resource_in);
1097  logged_dlclose(resource_in, mod->lib);
1098 
1099  goto error_return;
1100  }
1101 
1102  if (suppress_logging) {
1103  goto error_return;
1104  }
1105 
1106  resource_being_loaded = mod;
1107  mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
1108 #if defined(HAVE_PERMANENT_DLOPEN)
1109  manual_mod_reg(mod->lib, mod->resource);
1110 #endif
1111  if (resource_being_loaded) {
1113 
1114  module_load_error("Error loading module '%s': %s\n", resource_in, dlerror_msg);
1115  logged_dlclose(resource_in, mod->lib);
1116 
1117  goto error_return;
1118  }
1119 
1120  list = ast_str_create(64);
1121  if (list) {
1122  if (module_post_register(mod)) {
1123  goto loaded_error;
1124  }
1125 
1126  c = load_dlopen_missing(&list, &mod->requires);
1127  c += load_dlopen_missing(&list, &mod->enhances);
1128 #ifndef OPTIONAL_API
1129  c += load_dlopen_missing(&list, &mod->optional_modules);
1130 #endif
1131  }
1132 
1133  if (list && ast_str_strlen(list)) {
1134  module_load_error("Error loading module '%s', missing %s: %s\n",
1135  resource_in, c == 1 ? "dependency" : "dependencies", ast_str_buffer(list));
1136  } else {
1137  module_load_error("Error loading module '%s': %s\n", resource_in, dlerror_msg);
1138  }
1139 
1140 loaded_error:
1141  ast_free(list);
1142  unload_dynamic_module(mod);
1143 
1144  return NULL;
1145 
1146 error_return:
1147  ast_free(mod);
1148 
1149  return NULL;
1150  }
1151 
1152  return mod;
1153 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define ast_assert(a)
Definition: utils.h:695
static struct test_val c
#define NULL
Definition: resample.c:96
static int module_post_register(struct ast_module *mod)
Definition: loader.c:732
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
struct ast_vector_string enhances
Definition: loader.c:309
#define RTLD_LOCAL
Definition: loader.c:124
struct ast_vector_string optional_modules
Definition: loader.c:307
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void unload_dynamic_module(struct ast_module *mod)
Definition: loader.c:1010
static void logged_dlclose(const char *name, void *lib)
dlclose(), with failure logging.
Definition: loader.c:962
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
struct ast_vector_string requires
Definition: loader.c:305
#define ast_free(a)
Definition: astmm.h:182
static struct ast_module *volatile resource_being_loaded
Definition: loader.c:650
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static int load_dlopen_missing(struct ast_str **list, struct ast_vector_string *deps)
Definition: loader.c:1040
struct ast_module::@398 flags
void * lib
Definition: loader.c:298
char resource[0]
Definition: loader.c:333
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ load_dlopen_missing()

static int load_dlopen_missing ( struct ast_str **  list,
struct ast_vector_string *  deps 
)
static

Definition at line 1040 of file loader.c.

References AST_VECTOR_GET, AST_VECTOR_SIZE, c, find_resource(), and STR_APPEND_TEXT.

Referenced by load_dlopen().

1041 {
1042  int i;
1043  int c = 0;
1044 
1045  for (i = 0; i < AST_VECTOR_SIZE(deps); i++) {
1046  const char *dep = AST_VECTOR_GET(deps, i);
1047  if (!find_resource(dep, 0)) {
1048  STR_APPEND_TEXT(dep, list);
1049  c++;
1050  }
1051  }
1052 
1053  return c;
1054 }
static struct test_val c
#define STR_APPEND_TEXT(txt, str)
Definition: loader.c:144
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ load_dynamic_module()

static struct ast_module* load_dynamic_module ( const char *  resource_in,
unsigned int  suppress_logging 
)
static

Definition at line 1155 of file loader.c.

References ast_config_AST_MODULE_DIR, AST_MODFLAG_GLOBAL_SYMBOLS, ast_test_flag, ast_module::info, ast_module::lib, load_dlopen(), logged_dlclose(), PATH_MAX, RTLD_LOCAL, and RTLD_NOW.

Referenced by load_resource().

1156 {
1157  char fn[PATH_MAX];
1158  struct ast_module *mod;
1159  size_t resource_in_len = strlen(resource_in);
1160  const char *so_ext = "";
1161 
1162  if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) {
1163  so_ext = ".so";
1164  }
1165 
1166  snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext);
1167 
1168  /* Try loading in quiet mode first with RTLD_LOCAL. The majority of modules do not
1169  * export symbols so this allows the least number of calls to dlopen. */
1170  mod = load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_LOCAL, suppress_logging);
1171 
1172  if (!mod || !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
1173  return mod;
1174  }
1175 
1176  /* Close the module so we can reopen with correct flags. */
1177  logged_dlclose(resource_in, mod->lib);
1178 
1179  return load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_GLOBAL, 0);
1180 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
const struct ast_module_info * info
Definition: loader.c:294
#define RTLD_LOCAL
Definition: loader.c:124
static void logged_dlclose(const char *name, void *lib)
dlclose(), with failure logging.
Definition: loader.c:962
static struct ast_module * load_dlopen(const char *resource_in, const char *so_ext, const char *filename, int flags, unsigned int suppress_logging)
Definition: loader.c:1070
#define PATH_MAX
Definition: asterisk.h:40
#define RTLD_NOW
Definition: loader.c:120
void * lib
Definition: loader.c:298

◆ load_modules()

int load_modules ( void  )

Provided by loader.c

Definition at line 2338 of file loader.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_container_alloc_list, ast_copy_string(), ast_debug, AST_DLLIST_LOCK, AST_DLLIST_TRAVERSE, AST_DLLIST_UNLOCK, ast_free, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log, AST_MODULE_SUPPORT_DEPRECATED, ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_reset(), ast_str_strlen(), ast_strlen_zero, ast_tvdiff_us(), ast_tvnow(), AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_SIZE, ast_verb, ast_xml_find_element(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_xpath_get_first_result(), ast_xml_xpath_results_free(), ast_xmldoc_query(), ast_module::declined, done, ast_module::flags, get_name_from_resource(), ast_module::info, load_resource_list(), loader_builtin_init(), loader_config_init(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, NULL, order, ast_module::resource, load_order_entry::resource, ast_module::running, startup_errors, str, and ast_module_info::support_level.

Referenced by asterisk_daemon().

2339 {
2340  struct load_order_entry *order;
2341  unsigned int load_count;
2342  struct load_order load_order;
2343  int res = 0;
2344  int modulecount = 0;
2345  int i;
2346  struct ast_module *cur;
2347 #ifdef AST_XML_DOCS
2348  struct ast_str *warning_msg;
2349  char deprecated_in[33];
2350  char removed_in[33];
2351  char replacement[129];
2352 #endif
2353  struct timeval start_time = ast_tvnow();
2354  struct timeval end_time;
2355  int64_t usElapsed;
2356 
2357  ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
2358 
2359 #if defined(HAVE_PERMANENT_DLOPEN)
2361  info_list_obj_cmp_fn); /* must not be cleaned at shutdown */
2362  if (!info_list) {
2363  fprintf(stderr, "Module info list allocation failure.\n");
2364  return 1;
2365  }
2366 #endif
2367 
2370 
2373 
2375  if (res) {
2376  goto done;
2377  }
2378 
2380  if (res) {
2381  goto done;
2382  }
2383 
2384  load_count = 0;
2386  load_count++;
2387 
2388  if (load_count)
2389  ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
2390 
2391  res = load_resource_list(&load_order, &modulecount);
2392  if (res == -1) {
2393  ast_log(LOG_WARNING, "Some non-required modules failed to load.\n");
2394  res = 0;
2395  }
2396 
2397 done:
2398  while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
2399  ast_free(order->resource);
2400  ast_free(order);
2401  }
2402 
2403 #ifdef AST_XML_DOCS
2404  warning_msg = ast_str_create(512);
2405 #endif
2406 
2408 #ifdef AST_XML_DOCS
2409  char *mod_name = NULL;
2410  struct ast_xml_xpath_results *results;
2411 #endif
2412 
2413  if (!cur->flags.running || cur->flags.declined) {
2414  continue;
2415  }
2416 
2417 #ifdef AST_XML_DOCS
2418  mod_name = get_name_from_resource(cur->resource);
2419  if (!warning_msg || !mod_name) {
2420  /* If we can't allocate memory, we have bigger issues */
2421  ast_free(mod_name);
2422  continue;
2423  }
2424 
2425  /* Clear out the previous values */
2426  deprecated_in[0] = removed_in[0] = replacement[0] = 0;
2427 
2428  results = ast_xmldoc_query("/docs/module[@name='%s']", mod_name);
2429  if (results) {
2430  struct ast_xml_node *deprecated_node, *removed_node, *replacement_node;
2431  struct ast_xml_node *metadata_nodes = ast_xml_node_get_children(ast_xml_xpath_get_first_result(results));
2432 
2433  deprecated_node = ast_xml_find_element(metadata_nodes, "deprecated_in", NULL, NULL);
2434  if (deprecated_node) {
2435  const char *result_tmp = ast_xml_get_text(deprecated_node);
2436  if (!ast_strlen_zero(result_tmp)) {
2437  ast_copy_string(deprecated_in, result_tmp, sizeof(deprecated_in));
2438  }
2439  }
2440 
2441  removed_node = ast_xml_find_element(metadata_nodes, "removed_in", NULL, NULL);
2442  if (removed_node) {
2443  const char *result_tmp = ast_xml_get_text(removed_node);
2444  if (!ast_strlen_zero(result_tmp)) {
2445  ast_copy_string(removed_in, result_tmp, sizeof(removed_in));
2446  }
2447  }
2448 
2449  replacement_node = ast_xml_find_element(metadata_nodes, "replacement", NULL, NULL);
2450  if (replacement_node) {
2451  const char *result_tmp = ast_xml_get_text(replacement_node);
2452  if (!ast_strlen_zero(result_tmp)) {
2453  ast_copy_string(replacement, result_tmp, sizeof(replacement));
2454  }
2455  }
2456 
2457  ast_xml_xpath_results_free(results);
2458  }
2459 
2460  ast_str_reset(warning_msg);
2461 
2462  if (cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED || !ast_strlen_zero(deprecated_in)
2463  || !ast_strlen_zero(removed_in) || !ast_strlen_zero(replacement)) {
2464  int already_butted = 0;
2465 
2466  ast_str_append(&warning_msg, -1, "Module '%s' has been loaded", mod_name);
2467  if (!ast_strlen_zero(deprecated_in)) {
2468  ast_str_append(&warning_msg, -1, " but %s deprecated in Asterisk version %s",
2469  cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED ? "was" : "will be", deprecated_in);
2470  already_butted = 1;
2471  }
2472 
2473  if (!ast_strlen_zero(removed_in)) {
2474  ast_str_append(&warning_msg, -1, " %s will be removed in Asterisk version %s", already_butted ? "and" : "but", removed_in);
2475  } else {
2476  ast_str_append(&warning_msg, -1, " %s may be removed in a future release", already_butted ? "and" : "but");
2477  }
2478 
2479  ast_str_append(&warning_msg, -1, ".");
2480 
2481  if (!ast_strlen_zero(replacement)) {
2482  ast_str_append(&warning_msg, -1, " Its replacement is '%s'.", replacement);
2483  }
2484  }
2485 
2486  if (ast_str_strlen(warning_msg)) {
2487  ast_log(LOG_WARNING, "%s\n", ast_str_buffer(warning_msg));
2488  }
2489 
2490  ast_free(mod_name);
2491 #else
2493  ast_log(LOG_WARNING, "The deprecated module '%s' has been loaded and is running, it may be removed in a future version\n", cur->resource);
2494  }
2495 #endif
2496  }
2497 
2498 #ifdef AST_XML_DOCS
2499  ast_free(warning_msg);
2500 #endif
2501 
2503 
2504 
2505  for (i = 0; i < AST_VECTOR_SIZE(&startup_errors); i++) {
2506  char *str = AST_VECTOR_GET(&startup_errors, i);
2507 
2508  ast_log(LOG_ERROR, "%s", str);
2509  ast_free(str);
2510  }
2512 
2515 
2516  end_time = ast_tvnow();
2517  usElapsed = ast_tvdiff_us(end_time, start_time);
2518 
2519 #ifdef AST_XML_DOCS
2520  ast_debug(1, "Loader time with AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);
2521 #else
2522  ast_debug(1, "Loader time without AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);
2523 #endif
2524 
2525  return res;
2526 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
unsigned int running
Definition: loader.c:320
static char * get_name_from_resource(const char *resource)
Definition: loader.c:157
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
Definition: loader.c:1832
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
struct ast_xml_xpath_results * ast_xmldoc_query(const char *fmt,...)
Execute an XPath query on the loaded XML documentation.
Definition: xmldoc.c:2545
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
const char * str
Definition: app_jack.c:147
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
int done
Definition: test_amihooks.c:48
char * resource
Definition: loader.c:1833
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
integer order
Definition: analys.c:66
struct ast_xml_node * ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
Find a node element by name.
Definition: xml.c:266
unsigned int declined
Definition: loader.c:322
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
static int load_resource_list(struct load_order *load_order, int *mod_count)
Definition: loader.c:2101
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int loader_builtin_init(struct load_order *load_order)
Definition: loader.c:2179
static int loader_config_init(struct load_order *load_order)
Definition: loader.c:2214
static struct ast_str * startup_error_builder
Definition: loader.c:154
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
void ast_xml_xpath_results_free(struct ast_xml_xpath_results *results)
Free the XPath results.
Definition: xml.c:370
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
Definition: xml.c:317
Definition: search.h:40
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:78
static struct ast_vector_string startup_errors
Definition: loader.c:153
struct ast_module::@398 flags
enum ast_module_support_level support_level
Definition: module.h:416
char resource[0]
Definition: loader.c:333
struct ast_xml_node * ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
Return the first result node of an XPath query.
Definition: xml.c:365
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node&#39;s children.
Definition: xml.c:345
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ load_resource()

static enum ast_module_load_result load_resource ( const char *  resource_name,
unsigned int  suppress_logging,
struct module_vector *  module_priorities,
int  required,
int  preload 
)
static

loads a resource based upon resource_name. If global_symbols_only is set only modules with global symbols will be loaded.

If the module_vector is provided (not NULL) the module is found and added to the vector without running the module's load() function. By doing this, modules can be initialized later in order by priority and dependencies.

If the module_vector is not provided, the module's load function will be executed immediately

Definition at line 1763 of file loader.c.

References ast_fully_booted, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SUCCESS, ast_shutdown_final(), AST_VECTOR_ADD_SORTED, ast_module::declined, find_resource(), ast_module::flags, inspect_module(), load_dynamic_module(), LOG_WARNING, module_load_error(), module_post_register(), module_vector_cmp(), ast_module::preload, publish_load_message(), ast_module::required, ast_module::running, start_resource(), and unload_dynamic_module().

Referenced by ast_load_resource(), and load_resource_list().

1765 {
1766  struct ast_module *mod;
1768 
1769  if ((mod = find_resource(resource_name, 0))) {
1770  if (mod->flags.running) {
1771  ast_log(LOG_WARNING, "Module '%s' already loaded and running.\n", resource_name);
1772  return AST_MODULE_LOAD_DECLINE;
1773  }
1774  } else {
1775  mod = load_dynamic_module(resource_name, suppress_logging);
1776  if (!mod) {
1778  }
1779 
1780  if (module_post_register(mod)) {
1781  goto prestart_error;
1782  }
1783  }
1784 
1785  mod->flags.required |= required;
1786  mod->flags.preload |= preload;
1787 
1788  if (inspect_module(mod)) {
1789  goto prestart_error;
1790  }
1791 
1792  mod->flags.declined = 0;
1793 
1794  if (module_priorities) {
1795  if (AST_VECTOR_ADD_SORTED(module_priorities, mod, module_vector_cmp)) {
1796  goto prestart_error;
1797  }
1799  } else {
1800  res = start_resource(mod);
1801  }
1802 
1804  publish_load_message(resource_name, res);
1805  }
1806 
1807  return res;
1808 
1809 prestart_error:
1810  module_load_error("Module '%s' could not be loaded.\n", resource_name);
1811  unload_dynamic_module(mod);
1814  publish_load_message(resource_name, res);
1815  }
1816  return res;
1817 }
static enum ast_module_load_result start_resource(struct ast_module *mod)
Definition: loader.c:1678
ast_module_load_result
Definition: module.h:68
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
unsigned int running
Definition: loader.c:320
unsigned int required
Definition: loader.c:328
unsigned int preload
Definition: loader.c:330
#define LOG_WARNING
Definition: logger.h:274
static void publish_load_message(const char *name, enum ast_module_load_result result)
Definition: loader.c:1531
static int module_post_register(struct ast_module *mod)
Definition: loader.c:732
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
#define ast_log
Definition: astobj2.c:42
#define ast_fully_booted
Definition: options.h:115
unsigned int declined
Definition: loader.c:322
static void unload_dynamic_module(struct ast_module *mod)
Definition: loader.c:1010
int ast_shutdown_final(void)
Definition: asterisk.c:1829
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
Module could not be loaded properly.
Definition: module.h:102
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_module * load_dynamic_module(const char *resource_in, unsigned int suppress_logging)
Definition: loader.c:1155
struct ast_module::@398 flags
static unsigned int inspect_module(const struct ast_module *mod)
Definition: loader.c:1651
static int module_vector_cmp(struct ast_module *a, struct ast_module *b)
Definition: loader.c:371

◆ load_resource_list()

static int load_resource_list ( struct load_order load_order,
int *  mod_count 
)
static

loads modules in order by load_pri, updates mod_count

Returns
-1 on failure to load module, -2 on failure to load required module, otherwise 0

Definition at line 2101 of file loader.c.

References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, AST_VECTOR_FREE, AST_VECTOR_INIT, load_resource(), LOG_ERROR, module_load_error(), order, load_order_entry::preload, load_order_entry::required, load_order_entry::resource, and start_resource_list().

Referenced by load_modules().

2102 {
2103  struct module_vector module_priorities;
2104  struct load_order_entry *order;
2105  int attempt = 0;
2106  int count = 0;
2107  int res = 0;
2108  int didwork;
2109  int lasttry = 0;
2110 
2111  if (AST_VECTOR_INIT(&module_priorities, 500)) {
2112  ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
2113 
2114  return -1;
2115  }
2116 
2117  while (res != -2) {
2118  didwork = 0;
2119 
2120  AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
2121  enum ast_module_load_result lres;
2122 
2123  /* Suppress log messages unless this is the last pass */
2124  lres = load_resource(order->resource, !lasttry, &module_priorities, order->required, order->preload);
2125  ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);
2126  switch (lres) {
2128  case AST_MODULE_LOAD_SKIP:
2129  /* We're supplying module_priorities so SUCCESS isn't possible but we
2130  * still have to test for it. SKIP is only used when we try to start a
2131  * module that is missing dependencies. */
2132  break;
2134  res = -1;
2135  break;
2137  /* LOAD_FAILURE only happens for required modules */
2138  if (lasttry) {
2139  /* This run is just to print errors. */
2140  module_load_error("*** Failed to load module %s - Required\n", order->resource);
2141  fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
2142  res = -2;
2143  }
2144  break;
2146  /* load_resource worked and the module was added to module_priorities */
2148  ast_free(order->resource);
2149  ast_free(order);
2150  didwork = 1;
2151  break;
2152  }
2153  }
2155 
2156  if (!didwork) {
2157  if (lasttry) {
2158  break;
2159  }
2160  /* We know the next try is going to fail, it's only being performed
2161  * so we can print errors. */
2162  lasttry = 1;
2163  }
2164  attempt++;
2165  }
2166 
2167  if (res != -2) {
2168  res = start_resource_list(&module_priorities, &count);
2169  }
2170 
2171  if (mod_count) {
2172  *mod_count += count;
2173  }
2174  AST_VECTOR_FREE(&module_priorities);
2175 
2176  return res;
2177 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
ast_module_load_result
Definition: module.h:68
Definition: loader.c:1832
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
int required
Definition: loader.c:1834
char * resource
Definition: loader.c:1833
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
integer order
Definition: analys.c:66
static int start_resource_list(struct module_vector *resources, int *mod_count)
Definition: loader.c:1969
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
#define LOG_ERROR
Definition: logger.h:285
int preload
Definition: loader.c:1835
#define ast_free(a)
Definition: astmm.h:182
Module could not be loaded properly.
Definition: module.h:102
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging, struct module_vector *module_priorities, int required, int preload)
Definition: loader.c:1763

◆ loader_builtin_init()

static int loader_builtin_init ( struct load_order load_order)
static

Definition at line 2179 of file loader.c.

References add_to_load_order(), AST_DLLIST_REMOVE_HEAD, AST_DLLIST_TRAVERSE, ast_module_register(), ast_module::builtin, builtin_module_list, ast_module::flags, ast_module::info, loader_ready, module_post_register(), and ast_module::resource.

Referenced by load_modules().

2180 {
2181  struct ast_module *mod;
2182 
2183  /*
2184  * All built-in modules have registered the first time, now it's time to complete
2185  * the registration and add them to the priority list.
2186  */
2187  loader_ready = 1;
2188 
2190  /* ast_module_register doesn't finish when first run by built-in modules. */
2192  }
2193 
2194  /* Add all built-in modules to the load order. */
2196  if (!mod->flags.builtin) {
2197  continue;
2198  }
2199 
2200  /* Parse dependendencies from mod->info. */
2201  if (module_post_register(mod)) {
2202  return -1;
2203  }
2204 
2205  /* Built-in modules are not preloaded, most have an early load priority. */
2206  if (!add_to_load_order(mod->resource, load_order, 0, 0, 1)) {
2207  return -1;
2208  }
2209  }
2210 
2211  return 0;
2212 }
void ast_module_register(const struct ast_module_info *info)
Definition: loader.c:659
static unsigned int loader_ready
Definition: loader.c:150
static struct module_list builtin_module_list
Definition: loader.c:364
#define AST_DLLIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
static int module_post_register(struct ast_module *mod)
Definition: loader.c:732
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
static struct load_order_entry * add_to_load_order(const char *resource, struct load_order *load_order, int required, int preload, int builtin)
Definition: loader.c:1842
static struct ast_module *volatile resource_being_loaded
Definition: loader.c:650
unsigned int builtin
Definition: loader.c:326
Definition: search.h:40
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333

◆ loader_config_init()

static int loader_config_init ( struct load_order load_order)
static

Definition at line 2214 of file loader.c.

References add_to_load_order(), ast_config_AST_MODULE_DIR, ast_config_destroy(), ast_config_load2(), ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, AST_MODULE_CONFIG, ast_true(), ast_variable_browse(), ast_variable_retrieve(), load_order_entry::builtin, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, done, find_resource(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, order, load_order_entry::preload, load_order_entry::required, load_order_entry::resource, resource_name_baselen(), resource_name_match(), and ast_variable::value.

Referenced by load_modules().

2215 {
2216  int res = -1;
2217  struct load_order_entry *order;
2218  struct ast_config *cfg;
2219  struct ast_variable *v;
2220  struct ast_flags config_flags = { 0 };
2221 
2222  cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
2224  ast_log(LOG_WARNING, "'%s' invalid or missing.\n", AST_MODULE_CONFIG);
2225 
2226  return -1;
2227  }
2228 
2229  /* first, find all the modules we have been explicitly requested to load */
2230  for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
2231  int required;
2232  int preload = 0;
2233 
2234  if (!strncasecmp(v->name, "preload", strlen("preload"))) {
2235  preload = 1;
2236  if (!strcasecmp(v->name, "preload")) {
2237  required = 0;
2238  } else if (!strcasecmp(v->name, "preload-require")) {
2239  required = 1;
2240  } else {
2241  ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);
2242  goto done;
2243  }
2244  } else if (!strcasecmp(v->name, "load")) {
2245  required = 0;
2246  } else if (!strcasecmp(v->name, "require")) {
2247  required = 1;
2248  } else if (!strcasecmp(v->name, "noload") || !strcasecmp(v->name, "autoload")) {
2249  continue;
2250  } else {
2251  ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);
2252  goto done;
2253  }
2254 
2255  if (required) {
2256  ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
2257  }
2258 
2259  if (!add_to_load_order(v->value, load_order, required, preload, 0)) {
2260  goto done;
2261  }
2262  }
2263 
2264  /* check if 'autoload' is on */
2265  if (ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
2266  /* if we are allowed to load dynamic modules, scan the directory for
2267  for all available modules and add them as well */
2268  DIR *dir = opendir(ast_config_AST_MODULE_DIR);
2269  struct dirent *dirent;
2270 
2271  if (dir) {
2272  while ((dirent = readdir(dir))) {
2273  int ld = strlen(dirent->d_name);
2274 
2275  /* Must end in .so to load it. */
2276 
2277  if (ld < 4)
2278  continue;
2279 
2280  if (strcasecmp(dirent->d_name + ld - 3, ".so"))
2281  continue;
2282 
2283  /* if there is already a module by this name in the module_list,
2284  skip this file */
2285  if (find_resource(dirent->d_name, 0))
2286  continue;
2287 
2288  if (!add_to_load_order(dirent->d_name, load_order, 0, 0, 0)) {
2289  closedir(dir);
2290  goto done;
2291  }
2292  }
2293 
2294  closedir(dir);
2295  } else {
2296  ast_log(LOG_ERROR, "Unable to open modules directory '%s'.\n", ast_config_AST_MODULE_DIR);
2297  goto done;
2298  }
2299  }
2300 
2301  /* now scan the config for any modules we are prohibited from loading and
2302  remove them from the load order */
2303  for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
2304  size_t baselen;
2305 
2306  if (strcasecmp(v->name, "noload")) {
2307  continue;
2308  }
2309 
2310  baselen = resource_name_baselen(v->value);
2311  AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
2312  if (!resource_name_match(v->value, baselen, order->resource)) {
2313  if (order->builtin) {
2314  ast_log(LOG_ERROR, "%s is a built-in module, you cannot specify 'noload'.\n", v->value);
2315  goto done;
2316  }
2317 
2318  if (order->required) {
2319  ast_log(LOG_ERROR, "%s is configured with '%s' and 'noload', this is impossible.\n",
2320  v->value, order->preload ? "preload-require" : "require");
2321  goto done;
2322  }
2324  ast_free(order->resource);
2325  ast_free(order);
2326  }
2327  }
2329  }
2330 
2331  res = 0;
2332 done:
2333  ast_config_destroy(cfg);
2334 
2335  return res;
2336 }
struct ast_variable * next
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3154
Structure for variables, used for configurations and for channel variables.
Definition: loader.c:1832
static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
Definition: loader.c:928
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
int done
Definition: test_amihooks.c:48
int required
Definition: loader.c:1834
char * resource
Definition: loader.c:1833
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
integer order
Definition: analys.c:66
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define LOG_ERROR
Definition: logger.h:285
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: main/utils.c:1951
int builtin
Definition: loader.c:1836
static struct load_order_entry * add_to_load_order(const char *resource, struct load_order *load_order, int required, int preload, int builtin)
Definition: loader.c:1842
int preload
Definition: loader.c:1835
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
static size_t resource_name_baselen(const char *name)
Definition: loader.c:917
#define ast_free(a)
Definition: astmm.h:182
Structure used to handle boolean flags.
Definition: utils.h:199
#define CONFIG_STATUS_FILEMISSING
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
#define AST_MODULE_CONFIG
Module configuration file.
Definition: module.h:59
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528

◆ loadresult2str()

static const char* loadresult2str ( enum ast_module_load_result  result)
static

Definition at line 1514 of file loader.c.

References ARRAY_LEN, ast_log, AST_MODULE_LOAD_UNKNOWN_STRING, LOG_WARNING, and load_results_map::name.

Referenced by publish_load_message().

1515 {
1516  int i;
1517  for (i = 0; i < ARRAY_LEN(load_results); i++) {
1518  if (load_results[i].result == result) {
1519  return load_results[i].name;
1520  }
1521  }
1522 
1523  ast_log(LOG_WARNING, "Failed to find correct load result status. result %d\n", result);
1525 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
const char * name
Definition: loader.c:341
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_MODULE_LOAD_UNKNOWN_STRING
Definition: loader.c:351
static const struct load_results_map load_results[]
Definition: loader.c:344

◆ logged_dlclose()

static void logged_dlclose ( const char *  name,
void *  lib 
)
static

dlclose(), with failure logging.

Definition at line 962 of file loader.c.

References ast_log, AST_LOG_ERROR, error(), and S_OR.

Referenced by is_module_loaded(), load_dlopen(), load_dynamic_module(), and unload_dynamic_module().

963 {
964  char *error;
965 
966  if (!lib) {
967  return;
968  }
969 
970  /* Clear any existing error */
971  dlerror();
972  if (dlclose(lib)) {
973  error = dlerror();
974  ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
975  S_OR(name, "unknown"), S_OR(error, "Unknown error"));
976 #if defined(HAVE_PERMANENT_DLOPEN)
977  } else {
978  manual_mod_unreg(name);
979 #endif
980  }
981 }
#define ast_log
Definition: astobj2.c:42
#define AST_LOG_ERROR
Definition: logger.h:290
static const char name[]
Definition: cdr_mysql.c:74
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
int error(const char *format,...)
Definition: utils/frame.c:999

◆ module_deps_missing_recursive()

static int module_deps_missing_recursive ( struct ast_module mod,
struct module_vector *  missingdeps 
)
static

Recursively find required dependencies that are not running.

Parameters
modModule to scan for dependencies.
missingdepsVector listing modules that must be started first.
Return values
0All dependencies resolved.
-1Failed to resolve some dependencies.

An error from this function usually means a required module is not even loaded. This function is safe from infinite recursion, but dependency loops are not reported as an error from here. On success missingdeps will contain a list of every module that needs to be running before this module can start. missingdeps is sorted by load priority so any missing dependencies can be started if needed.

Definition at line 566 of file loader.c.

References AST_VECTOR_ADD_SORTED, AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_GET_CMP, AST_VECTOR_INIT, AST_VECTOR_REMOVE, AST_VECTOR_SIZE, find_resource(), module_deps_reference(), and module_vector_cmp().

Referenced by resource_list_recursive_decline(), start_resource(), and start_resource_list().

567 {
568  int i = 0;
569  int res = -1;
570  struct ast_vector_const_string localdeps;
571  struct ast_module *dep;
572 
573  /*
574  * localdeps stores a copy of all dependencies that mod could not reference.
575  * First we discard modules that we've already found. We add all newly found
576  * modules to the missingdeps vector then scan them recursively. This will
577  * ensure we quickly run out of stuff to do.
578  */
579  AST_VECTOR_INIT(&localdeps, 0);
580  if (module_deps_reference(mod, &localdeps)) {
581  goto clean_return;
582  }
583 
584  while (i < AST_VECTOR_SIZE(&localdeps)) {
585  dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
586  if (!dep) {
587  goto clean_return;
588  }
589 
590  if (AST_VECTOR_GET_CMP(missingdeps, dep, AST_VECTOR_ELEM_DEFAULT_CMP)) {
591  /* Skip common dependency. We have already searched it. */
592  AST_VECTOR_REMOVE(&localdeps, i, 0);
593  } else {
594  /* missingdeps is the real list so keep it sorted. */
595  if (AST_VECTOR_ADD_SORTED(missingdeps, dep, module_vector_cmp)) {
596  goto clean_return;
597  }
598  i++;
599  }
600  }
601 
602  res = 0;
603  for (i = 0; !res && i < AST_VECTOR_SIZE(&localdeps); i++) {
604  dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
605  /* We've already confirmed dep is loaded in the first loop. */
606  res = module_deps_missing_recursive(dep, missingdeps);
607  }
608 
609 clean_return:
610  AST_VECTOR_FREE(&localdeps);
611 
612  return res;
613 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
Recursively find required dependencies that are not running.
Definition: loader.c:566
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
Definition: loader.c:534
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
static int module_vector_cmp(struct ast_module *a, struct ast_module *b)
Definition: loader.c:371

◆ module_deps_process_reqlist()

static int module_deps_process_reqlist ( struct ast_module mod,
struct ast_vector_string *  vec,
struct ast_vector_const_string *  missing,
int  ref_enhancers,
int  isoptional 
)
static

Definition at line 485 of file loader.c.

References AST_VECTOR_APPEND, AST_VECTOR_GET, AST_VECTOR_SIZE, find_resource(), ast_module::flags, module_reffed_deps_add(), module_reffed_deps_add_dep_enhancers(), and ast_module::running.

Referenced by module_deps_reference().

488 {
489  int idx;
490 
491  for (idx = 0; idx < AST_VECTOR_SIZE(vec); idx++) {
492  const char *depname = AST_VECTOR_GET(vec, idx);
493  struct ast_module *dep = find_resource(depname, 0);
494 
495  if (!dep || !dep->flags.running) {
496  if (isoptional && !dep) {
497  continue;
498  }
499 
500  if (missing && !AST_VECTOR_APPEND(missing, depname)) {
501  continue;
502  }
503 
504  return -1;
505  }
506 
507  if (module_reffed_deps_add(mod, dep, missing)) {
508  return -1;
509  }
510 
511  if (ref_enhancers && module_reffed_deps_add_dep_enhancers(mod, dep, missing)) {
512  return -1;
513  }
514  }
515 
516  return 0;
517 }
unsigned int running
Definition: loader.c:320
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
static int module_reffed_deps_add_dep_enhancers(struct ast_module *mod, struct ast_module *dep, struct ast_vector_const_string *missing)
Definition: loader.c:448
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
struct ast_module::@398 flags
static int module_reffed_deps_add(struct ast_module *mod, struct ast_module *dep, struct ast_vector_const_string *missing)
Definition: loader.c:416
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ module_deps_reference()

static int module_deps_reference ( struct ast_module mod,
struct ast_vector_const_string *  missing 
)
static

Definition at line 534 of file loader.c.

References ast_module::enhances, module_deps_process_reqlist(), ast_module::optional_modules, and ast_module::requires.

Referenced by module_deps_missing_recursive(), start_resource(), start_resource_attempt(), and start_resource_list().

535 {
536  int res = 0;
537 
538  /* Grab references to modules we enhance but not other enhancements. */
539  res |= module_deps_process_reqlist(mod, &mod->enhances, missing, 0, 0);
540 
541  /* Grab references to modules we require plus enhancements. */
542  res |= module_deps_process_reqlist(mod, &mod->requires, missing, 1, 0);
543 
544  /* Grab references to optional modules including enhancements. */
545  res |= module_deps_process_reqlist(mod, &mod->optional_modules, missing, 1, 1);
546 
547  return res;
548 }
struct ast_vector_string enhances
Definition: loader.c:309
struct ast_vector_string optional_modules
Definition: loader.c:307
struct ast_vector_string requires
Definition: loader.c:305
static int module_deps_process_reqlist(struct ast_module *mod, struct ast_vector_string *vec, struct ast_vector_const_string *missing, int ref_enhancers, int isoptional)
Definition: loader.c:485

◆ module_destroy()

static void module_destroy ( struct ast_module mod)
static

Definition at line 744 of file loader.c.

References ao2_cleanup, ast_free, AST_LIST_HEAD_DESTROY, ast_module_unref, ast_std_free(), AST_VECTOR_CALLBACK_VOID, AST_VECTOR_FREE, ast_module::builtin, ast_module::enhances, ast_module::flags, ast_module::optional_modules, ast_module::ref_debug, ast_module::reffed_deps, ast_module::requires, and ast_module::users.

Referenced by ast_module_unregister(), and modules_shutdown().

745 {
747  AST_VECTOR_FREE(&mod->requires);
748 
751 
753  AST_VECTOR_FREE(&mod->enhances);
754 
755  /* Release references to all dependencies. */
758 
760  ao2_cleanup(mod->ref_debug);
761  if (mod->flags.builtin) {
762  ast_std_free(mod);
763  } else {
764  ast_free(mod);
765  }
766 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
void ast_std_free(void *ptr)
Definition: astmm.c:1766
struct module_user_list users
Definition: loader.c:302
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
struct ast_vector_string enhances
Definition: loader.c:309
struct ast_vector_string optional_modules
Definition: loader.c:307
struct ast_vector_string requires
Definition: loader.c:305
void * ref_debug
Definition: loader.c:296
#define ast_free(a)
Definition: astmm.h:182
unsigned int builtin
Definition: loader.c:326
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_module::@398 flags
struct module_vector reffed_deps
Vector holding pointers to modules we have a reference to.
Definition: loader.c:317
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865

◆ module_load_error()

static void module_load_error ( const char *  fmt,
  ... 
)
static

Definition at line 269 of file loader.c.

References ast_free, ast_log, ast_log_ap(), ast_str_buffer(), ast_str_set_va(), ast_strdup, AST_VECTOR_APPEND, copy(), LOG_ERROR, NULL, and startup_errors.

Referenced by inspect_module(), load_dlopen(), load_resource(), load_resource_list(), resource_list_recursive_decline(), start_resource(), start_resource_attempt(), and start_resource_list().

270 {
271  char *copy = NULL;
272  va_list ap;
273 
274  va_start(ap, fmt);
275  if (startup_error_builder) {
278  if (!copy || AST_VECTOR_APPEND(&startup_errors, copy)) {
280  ast_free(copy);
281  }
282  } else {
283  ast_log_ap(LOG_ERROR, fmt, ap);
284  }
285  va_end(ap);
286 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
Definition: strings.h:982
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static struct ast_str * startup_error_builder
Definition: loader.c:154
#define ast_free(a)
Definition: astmm.h:182
static struct ast_vector_string startup_errors
Definition: loader.c:153
void ast_log_ap(int level, const char *file, int line, const char *function, const char *fmt, va_list ap)
Definition: logger.c:2110

◆ module_load_helper()

static void module_load_helper ( const char *  word)
static

Definition at line 1361 of file loader.c.

References ast_config_AST_MODULE_DIR, AST_DLLIST_LOCK, AST_DLLIST_UNLOCK, ast_file_read_dirs(), module_load_helper_on_file(), and module_load_word::word.

Referenced by ast_module_helper().

1362 {
1363  struct module_load_word word_l = {
1364  .word = word,
1365  .len = strlen(word),
1366  .moddir_len = strlen(ast_config_AST_MODULE_DIR),
1367  };
1368 
1372 }
const char * word
Definition: loader.c:1324
const char * ast_config_AST_MODULE_DIR
Definition: options.c:153
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static int module_load_helper_on_file(const char *dir_name, const char *filename, void *obj)
Definition: loader.c:1329
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
Definition: file.c:1231
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
short word

◆ module_load_helper_on_file()

static int module_load_helper_on_file ( const char *  dir_name,
const char *  filename,
void *  obj 
)
static

Definition at line 1329 of file loader.c.

References ast_asprintf, ast_assert, ast_cli_completion_add(), ast_free, ast_strdup, ast_strlen_zero, find_resource(), ast_module::flags, module_load_word::len, module_load_word::moddir_len, NULL, ast_module::running, and module_load_word::word.

Referenced by module_load_helper().

1330 {
1331  struct module_load_word *word = obj;
1332  struct ast_module *mod;
1333  char *filename_merged = NULL;
1334 
1335  /* dir_name will never be shorter than word->moddir_len. */
1336  dir_name += word->moddir_len;
1337  if (!ast_strlen_zero(dir_name)) {
1338  ast_assert(dir_name[0] == '/');
1339 
1340  dir_name += 1;
1341  if (ast_asprintf(&filename_merged, "%s/%s", dir_name, filename) < 0) {
1342  /* If we can't allocate the string just give up! */
1343  return -1;
1344  }
1345  filename = filename_merged;
1346  }
1347 
1348  if (!strncasecmp(filename, word->word, word->len)) {
1349  /* Don't list files that are already loaded! */
1350  mod = find_resource(filename, 0);
1351  if (!mod || !mod->flags.running) {
1353  }
1354  }
1355 
1356  ast_free(filename_merged);
1357 
1358  return 0;
1359 }
const char * word
Definition: loader.c:1324
unsigned int running
Definition: loader.c:320
#define ast_assert(a)
Definition: utils.h:695
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_strlen_zero(foo)
Definition: strings.h:52
size_t moddir_len
Definition: loader.c:1326
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:937
#define ast_free(a)
Definition: astmm.h:182
struct ast_module::@398 flags
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
short word

◆ module_matches_helper_type()

static int module_matches_helper_type ( struct ast_module mod,
enum ast_module_helper_type  type 
)
static

Definition at line 1299 of file loader.c.

References ast_assert, AST_MODULE_HELPER_LOADED, AST_MODULE_HELPER_RELOAD, AST_MODULE_HELPER_RUNNING, AST_MODULE_HELPER_UNLOAD, ast_module::declined, ast_module::flags, ast_module::info, ast_module_info::reload, ast_module::running, and ast_module::usecount.

Referenced by ast_module_helper().

1300 {
1301  switch (type) {
1303  return !mod->usecount && mod->flags.running && !mod->flags.declined;
1304 
1306  return mod->flags.running && mod->info->reload;
1307 
1309  return mod->flags.running;
1310 
1312  /* if we have a 'struct ast_module' then we're loaded. */
1313  return 1;
1314  default:
1315  /* This function is not called for AST_MODULE_HELPER_LOAD. */
1316  /* Unknown ast_module_helper_type. Assume it doesn't match. */
1317  ast_assert(0);
1318 
1319  return 0;
1320  }
1321 }
static const char type[]
Definition: chan_ooh323.c:109
unsigned int running
Definition: loader.c:320
int usecount
Definition: loader.c:300
#define ast_assert(a)
Definition: utils.h:695
const struct ast_module_info * info
Definition: loader.c:294
unsigned int declined
Definition: loader.c:322
int(* reload)(void)
Definition: module.h:346
struct ast_module::@398 flags

◆ module_post_register()

static int module_post_register ( struct ast_module mod)
static

Definition at line 732 of file loader.c.

References ast_vector_string_split(), ast_module::enhances, ast_module_info::enhances, ast_module::info, ast_module::optional_modules, ast_module_info::optional_modules, ast_module::requires, and ast_module_info::requires.

Referenced by load_dlopen(), load_resource(), and loader_builtin_init().

733 {
734  int res;
735 
736  /* Split lists from mod->info. */
737  res = ast_vector_string_split(&mod->requires, mod->info->requires, ",", 0, strcasecmp);
738  res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp);
739  res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp);
740 
741  return res;
742 }
const char * enhances
Modules that we provide enhanced functionality for.
Definition: module.h:406
const char * requires
Definition: module.h:373
struct ast_vector_string enhances
Definition: loader.c:309
const char * optional_modules
Comma-separated list of optionally required modules.
Definition: module.h:383
const struct ast_module_info * info
Definition: loader.c:294
struct ast_vector_string optional_modules
Definition: loader.c:307
struct ast_vector_string requires
Definition: loader.c:305
int ast_vector_string_split(struct ast_vector_string *dest, const char *input, const char *delim, int flags, int(*excludes_cmp)(const char *s1, const char *s2))
Append a string vector by splitting a string.
Definition: strings.c:393

◆ module_reffed_deps_add()

static int module_reffed_deps_add ( struct ast_module mod,
struct ast_module dep,
struct ast_vector_const_string *  missing 
)
static

Definition at line 416 of file loader.c.

References ast_module_ref, AST_VECTOR_APPEND, AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_GET_CMP, ast_module::flags, ast_module::info, ast_module_info::name, ast_module::reffed_deps, and ast_module::running.

Referenced by module_deps_process_reqlist(), and module_reffed_deps_add_dep_enhancers().

418 {
419  if (!dep->flags.running) {
420  return !missing ? -1 : AST_VECTOR_APPEND(missing, dep->info->name);
421  }
422 
424  /* Skip duplicate. */
425  return 0;
426  }
427 
428  if (AST_VECTOR_APPEND(&mod->reffed_deps, dep)) {
429  return -1;
430  }
431 
432  ast_module_ref(dep);
433 
434  return 0;
435 }
unsigned int running
Definition: loader.c:320
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
const char * name
Definition: module.h:350
const struct ast_module_info * info
Definition: loader.c:294
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
struct ast_module::@398 flags
struct module_vector reffed_deps
Vector holding pointers to modules we have a reference to.
Definition: loader.c:317
#define ast_module_ref(mod)
Hold a reference to the module.
Definition: module.h:443

◆ module_reffed_deps_add_dep_enhancers()

static int module_reffed_deps_add_dep_enhancers ( struct ast_module mod,
struct ast_module dep,
struct ast_vector_const_string *  missing 
)
static

Definition at line 448 of file loader.c.

References AST_DLLIST_TRAVERSE, AST_VECTOR_GET_CMP, ast_module::declined, ast_module::enhances, ast_module::flags, ast_module::info, module_reffed_deps_add(), and ast_module_info::name.

Referenced by module_deps_process_reqlist().

450 {
451  struct ast_module *cur;
452 
454  if (cur->flags.declined) {
455  continue;
456  }
457 
458  if (!AST_VECTOR_GET_CMP(&cur->enhances, dep->info->name, !strcasecmp)) {
459  /* dep is not enhanced by cur. */
460  continue;
461  }
462 
463  /* dep is enhanced by cur, therefore mod requires cur. */
464  if (module_reffed_deps_add(mod, cur, missing)) {
465  return -1;
466  }
467  }
468 
469  return 0;
470 }
struct ast_vector_string enhances
Definition: loader.c:309
const char * name
Definition: module.h:350
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
unsigned int declined
Definition: loader.c:322
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
Definition: search.h:40
struct ast_module::@398 flags
static int module_reffed_deps_add(struct ast_module *mod, struct ast_module *dep, struct ast_vector_const_string *missing)
Definition: loader.c:416

◆ module_vector_cmp()

static int module_vector_cmp ( struct ast_module a,
struct ast_module b 
)
static

Definition at line 371 of file loader.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEFAULT, ast_test_flag, find_resource(), ast_module::flags, ast_module::info, ast_module_info::load_pri, ast_module::preload, and ast_module::resource.

Referenced by load_resource(), and module_deps_missing_recursive().

372 {
373  int preload_diff = (int)b->flags.preload - (int)a->flags.preload;
374  /* if load_pri is not set, default is 128. Lower is better */
375  int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)
377  int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)
379 
380  if (preload_diff) {
381  /* -1 preload a but not b */
382  /* 0 preload both or neither */
383  /* 1 preload b but not a */
384  return preload_diff;
385  }
386 
387  /*
388  * Returns comparison values for a vector sorted by priority.
389  * <0 a_pri < b_pri
390  * =0 a_pri == b_pri
391  * >0 a_pri > b_pri
392  */
393  return a_pri - b_pri;
394 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int preload
Definition: loader.c:330
unsigned char load_pri
Definition: module.h:370
const struct ast_module_info * info
Definition: loader.c:294
struct ast_module::@398 flags

◆ module_vector_strcasecmp()

static int module_vector_strcasecmp ( struct ast_module a,
struct ast_module b 
)
static

Definition at line 366 of file loader.c.

References ast_module::resource.

Referenced by alpha_module_list_create().

367 {
368  return strcasecmp(a->resource, b->resource);
369 }
char resource[0]
Definition: loader.c:333

◆ modules_shutdown()

int modules_shutdown ( void  )

Provided by loader.c

Note
Some resources, like timers, are started up dynamically, and thus may be still in use, even if all channels are dead. We must therefore check the usecount before asking modules to unload.

Definition at line 1182 of file loader.c.

References ast_debug, AST_DLLIST_EMPTY, AST_DLLIST_LOCK, AST_DLLIST_REMOVE_CURRENT, AST_DLLIST_TRAVERSE, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN, AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END, AST_DLLIST_UNLOCK, ast_module_unref, ast_verb, ast_module::declined, ast_module::flags, ast_module::info, ast_module::keepuntilshutdown, module_destroy(), ast_module::resource, ast_module::running, ast_module_info::unload, and ast_module::usecount.

Referenced by really_quit().

1183 {
1184  struct ast_module *mod;
1185  int somethingchanged;
1186  int res;
1187 
1189 
1190  /*!\note Some resources, like timers, are started up dynamically, and thus
1191  * may be still in use, even if all channels are dead. We must therefore
1192  * check the usecount before asking modules to unload. */
1193  do {
1194  /* Reset flag before traversing the list */
1195  somethingchanged = 0;
1196 
1198  if (mod->usecount) {
1199  ast_debug(1, "Passing on %s: its use count is %d\n",
1200  mod->resource, mod->usecount);
1201  continue;
1202  }
1204  if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
1205  ast_verb(1, "Unloading %s\n", mod->resource);
1206  mod->info->unload();
1207  }
1208  module_destroy(mod);
1209  somethingchanged = 1;
1210  }
1212  if (!somethingchanged) {
1214  if (mod->flags.keepuntilshutdown) {
1215  ast_module_unref(mod);
1216  mod->flags.keepuntilshutdown = 0;
1217  somethingchanged = 1;
1218  }
1219  }
1220  }
1221  } while (somethingchanged);
1222 
1223  res = AST_DLLIST_EMPTY(&module_list);
1225 
1226  return !res;
1227 }
unsigned int running
Definition: loader.c:320
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static void module_destroy(struct ast_module *mod)
Definition: loader.c:744
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: dlinkedlists.h:887
int usecount
Definition: loader.c:300
#define AST_DLLIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: dlinkedlists.h:752
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const struct ast_module_info * info
Definition: loader.c:294
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: dlinkedlists.h:575
int(* unload)(void)
Definition: module.h:348
unsigned int declined
Definition: loader.c:322
#define AST_DLLIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: dlinkedlists.h:468
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
Closes a safe loop traversal block.
Definition: dlinkedlists.h:920
unsigned int keepuntilshutdown
Definition: loader.c:324
Definition: search.h:40
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45

◆ printdigest()

static int printdigest ( const unsigned char *  d)
static

Definition at line 875 of file loader.c.

References ast_debug, and buf.

Referenced by verify_key().

876 {
877  int x, pos;
878  char buf[256]; /* large enough so we don't have to worry */
879 
880  for (pos = 0, x = 0; x < 16; x++)
881  pos += sprintf(buf + pos, " %02hhx", *d++);
882 
883  ast_debug(1, "Unexpected signature:%s\n", buf);
884 
885  return 0;
886 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static struct test_val d
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

◆ publish_load_message()

static void publish_load_message ( const char *  name,
enum ast_module_load_result  result 
)
static

Definition at line 1531 of file loader.c.

References loadresult2str(), publish_load_message_type(), and status.

Referenced by load_resource().

1532 {
1533  const char *status;
1534 
1535  status = loadresult2str(result);
1536 
1537  publish_load_message_type("Load", name, status);
1538 }
static void publish_load_message_type(const char *type, const char *name, const char *status)
Definition: loader.c:1475
static const char * loadresult2str(enum ast_module_load_result result)
Definition: loader.c:1514
static const char name[]
Definition: cdr_mysql.c:74
static PGresult * result
Definition: cel_pgsql.c:88
jack_status_t status
Definition: app_jack.c:146

◆ publish_load_message_type()

static void publish_load_message_type ( const char *  type,
const char *  name,
const char *  status 
)
static
Since
12

Definition at line 1475 of file loader.c.

References ao2_cleanup, ast_assert, ast_json_pack(), ast_json_payload_create(), ast_json_ref(), ast_json_unref(), ast_manager_get_generic_type(), ast_manager_get_topic(), ast_strlen_zero, EVENT_FLAG_SYSTEM, NULL, RAII_VAR, stasis_message_create(), and stasis_publish().

Referenced by publish_load_message(), publish_reload_message(), and publish_unload_message().

1476 {
1478  RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
1479  RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1480  RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
1481 
1482  ast_assert(type != NULL);
1485 
1487  return;
1488  }
1489 
1490  event_object = ast_json_pack("{s:s, s:s}",
1491  "Module", name,
1492  "Status", status);
1493  json_object = ast_json_pack("{s:s, s:i, s:o}",
1494  "type", type,
1495  "class_type", EVENT_FLAG_SYSTEM,
1496  "event", ast_json_ref(event_object));
1497  if (!json_object) {
1498  return;
1499  }
1500 
1501  payload = ast_json_payload_create(json_object);
1502  if (!payload) {
1503  return;
1504  }
1505 
1507  if (!message) {
1508  return;
1509  }
1510 
1512 }
static const char type[]
Definition: chan_ooh323.c:109
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition: json.c:735
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
struct stasis_message_type * ast_manager_get_generic_type(void)
Get the stasis_message_type for generic messages.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1511
static const char name[]
Definition: cdr_mysql.c:74
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1720
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Abstract JSON element (object, array, string, int, ...).
jack_status_t status
Definition: app_jack.c:146

◆ publish_reload_message()

static void publish_reload_message ( const char *  name,
enum ast_module_reload_result  result 
)
static
Since
12

Definition at line 1554 of file loader.c.

References publish_load_message_type(), and S_OR.

Referenced by ast_module_reload().

1555 {
1556  char res_buffer[8];
1557 
1558  snprintf(res_buffer, sizeof(res_buffer), "%u", result);
1559  publish_load_message_type("Reload", S_OR(name, "All"), res_buffer);
1560 }
static void publish_load_message_type(const char *type, const char *name, const char *status)
Definition: loader.c:1475
static const char name[]
Definition: cdr_mysql.c:74
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static PGresult * result
Definition: cel_pgsql.c:88

◆ publish_unload_message()

static void publish_unload_message ( const char *  name,
const char *  status 
)
static

Definition at line 1544 of file loader.c.

References publish_load_message_type().

Referenced by ast_unload_resource().

1545 {
1547 }
static void publish_load_message_type(const char *type, const char *name, const char *status)
Definition: loader.c:1475
static const char name[]
Definition: cdr_mysql.c:74
jack_status_t status
Definition: app_jack.c:146

◆ queue_reload_request()

static void queue_reload_request ( const char *  module)
static

Definition at line 1432 of file loader.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_strlen_zero, item, LOG_ERROR, and reload_queue_item::module.

Referenced by ast_module_reload().

1433 {
1434  struct reload_queue_item *item;
1435 
1437 
1438  if (do_full_reload) {
1440  return;
1441  }
1442 
1443  if (ast_strlen_zero(module)) {
1444  /* A full reload request (when module is NULL) wipes out any previous
1445  reload requests and causes the queue to ignore future ones */
1446  while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1447  ast_free(item);
1448  }
1449  do_full_reload = 1;
1450  } else {
1451  /* No reason to add the same module twice */
1453  if (!strcasecmp(item->module, module)) {
1455  return;
1456  }
1457  }
1458  item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
1459  if (!item) {
1460  ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
1462  return;
1463  }
1464  strcpy(item->module, module);
1466  }
1468 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static struct aco_type item
Definition: test_config.c:1463
#define ast_strlen_zero(foo)
Definition: strings.h:52
char module[0]
Definition: loader.c:635
#define ast_log
Definition: astobj2.c:42
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int do_full_reload
Definition: loader.c:638
Definition: search.h:40

◆ resource_list_recursive_decline()

static int resource_list_recursive_decline ( struct module_vector *  resources,
struct ast_module mod,
struct ast_str **  printmissing 
)
static

Definition at line 1906 of file loader.c.

References ast_module_name(), ast_str_buffer(), ast_str_create, ast_str_reset(), AST_VECTOR_APPEND, AST_VECTOR_CALLBACK_VOID, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_GET_CMP, AST_VECTOR_INIT, AST_VECTOR_RESET, AST_VECTOR_SIZE, ast_module::declined, ast_module::flags, module_deps_missing_recursive(), module_load_error(), ast_module::required, and STR_APPEND_TEXT.

Referenced by start_resource_list().

1908 {
1909  struct module_vector missingdeps;
1910  struct ast_vector_const_string localdeps;
1911  int i = 0;
1912  int res = -1;
1913 
1914  mod->flags.declined = 1;
1915  if (mod->flags.required) {
1916  module_load_error("Required module %s declined to load.\n", ast_module_name(mod));
1917 
1918  return -2;
1919  }
1920 
1921  module_load_error("%s declined to load.\n", ast_module_name(mod));
1922 
1923  if (!*printmissing) {
1924  *printmissing = ast_str_create(64);
1925  if (!*printmissing) {
1926  return -1;
1927  }
1928  } else {
1929  ast_str_reset(*printmissing);
1930  }
1931 
1932  AST_VECTOR_INIT(&missingdeps, 0);
1933  AST_VECTOR_INIT(&localdeps, 0);
1934 
1935  /* Decline everything that depends on 'mod' from resources so we can
1936  * print a concise list. */
1937  while (res != -2 && i < AST_VECTOR_SIZE(resources)) {
1938  struct ast_module *dep = AST_VECTOR_GET(resources, i);
1939  i++;
1940 
1942  if (dep->flags.declined || module_deps_missing_recursive(dep, &missingdeps)) {
1943  continue;
1944  }
1945 
1946  if (AST_VECTOR_GET_CMP(&missingdeps, mod, AST_VECTOR_ELEM_DEFAULT_CMP)) {
1947  dep->flags.declined = 1;
1948  if (dep->flags.required) {
1949  module_load_error("Cannot load required module %s that depends on %s\n",
1950  ast_module_name(dep), ast_module_name(mod));
1951  res = -2;
1952  } else {
1953  AST_VECTOR_APPEND(&localdeps, ast_module_name(dep));
1954  }
1955  }
1956  }
1957  AST_VECTOR_FREE(&missingdeps);
1958 
1959  if (res != -2 && AST_VECTOR_SIZE(&localdeps)) {
1960  AST_VECTOR_CALLBACK_VOID(&localdeps, STR_APPEND_TEXT, printmissing);
1961  module_load_error("Declined modules which depend on %s: %s\n",
1962  ast_module_name(mod), ast_str_buffer(*printmissing));
1963  }
1964  AST_VECTOR_FREE(&localdeps);
1965 
1966  return res;
1967 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
unsigned int required
Definition: loader.c:328
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
Recursively find required dependencies that are not running.
Definition: loader.c:566
#define STR_APPEND_TEXT(txt, str)
Definition: loader.c:144
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
unsigned int declined
Definition: loader.c:322
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:627
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:733
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:615
struct ast_module::@398 flags
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ resource_name_baselen()

static size_t resource_name_baselen ( const char *  name)
static

Definition at line 917 of file loader.c.

References len().

Referenced by add_to_load_order(), ast_module_reload(), find_resource(), loader_config_init(), and resource_name_match().

918 {
919  size_t len = strlen(name);
920 
921  if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
922  return len - 3;
923  }
924 
925  return len;
926 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
Definition: cdr_mysql.c:74

◆ resource_name_match()

static int resource_name_match ( const char *  name1,
size_t  baselen1,
const char *  name2 
)
static

Definition at line 928 of file loader.c.

References resource_name_baselen().

Referenced by add_to_load_order(), ast_module_reload(), find_resource(), and loader_config_init().

929 {
930  if (baselen1 != resource_name_baselen(name2)) {
931  return -1;
932  }
933 
934  return strncasecmp(name1, name2, baselen1);
935 }
static size_t resource_name_baselen(const char *name)
Definition: loader.c:917

◆ start_resource()

static enum ast_module_load_result start_resource ( struct ast_module mod)
static

Definition at line 1678 of file loader.c.

References AST_DLLIST_INSERT_TAIL, AST_DLLIST_LOCK, AST_DLLIST_REMOVE, AST_DLLIST_UNLOCK, ast_fully_booted, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_module_shutdown_ref, ast_update_use_count(), AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_SIZE, ast_verb, ast_module::builtin, COLOR_BLACK, COLOR_BROWN, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, ast_module_info::load, module_deps_missing_recursive(), module_deps_reference(), module_load_error(), ast_module_info::name, NULL, ast_module::required, ast_module::resource, ast_module::running, term_color(), and tmp().

Referenced by load_resource(), and start_resource_attempt().

1679 {
1680  char tmp[256];
1681  enum ast_module_load_result res;
1682 
1683  if (mod->flags.running) {
1684  return AST_MODULE_LOAD_SUCCESS;
1685  }
1686 
1687  if (!mod->info->load) {
1688  mod->flags.declined = 1;
1689 
1691  }
1692 
1693  if (module_deps_reference(mod, NULL)) {
1694  struct module_vector missing;
1695  int i;
1696 
1697  AST_VECTOR_INIT(&missing, 0);
1698  if (module_deps_missing_recursive(mod, &missing)) {
1699  module_load_error("%s has one or more unknown dependencies.\n", mod->info->name);
1700  }
1701  for (i = 0; i < AST_VECTOR_SIZE(&missing); i++) {
1702  module_load_error("%s loaded before dependency %s!\n", mod->info->name,
1703  AST_VECTOR_GET(&missing, i)->info->name);
1704  }
1705  AST_VECTOR_FREE(&missing);
1706 
1707  return AST_MODULE_LOAD_DECLINE;
1708  }
1709 
1710  if (!ast_fully_booted) {
1711  ast_verb(1, "Loading %s.\n", mod->resource);
1712  }
1713  res = mod->info->load();
1714 
1715  switch (res) {
1717  if (!ast_fully_booted) {
1718  ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1719  } else {
1720  ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1721  }
1722 
1723  mod->flags.running = 1;
1724  if (mod->flags.builtin) {
1725  /* Built-in modules cannot be unloaded. */
1727  }
1728 
1730  break;
1732  mod->flags.declined = 1;
1733  if (mod->flags.required) {
1735  }
1736  break;
1738  mod->flags.declined = 1;
1739  break;
1740  case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1742  break;
1743  }
1744 
1745  /* Make sure the newly started module is at the end of the list */
1750 
1751  return res;
1752 }
const char * description
Definition: module.h:352
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
ast_module_load_result
Definition: module.h:68
unsigned int running
Definition: loader.c:320
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:2528
unsigned int required
Definition: loader.c:328
#define AST_DLLIST_UNLOCK(head)
Attempts to unlock a list.
Definition: dlinkedlists.h:122
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
Recursively find required dependencies that are not running.
Definition: loader.c:566
#define ast_verb(level,...)
Definition: logger.h:463
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
#define AST_DLLIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
const char * name
Definition: module.h:350
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
const struct ast_module_info * info
Definition: loader.c:294
#define ast_fully_booted
Definition: options.h:115
unsigned int declined
Definition: loader.c:322
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
Definition: term.c:184
#define COLOR_BLACK
Definition: term.h:47
def info(msg)
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Definition: module.h:464
Module could not be loaded properly.
Definition: module.h:102
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
unsigned int builtin
Definition: loader.c:326
static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
Definition: loader.c:534
#define AST_DLLIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: search.h:40
struct ast_module::@398 flags
enum ast_module_load_result(* load)(void)
Definition: module.h:344
#define COLOR_BROWN
Definition: term.h:53
char resource[0]
Definition: loader.c:333
#define AST_DLLIST_LOCK(head)
Locks a list.
Definition: dlinkedlists.h:45
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611

◆ start_resource_attempt()

static enum ast_module_load_result start_resource_attempt ( struct ast_module mod,
int *  count 
)
static

Definition at line 1878 of file loader.c.

References ast_debug, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_DEFAULT, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_test_flag, ast_module::flags, ast_module::info, ast_module_info::load_pri, module_deps_reference(), module_load_error(), NULL, ast_module::required, ast_module::resource, and start_resource().

Referenced by start_resource_list().

1879 {
1880  enum ast_module_load_result lres;
1881 
1882  /* Try to grab required references. */
1883  if (module_deps_reference(mod, NULL)) {
1884  /* We're likely to retry so not an error. */
1885  ast_debug(1, "Module %s is missing dependencies\n", mod->resource);
1886  return AST_MODULE_LOAD_SKIP;
1887  }
1888 
1889  lres = start_resource(mod);
1890  ast_debug(3, "START: %-46s[%d] %d\n",
1891  mod->resource,
1893  lres);
1894 
1895  if (lres == AST_MODULE_LOAD_SUCCESS) {
1896  (*count)++;
1897  } else if (lres == AST_MODULE_LOAD_FAILURE) {
1898  module_load_error("*** Failed to load %smodule %s\n",
1899  mod->flags.required ? "required " : "",
1900  mod->resource);
1901  }
1902 
1903  return lres;
1904 }
static enum ast_module_load_result start_resource(struct ast_module *mod)
Definition: loader.c:1678
ast_module_load_result
Definition: module.h:68
unsigned int required
Definition: loader.c:328
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned char load_pri
Definition: module.h:370
#define NULL
Definition: resample.c:96
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const struct ast_module_info * info
Definition: loader.c:294
Module could not be loaded properly.
Definition: module.h:102
static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
Definition: loader.c:534
struct ast_module::@398 flags
char resource[0]
Definition: loader.c:333

◆ start_resource_list()

static int start_resource_list ( struct module_vector *  resources,
int *  mod_count 
)
static

Definition at line 1969 of file loader.c.

References ast_debug, ast_free, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_module_name(), ast_str_buffer(), ast_str_create, ast_str_reset(), AST_VECTOR_CALLBACK_VOID, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_FREE, AST_VECTOR_GET, AST_VECTOR_INIT, AST_VECTOR_REMOVE, AST_VECTOR_REMOVE_CMP_ORDERED, AST_VECTOR_RESET, AST_VECTOR_SIZE, ast_module::declined, ast_module::flags, module_deps_missing_recursive(), module_deps_reference(), module_load_error(), NULL, resource_list_recursive_decline(), start_resource_attempt(), and STR_APPEND_TEXT.

Referenced by load_resource_list().

1970 {
1971  struct module_vector missingdeps;
1972  int res = 0;
1973  struct ast_str *printmissing = NULL;
1974 
1975  AST_VECTOR_INIT(&missingdeps, 0);
1976  while (res != -2 && AST_VECTOR_SIZE(resources)) {
1977  struct ast_module *mod = AST_VECTOR_REMOVE(resources, 0, 1);
1978  enum ast_module_load_result lres;
1979 
1980  if (mod->flags.declined) {
1981  ast_debug(1, "%s is already declined, skipping\n", ast_module_name(mod));
1982  continue;
1983  }
1984 
1985 retry_load:
1986  lres = start_resource_attempt(mod, mod_count);
1987  if (lres == AST_MODULE_LOAD_SUCCESS) {
1988  /* No missing dependencies, successful. */
1989  continue;
1990  }
1991 
1992  if (lres == AST_MODULE_LOAD_FAILURE) {
1993  res = -2;
1994  break;
1995  }
1996 
1997  if (lres == AST_MODULE_LOAD_DECLINE) {
1998  res = resource_list_recursive_decline(resources, mod, &printmissing);
1999  continue;
2000  }
2001 
2002  if (module_deps_missing_recursive(mod, &missingdeps)) {
2004  module_load_error("Failed to resolve dependencies for %s\n", ast_module_name(mod));
2005  res = resource_list_recursive_decline(resources, mod, &printmissing);
2006  continue;
2007  }
2008 
2009  if (!AST_VECTOR_SIZE(&missingdeps)) {
2010  module_load_error("%s load function returned an invalid result. "
2011  "This is a bug in the module.\n", ast_module_name(mod));
2012  /* Dependencies were met but the module failed to start and the result
2013  * code was not AST_MODULE_LOAD_FAILURE or AST_MODULE_LOAD_DECLINE. */
2014  res = resource_list_recursive_decline(resources, mod, &printmissing);
2015  continue;
2016  }
2017 
2018  ast_debug(1, "%s has %d dependencies\n",
2019  ast_module_name(mod), (int)AST_VECTOR_SIZE(&missingdeps));
2020  while (AST_VECTOR_SIZE(&missingdeps)) {
2021  int didwork = 0;
2022  int i = 0;
2023 
2024  while (i < AST_VECTOR_SIZE(&missingdeps)) {
2025  struct ast_module *dep = AST_VECTOR_GET(&missingdeps, i);
2026 
2027  if (dep->flags.declined) {
2028  ast_debug(1, "%s tried to start %s but it's already declined\n",
2029  ast_module_name(mod), ast_module_name(dep));
2030  i++;
2031  continue;
2032  }
2033 
2034  ast_debug(1, "%s trying to start %s\n", ast_module_name(mod), ast_module_name(dep));
2035  lres = start_resource_attempt(dep, mod_count);
2036  if (lres == AST_MODULE_LOAD_SUCCESS) {
2037  ast_debug(1, "%s started %s\n", ast_module_name(mod), ast_module_name(dep));
2038  AST_VECTOR_REMOVE(&missingdeps, i, 1);
2039  AST_VECTOR_REMOVE_CMP_ORDERED(resources, dep,
2041  didwork++;
2042  continue;
2043  }
2044 
2045  if (lres == AST_MODULE_LOAD_FAILURE) {
2046  module_load_error("Failed to load %s.\n", ast_module_name(dep));
2047  res = -2;
2048  goto exitpoint;
2049  }
2050 
2051  ast_debug(1, "%s failed to start %s\n", ast_module_name(mod), ast_module_name(dep));
2052  i++;
2053  }
2054 
2055  if (!didwork) {
2056  break;
2057  }
2058  }
2059 
2060  if (AST_VECTOR_SIZE(&missingdeps)) {
2061  if (!printmissing) {
2062  printmissing = ast_str_create(64);
2063  } else {
2064  ast_str_reset(printmissing);
2065  }
2066 
2067  if (printmissing) {
2068  struct ast_vector_const_string localdeps;
2069 
2070  AST_VECTOR_INIT(&localdeps, 0);
2071  module_deps_reference(mod, &localdeps);
2072  AST_VECTOR_CALLBACK_VOID(&localdeps, STR_APPEND_TEXT, &printmissing);
2073  AST_VECTOR_FREE(&localdeps);
2074  }
2075 
2076  module_load_error("Failed to load %s due to dependencies: %s.\n",
2077  ast_module_name(mod),
2078  printmissing ? ast_str_buffer(printmissing) : "allocation failure creating list");
2079  res = resource_list_recursive_decline(resources, mod, &printmissing);
2080 
2082 
2083  continue;
2084  }
2085 
2086  /* If we're here it means that we started with missingdeps and they're all loaded
2087  * now. It's impossible to reach this point a second time for the same module. */
2088  goto retry_load;
2089  }
2090 
2091 exitpoint:
2092  ast_free(printmissing);
2093  AST_VECTOR_FREE(&missingdeps);
2094 
2095  return res;
2096 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
ast_module_load_result
Definition: module.h:68
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define NULL
Definition: resample.c:96
static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
Recursively find required dependencies that are not running.
Definition: loader.c:566
#define STR_APPEND_TEXT(txt, str)
Definition: loader.c:144
static void module_load_error(const char *fmt,...)
Definition: loader.c:269
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
unsigned int declined
Definition: loader.c:322
static int resource_list_recursive_decline(struct module_vector *resources, struct ast_module *mod, struct ast_str **printmissing)
Definition: loader.c:1906
static enum ast_module_load_result start_resource_attempt(struct ast_module *mod, int *count)
Definition: loader.c:1878
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:627
Module could not be loaded properly.
Definition: module.h:102
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order...
Definition: vector.h:540
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:653
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:615
static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
Definition: loader.c:534
struct ast_module::@398 flags
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
Definition: vector.h:865
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ unload_dynamic_module()

static void unload_dynamic_module ( struct ast_module mod)
static

Definition at line 1010 of file loader.c.

References ast_log, ast_module_name(), ast_strdupa, is_module_loaded(), ast_module::lib, LOG_WARNING, logged_dlclose(), and name.

Referenced by ast_unload_resource(), load_dlopen(), and load_resource().

1011 {
1012 #if defined(HAVE_RTLD_NOLOAD)
1013  char *name = ast_strdupa(ast_module_name(mod));
1014 #endif
1015  void *lib = mod->lib;
1016 
1017  /* WARNING: the structure pointed to by mod is going to
1018  disappear when this operation succeeds, so we can't
1019  dereference it */
1020  logged_dlclose(ast_module_name(mod), lib);
1021 
1022  /* There are several situations where the module might still be resident
1023  * in memory.
1024  *
1025  * If somehow there was another dlopen() on the same module (unlikely,
1026  * since that all is supposed to happen in loader.c).
1027  *
1028  * Avoid the temptation of repeating the dlclose(). The other code that
1029  * dlopened the module still has its module reference, and should close
1030  * it itself. In other situations, dlclose() will happily return success
1031  * for as many times as you wish to call it.
1032  */
1033 #if defined(HAVE_RTLD_NOLOAD)
1034  if (is_module_loaded(name)) {
1035  ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
1036  }
1037 #endif
1038 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static void logged_dlclose(const char *name, void *lib)
dlclose(), with failure logging.
Definition: loader.c:962
static const char name[]
Definition: cdr_mysql.c:74
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:615
void * lib
Definition: loader.c:298
static int is_module_loaded(const char *resource_name)
Check to see if the given resource is loaded.
Definition: loader.c:991

◆ verify_key()

static int verify_key ( const unsigned char *  key)
static

Definition at line 900 of file loader.c.

References expected_key, key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().

Referenced by inspect_module().

901 {
902  struct MD5Context c;
903  unsigned char digest[16];
904 
905  MD5Init(&c);
906  MD5Update(&c, key, strlen((char *)key));
907  MD5Final(digest, &c);
908 
909  if (key_matches(expected_key, digest))
910  return 0;
911 
912  printdigest(digest);
913 
914  return -1;
915 }
static int key_matches(const unsigned char *key1, const unsigned char *key2)
Definition: loader.c:888
static const unsigned char expected_key[]
Definition: loader.c:134
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:120
static struct test_val c
void MD5Init(struct MD5Context *context)
Definition: md5.c:57
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:72
Definition: md5.h:26
static int printdigest(const unsigned char *d)
Definition: loader.c:875

Variable Documentation

◆ buildopt_sum

char buildopt_sum[33] = AST_BUILDOPT_SUM
static

Definition at line 138 of file loader.c.

Referenced by inspect_module().

◆ builtin_module_list

struct module_list builtin_module_list
static

Definition at line 364 of file loader.c.

Referenced by ast_module_register(), and loader_builtin_init().

◆ do_full_reload

int do_full_reload = 0
static

Definition at line 638 of file loader.c.

◆ expected_key

const unsigned char expected_key[]
static
Initial value:
=
{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 }

Definition at line 134 of file loader.c.

Referenced by verify_key().

◆ load_results

const struct load_results_map load_results[]
static

Definition at line 344 of file loader.c.

◆ loader_ready

unsigned int loader_ready
static

Definition at line 150 of file loader.c.

Referenced by ast_module_register(), and loader_builtin_init().

◆ module_list

struct module_list module_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ modules_loaded

int modules_loaded
static

Internal flag to indicate all modules have been initially loaded.

Definition at line 291 of file loader.c.

◆ reload_queue

struct reload_queue reload_queue = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static

◆ reloadlock

ast_mutex_t reloadlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 631 of file loader.c.

Referenced by ast_module_reload().

◆ resource_being_loaded

struct ast_module* volatile resource_being_loaded
static

Definition at line 650 of file loader.c.

Referenced by ast_module_register().

◆ startup_error_builder

struct ast_str* startup_error_builder
static

Definition at line 154 of file loader.c.

◆ startup_errors

struct ast_vector_string startup_errors
static

String container for deferring output of startup errors.

Definition at line 153 of file loader.c.

Referenced by load_modules(), and module_load_error().

◆ support_level_map

const char* support_level_map[]

Definition at line 2748 of file loader.c.

◆ updaters

struct updaters updaters = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
static