Wed Jan 8 2020 09:50:14

Asterisk developer's documentation


loader.c File Reference

Module Loader. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include <dirent.h>
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/term.h"
#include "asterisk/manager.h"
#include "asterisk/cdr.h"
#include "asterisk/enum.h"
#include "asterisk/http.h"
#include "asterisk/lock.h"
#include "asterisk/features.h"
#include "asterisk/dsp.h"
#include "asterisk/udptl.h"
#include "asterisk/heap.h"
#include "asterisk/app.h"
#include "asterisk/test.h"
#include <dlfcn.h>
#include "asterisk/md5.h"
#include "asterisk/utils.h"

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  loadupdate
 
struct  module_list
 
struct  module_user_list
 
struct  reload_classes
 
struct  reload_queue
 
struct  reload_queue_item
 
struct  updaters
 

Macros

#define RTLD_LOCAL   0
 
#define RTLD_NOW   0
 

Functions

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 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, int needsreload)
 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...
 
struct ast_moduleast_module_ref (struct ast_module *mod)
 
void ast_module_register (const struct ast_module_info *info)
 
int ast_module_reload (const char *name)
 Reload asterisk modules. More...
 
void ast_module_shutdown (void)
 Run the unload() callback for all loaded modules. More...
 
void ast_module_unref (struct ast_module *mod)
 
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 *like), const char *like)
 Ask for a list of modules, descriptions, and use counts. More...
 
void ast_update_use_count (void)
 Notify when usecount has been changed. More...
 
static void close_lib (const char *name, void *lib)
 
static struct ast_modulefind_resource (const char *resource, int do_lock)
 
static unsigned int inspect_module (const struct ast_module *mod)
 
static int key_matches (const unsigned char *key1, const unsigned char *key2)
 
static struct ast_moduleload_dynamic_module (const char *resource_in, unsigned int global_symbols_only, struct ast_heap *resource_heap)
 
int load_modules (unsigned int preload_only)
 
static enum ast_module_load_result load_resource (const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
 
static int load_resource_list (struct load_order *load_order, unsigned int global_symbols, int *mod_count)
 
static int mod_load_cmp (void *a, void *b)
 
static int printdigest (const unsigned char *d)
 
static void queue_reload_request (const char *module)
 
static int resource_name_match (const char *name1_in, const char *name2_in)
 
static enum ast_module_load_result start_resource (struct ast_module *mod)
 
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 int do_full_reload = 0
 
static struct module_list embedded_module_list
 
static unsigned int embedding = 1
 
static const unsigned char expected_key []
 
static struct module_list module_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static struct reload_classes reload_classes []
 
static struct reload_queue reload_queue = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 
static ast_mutex_t reloadlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static struct ast_moduleresource_being_loaded
 
static struct updaters updaters = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
 

Detailed Description

Module Loader.

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

Definition in file loader.c.

Macro Definition Documentation

#define RTLD_LOCAL   0

Definition at line 69 of file loader.c.

Referenced by load_dynamic_module().

#define RTLD_NOW   0

Definition at line 65 of file loader.c.

Referenced by load_dynamic_module().

Function Documentation

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

Definition at line 209 of file loader.c.

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

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

210 {
211  struct ast_module_user *u;
212 
213  u = ast_calloc(1, sizeof(*u));
214  if (!u) {
215  return NULL;
216  }
217 
218  u->chan = chan;
219 
220  AST_LIST_LOCK(&mod->users);
221  AST_LIST_INSERT_HEAD(&mod->users, u, entry);
222  AST_LIST_UNLOCK(&mod->users);
223 
225 
227 
228  return u;
229 }
struct module_user_list users
Definition: loader.c:93
#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
struct ast_module_user::@276 entry
int usecount
Definition: loader.c:92
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
struct ast_channel * chan
Definition: loader.c:73
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_calloc(a, b)
Definition: astmm.h:82
void __ast_module_user_hangup_all ( struct ast_module mod)

Definition at line 254 of file loader.c.

References 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::usecount, and ast_module::users.

Referenced by ast_unload_resource().

255 {
256  struct ast_module_user *u;
257 
258  AST_LIST_LOCK(&mod->users);
259  while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
260  if (u->chan) {
262  }
264  ast_free(u);
265  }
266  AST_LIST_UNLOCK(&mod->users);
267 
269 }
struct module_user_list users
Definition: loader.c:93
#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
struct ast_module_user::@276 entry
int usecount
Definition: loader.c:92
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct ast_channel * chan
Definition: loader.c:73
#define ast_free(a)
Definition: astmm.h:97
void __ast_module_user_remove ( struct ast_module mod,
struct ast_module_user u 
)

Definition at line 231 of file loader.c.

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

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

232 {
233  if (!u) {
234  return;
235  }
236 
237  AST_LIST_LOCK(&mod->users);
238  u = AST_LIST_REMOVE(&mod->users, u, entry);
239  AST_LIST_UNLOCK(&mod->users);
240  if (!u) {
241  /*
242  * Was not in the list. Either a bad pointer or
243  * __ast_module_user_hangup_all() has been called.
244  */
245  return;
246  }
247 
249  ast_free(u);
250 
252 }
struct module_user_list users
Definition: loader.c:93
#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
struct ast_module_user::@276 entry
int usecount
Definition: loader.c:92
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
Definition: linkedlists.h:841
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
#define ast_free(a)
Definition: astmm.h:97
static struct load_order_entry* add_to_load_order ( const char *  resource,
struct load_order load_order,
int  required 
)
static

Definition at line 968 of file loader.c.

References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdup, load_order_entry::required, load_order_entry::resource, and resource_name_match().

Referenced by load_modules().

969 {
970  struct load_order_entry *order;
971 
972  AST_LIST_TRAVERSE(load_order, order, entry) {
973  if (!resource_name_match(order->resource, resource)) {
974  /* Make sure we have the proper setting for the required field
975  (we might have both load= and required= lines in modules.conf) */
976  order->required |= required;
977  return NULL;
978  }
979  }
980 
981  if (!(order = ast_calloc(1, sizeof(*order))))
982  return NULL;
983 
984  order->resource = ast_strdup(resource);
985  order->required = required;
986  AST_LIST_INSERT_TAIL(load_order, order, entry);
987 
988  return order;
989 }
#define ast_strdup(a)
Definition: astmm.h:109
Definition: loader.c:960
static int resource_name_match(const char *name1_in, const char *name2_in)
Definition: loader.c:338
int required
Definition: loader.c:962
char * resource
Definition: loader.c:961
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_calloc(a, b)
Definition: astmm.h:82
struct load_order_entry::@281 entry
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 947 of file loader.c.

References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_test_suite_event_notify, and load_resource().

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

948 {
949  int res;
951  res = load_resource(resource_name, 0, NULL, 0);
952  if (!res) {
953  ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
954  }
956 
957  return res;
958 }
#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 enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
Definition: loader.c:893
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
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 1268 of file loader.c.

References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_malloc, and loadupdate::updater.

1269 {
1270  struct loadupdate *tmp;
1271 
1272  if (!(tmp = ast_malloc(sizeof(*tmp))))
1273  return -1;
1274 
1275  tmp->updater = v;
1279 
1280  return 0;
1281 }
#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
int(* updater)(void)
Definition: loader.c:122
struct loadupdate::@279 entry
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
#define ast_malloc(a)
Definition: astmm.h:91
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 1283 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.

1284 {
1285  struct loadupdate *cur;
1286 
1289  if (cur->updater == v) {
1291  break;
1292  }
1293  }
1296 
1297  return cur ? 0 : -1;
1298 }
#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
int(* updater)(void)
Definition: loader.c:122
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
struct loadupdate::@279 entry
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
int ast_module_check ( const char *  name)

Check if module exists.

Check if module with the name given is loaded.

Definition at line 1255 of file loader.c.

References ast_strlen_zero(), and find_resource().

Referenced by ifmodule_read(), load_module(), manager_modulecheck(), and unload_module().

1256 {
1257  struct ast_module *cur;
1258 
1259  if (ast_strlen_zero(name))
1260  return 0; /* FALSE */
1261 
1262  cur = find_resource(name, 1);
1263 
1264  return (cur != NULL);
1265 }
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:356
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char name[]
char* ast_module_helper ( const char *  line,
const char *  word,
int  pos,
int  state,
int  rpos,
int  needsreload 
)

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.
needsreloadThis should be 1 if we need to reload this module and 0 otherwise. This function will only return modules that are reloadble if this is 1.
Return values
Apossible completion of the partial match.
NULLif no matches were found.

Definition at line 626 of file loader.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_module::info, name, reload_classes::name, ast_module_info::reload, and ast_module::resource.

Referenced by conf_run(), handle_modlist(), handle_reload(), handle_unload(), and load_module().

627 {
628  struct ast_module *cur;
629  int i, which=0, l = strlen(word);
630  char *ret = NULL;
631 
632  if (pos != rpos)
633  return NULL;
634 
637  if (!strncasecmp(word, cur->resource, l) &&
638  (cur->info->reload || !needsreload) &&
639  ++which > state) {
640  ret = ast_strdup(cur->resource);
641  break;
642  }
643  }
645 
646  if (!ret) {
647  for (i=0; !ret && reload_classes[i].name; i++) {
648  if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
649  ret = ast_strdup(reload_classes[i].name);
650  }
651  }
652 
653  return ret;
654 }
struct ast_module::@278 entry
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define ast_strdup(a)
Definition: astmm.h:109
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
const char * name
Definition: loader.c:277
Definition: ael.tab.c:203
int(* reload)(void)
Definition: module.h:229
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
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 104 of file loader.c.

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

105 {
106  if (!mod || !mod->info) {
107  return NULL;
108  }
109 
110  return mod->info->name;
111 }
const char * name
Definition: module.h:233
struct ast_module_info * info
Definition: loader.c:90
struct ast_module* ast_module_ref ( struct ast_module mod)

Definition at line 1300 of file loader.c.

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

Referenced by __oh323_new(), agi_handle_command(), alsa_new(), ast_agi_register(), ast_app_exec_sub(), ast_app_expand_sub_args(), ast_fax_tech_register(), ast_iax2_new(), ast_rtp_instance_new(), ast_srtp_create(), ast_timer_open(), dahdi_new(), dahdi_pri_cc_agent_init(), data_result_generate_node(), fax_session_new(), fax_session_reserve(), find_best_technology(), fn_wrapper(), gtalk_new(), handle_cli_file_convert(), handle_orig(), load_module(), local_alloc(), mgcp_new(), mixmonitor_exec(), moh_alloc(), moh_files_alloc(), mute_add_audiohook(), my_module_ref(), newpvt(), oss_new(), phone_check_exception(), phone_new(), sip_handle_cc(), sip_new(), skinny_new(), and smdi_load().

1301 {
1302  if (!mod) {
1303  return NULL;
1304  }
1305 
1306  ast_atomic_fetchadd_int(&mod->usecount, +1);
1308 
1309  return mod;
1310 }
int usecount
Definition: loader.c:92
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
void ast_module_register ( const struct ast_module_info info)

Definition at line 147 of file loader.c.

References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, embedded_module_list, embedding, ast_module::info, ast_module::resource, resource_being_loaded, and ast_module::users.

148 {
149  struct ast_module *mod;
150 
151  if (embedding) {
152  if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
153  return;
154  strcpy(mod->resource, info->name);
155  } else {
156  mod = resource_being_loaded;
157  }
158 
159  mod->info = info;
160  AST_LIST_HEAD_INIT(&mod->users);
161 
162  /* during startup, before the loader has been initialized,
163  there are no threads, so there is no need to take the lock
164  on this list to manipulate it. it is also possible that it
165  might be unsafe to use the list lock at that point... so
166  let's avoid it altogether
167  */
168  if (embedding) {
170  } else {
172  /* it is paramount that the new entry be placed at the tail of
173  the list, otherwise the code that uses dlopen() to load
174  dynamic modules won't be able to find out if the module it
175  just opened was registered or failed to load
176  */
179  }
180 
181  /* give the module a copy of its own handle, for later use in registrations and the like */
182  *((struct ast_module **) &(info->self)) = mod;
183 }
struct module_user_list users
Definition: loader.c:93
struct ast_module::@278 entry
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
static struct ast_module * resource_being_loaded
Definition: loader.c:143
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
const char * name
Definition: module.h:233
struct ast_module * self
Definition: module.h:227
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:611
static struct module_list embedded_module_list
Definition: loader.c:119
#define ast_calloc(a, b)
Definition: astmm.h:82
static unsigned int embedding
Definition: loader.c:85
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
int 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.
Returns
0 if the specified module was not found.
Return values
1if the module was found but cannot be reloaded.
-1if a reload operation is already in progress.
2if the specfied module was found and reloaded.

Definition at line 721 of file loader.c.

References ast_config_AST_CONFIG_DIR, ast_fully_booted, ast_lastreloadtime, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_lock_path(), AST_LOCK_SUCCESS, AST_LOCK_TIMEOUT, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_opt_lock_confdir, ast_test_suite_event_notify, ast_tvnow(), ast_unlock_path(), ast_verb, ast_verbose(), ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, LOG_NOTICE, LOG_WARNING, reload_classes::name, queue_reload_request(), ast_module_info::reload, ast_module::resource, resource_name_match(), and ast_module::running.

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

722 {
723  struct ast_module *cur;
724  int res = 0; /* return value. 0 = not found, others, see below */
725  int i;
726 
727  /* If we aren't fully booted, we just pretend we reloaded but we queue this
728  up to run once we are booted up. */
729  if (!ast_fully_booted) {
731  return 0;
732  }
733 
735  ast_verbose("The previous reload command didn't finish yet\n");
736  return -1; /* reload already in progress */
737  }
739 
740  if (ast_opt_lock_confdir) {
741  int try;
742  int res;
743  for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
745  if (res == AST_LOCK_TIMEOUT) {
746  ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
747  }
748  }
749  if (res != AST_LOCK_SUCCESS) {
750  ast_verbose("Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
752  return -1;
753  }
754  }
755 
756  /* Call "predefined" reload here first */
757  for (i = 0; reload_classes[i].name; i++) {
758  if (!name || !strcasecmp(name, reload_classes[i].name)) {
759  if (!reload_classes[i].reload_fn()) {
760  ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", name);
761  }
762  res = 2; /* found and reloaded */
763  }
764  }
765 
766  if (name && res) {
767  if (ast_opt_lock_confdir) {
769  }
771  return res;
772  }
773 
776  const struct ast_module_info *info = cur->info;
777 
778  if (name && resource_name_match(name, cur->resource))
779  continue;
780 
781  if (!cur->flags.running || cur->flags.declined) {
782  if (!name)
783  continue;
784  ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. "
785  "Before reloading the module, you must run \"module load %s\" "
786  "and fix whatever is preventing the module from being initialized.\n",
787  name, name);
788  res = 2; /* Don't report that the module was not found */
789  break;
790  }
791 
792  if (!info->reload) { /* cannot be reloaded */
793  /* Nothing to reload, so reload is successful */
794  ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource);
795  if (res < 1) /* store result if possible */
796  res = 1; /* 1 = no reload() method */
797  continue;
798  }
799 
800  res = 2;
801  ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
802  if (!info->reload()) {
803  ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource);
804  }
805  }
807 
808  if (ast_opt_lock_confdir) {
810  }
812 
813  return res;
814 }
const char * description
Definition: module.h:234
unsigned int running
Definition: loader.c:95
struct ast_module::@278 entry
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
int ast_unlock_path(const char *path)
Unlock a path.
Definition: app.c:1668
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
const char * name
Definition: loader.c:277
#define ast_verb(level,...)
Definition: logger.h:243
static int resource_name_match(const char *name1_in, const char *name2_in)
Definition: loader.c:338
enum AST_LOCK_RESULT ast_lock_path(const char *path)
Lock a filesystem path.
Definition: app.c:1652
#define ast_mutex_trylock(a)
Definition: lock.h:157
int(* reload)(void)
Definition: module.h:229
#define ast_fully_booted
Definition: options.h:113
struct timeval ast_lastreloadtime
Definition: asterisk.c:219
unsigned int declined
Definition: loader.c:96
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
struct ast_module::@277 flags
const char * ast_config_AST_CONFIG_DIR
Definition: asterisk.c:256
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static const char name[]
static void queue_reload_request(const char *module)
Definition: loader.c:683
static ast_mutex_t reloadlock
Definition: loader.c:128
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
#define ast_opt_lock_confdir
Definition: options.h:131
#define ast_mutex_unlock(a)
Definition: lock.h:156
void ast_module_shutdown ( void  )

Run the unload() callback for all loaded modules.

This function should be called when Asterisk is shutting down gracefully.

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.
If we go through the entire list without changing anything, ignore the usecounts and unload, then exit.

Definition at line 513 of file loader.c.

References AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module::declined, ast_module::flags, free, ast_module::info, ast_module::running, ast_module_info::unload, ast_module::usecount, and ast_module::users.

Referenced by really_quit().

514 {
515  struct ast_module *mod;
516  int somethingchanged = 1, final = 0;
517 
519 
520  /*!\note Some resources, like timers, are started up dynamically, and thus
521  * may be still in use, even if all channels are dead. We must therefore
522  * check the usecount before asking modules to unload. */
523  do {
524  if (!somethingchanged) {
525  /*!\note If we go through the entire list without changing
526  * anything, ignore the usecounts and unload, then exit. */
527  final = 1;
528  }
529 
530  /* Reset flag before traversing the list */
531  somethingchanged = 0;
532 
534  if (!final && mod->usecount) {
535  continue;
536  }
538  if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
539  mod->info->unload();
540  }
542  free(mod);
543  somethingchanged = 1;
544  }
546  } while (somethingchanged && !final);
547 
549 }
unsigned int running
Definition: loader.c:95
struct module_user_list users
Definition: loader.c:93
struct ast_module::@278 entry
#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
int usecount
Definition: loader.c:92
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:638
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
unsigned int declined
Definition: loader.c:96
int(* unload)(void)
Definition: module.h:230
struct ast_module::@277 flags
#define free(a)
Definition: astmm.h:94
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct ast_module_info * info
Definition: loader.c:90
void ast_module_unref ( struct ast_module mod)

Definition at line 1312 of file loader.c.

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

Referenced by agi_handle_command(), alsa_hangup(), ast_agi_unregister(), ast_app_exec_sub(), ast_app_expand_sub_args(), ast_bridge_check(), ast_fax_tech_unregister(), ast_rtp_instance_new(), ast_smdi_interface_destroy(), ast_srtp_destroy(), ast_timer_close(), dahdi_destroy_channel_bynum(), dahdi_hangup(), dahdi_pri_cc_agent_destructor(), dahdi_pri_cc_agent_init(), data_result_generate_node(), destroy(), destroy_bridge(), destroy_callback(), destroy_session(), fax_session_new(), filestream_destructor(), gtalk_hangup(), handle_cli_file_convert(), handle_orig(), iax2_predestroy(), instance_destructor(), local_ast_moh_cleanup(), local_pvt_destructor(), mgcp_hangup(), mixmonitor_exec(), mixmonitor_thread(), my_module_unref(), oh323_hangup(), oss_hangup(), phone_check_exception(), phone_hangup(), sip_cc_monitor_destructor(), sip_hangup(), skinny_hangup(), and smart_bridge_operation().

1313 {
1314  if (!mod) {
1315  return;
1316  }
1317 
1318  ast_atomic_fetchadd_int(&mod->usecount, -1);
1320 }
int usecount
Definition: loader.c:92
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
void ast_module_unregister ( const struct ast_module_info info)

Definition at line 185 of file loader.c.

References ast_free, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module::info, and ast_module::users.

186 {
187  struct ast_module *mod = NULL;
188 
189  /* it is assumed that the users list in the module structure
190  will already be empty, or we cannot have gotten to this
191  point
192  */
195  if (mod->info == info) {
197  break;
198  }
199  }
202 
203  if (mod) {
205  ast_free(mod);
206  }
207 }
struct module_user_list users
Definition: loader.c:93
struct ast_module::@278 entry
#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
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:638
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ast_free(a)
Definition: astmm.h:97
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct ast_module_info * info
Definition: loader.c:90
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 656 of file loader.c.

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

Referenced by main().

657 {
658  struct reload_queue_item *item;
659 
660  if (!ast_fully_booted) {
661  return;
662  }
663 
665 
666  if (do_full_reload) {
667  do_full_reload = 0;
669  ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
670  ast_module_reload(NULL);
671  return;
672  }
673 
674  while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
675  ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
676  ast_module_reload(item->module);
677  ast_free(item);
678  }
679 
681 }
#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
char module[0]
Definition: loader.c:132
#define ast_fully_booted
Definition: options.h:113
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct reload_queue_item::@280 entry
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int ast_module_reload(const char *name)
Reload asterisk modules.
Definition: loader.c:721
#define ast_free(a)
Definition: astmm.h:97
static int do_full_reload
Definition: loader.c:135
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 551 of file loader.c.

References __ast_module_user_hangup_all(), AST_FORCE_FIRM, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_test_suite_event_notify, ast_update_use_count(), ast_module::declined, find_resource(), ast_module::flags, ast_module::info, ast_module::lib, LOG_WARNING, ast_module_info::restore_globals, ast_module::running, ast_module_info::unload, unload_dynamic_module(), and ast_module::usecount.

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

552 {
553  struct ast_module *mod;
554  int res = -1;
555  int error = 0;
556 
558 
559  if (!(mod = find_resource(resource_name, 0))) {
561  ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
562  return -1;
563  }
564 
565  if (!mod->flags.running || mod->flags.declined) {
566  ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
567  error = 1;
568  }
569 
570  if (!error && (mod->usecount > 0)) {
571  if (force)
572  ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
573  resource_name, mod->usecount);
574  else {
575  ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
576  mod->usecount);
577  error = 1;
578  }
579  }
580 
581  if (!error) {
582  /* Request any channels attached to the module to hangup. */
584 
585  res = mod->info->unload();
586  if (res) {
587  ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
588  if (force <= AST_FORCE_FIRM) {
589  error = 1;
590  } else {
591  ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
592  }
593  }
594 
595  if (!error) {
596  /*
597  * Request hangup on any channels that managed to get attached
598  * while we called the module unload function.
599  */
601  sched_yield();
602  }
603  }
604 
605  if (!error)
606  mod->flags.running = mod->flags.declined = 0;
607 
609 
610  if (!error && !mod->lib && mod->info && mod->info->restore_globals)
611  mod->info->restore_globals();
612 
613 #ifdef LOADABLE_MODULES
614  if (!error) {
616  ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
617  }
618 #endif
619 
620  if (!error)
622 
623  return res;
624 }
unsigned int running
Definition: loader.c:95
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
void __ast_module_user_hangup_all(struct ast_module *)
Definition: loader.c:254
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int usecount
Definition: loader.c:92
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:356
unsigned int declined
Definition: loader.c:96
int(* unload)(void)
Definition: module.h:230
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
static void unload_dynamic_module(struct ast_module *mod)
Definition: loader.c:393
struct ast_module::@277 flags
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void(* restore_globals)(void)
Definition: module.h:232
struct ast_module_info * info
Definition: loader.c:90
void * lib
Definition: loader.c:91
int ast_update_module_list ( int(*)(const char *module, const char *description, int usecnt, const char *like)  modentry,
const char *  like 
)

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

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 1234 of file loader.c.

References AST_LIST_TRAVERSE, AST_LIST_TRYLOCK, AST_LIST_UNLOCK, ast_module_info::description, ast_module::info, ast_module::resource, and ast_module::usecount.

Referenced by ast_var_Modules(), and handle_modlist().

1236 {
1237  struct ast_module *cur;
1238  int unlock = -1;
1239  int total_mod_loaded = 0;
1240 
1242  unlock = 0;
1243 
1245  total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1246  }
1247 
1248  if (unlock)
1250 
1251  return total_mod_loaded;
1252 }
const char * description
Definition: module.h:234
struct ast_module::@278 entry
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int usecount
Definition: loader.c:92
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_TRYLOCK(head)
Locks a list, without blocking if the list is locked.
Definition: linkedlists.h:104
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
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 1222 of file loader.c.

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

Referenced by __ast_module_user_add(), __ast_module_user_hangup_all(), __ast_module_user_remove(), ast_module_ref(), ast_module_unref(), ast_unload_resource(), handle_request_do(), oh323_request(), sip_request_call(), start_resource(), and unistim_new().

1223 {
1224  /* Notify any module monitors that the use count for a
1225  resource has changed */
1226  struct loadupdate *m;
1227 
1230  m->updater();
1232 }
#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
int(* updater)(void)
Definition: loader.c:122
struct loadupdate::@279 entry
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
static void close_lib ( const char *  name,
void *  lib 
)
static

Definition at line 376 of file loader.c.

References ast_log(), AST_LOG_ERROR, and S_OR.

Referenced by load_dynamic_module(), and unload_dynamic_module().

377 {
378  char *error;
379 
380  if (!lib) {
381  return;
382  }
383 
384  /* Clear any existing error */
385  dlerror();
386  if (dlclose(lib)) {
387  error = dlerror();
388  ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
389  S_OR(name, "unknown"), S_OR(error, "Unknown error"));
390  }
391 }
#define AST_LOG_ERROR
Definition: logger.h:160
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:77
static struct ast_module* find_resource ( const char *  resource,
int  do_lock 
)
static

Definition at line 356 of file loader.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_module::resource, and resource_name_match().

Referenced by ast_module_check(), ast_unload_resource(), load_dynamic_module(), load_modules(), and load_resource().

357 {
358  struct ast_module *cur;
359 
360  if (do_lock)
362 
365  break;
366  }
367 
368  if (do_lock)
370 
371  return cur;
372 }
struct ast_module::@278 entry
#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 int resource_name_match(const char *name1_in, const char *name2_in)
Definition: loader.c:338
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
char resource[0]
Definition: loader.c:99
static unsigned int inspect_module ( const struct ast_module mod)
static

Definition at line 816 of file loader.c.

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

Referenced by load_resource().

817 {
818  if (!mod->info->description) {
819  ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
820  return 1;
821  }
822 
823  if (!mod->info->key) {
824  ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
825  return 1;
826  }
827 
828  if (verify_key((unsigned char *) mod->info->key)) {
829  ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
830  return 1;
831  }
832 
833  if (!ast_strlen_zero(mod->info->buildopt_sum) &&
834  strcmp(buildopt_sum, mod->info->buildopt_sum)) {
835  ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
836  ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
837  return 1;
838  }
839 
840  return 0;
841 }
const char * description
Definition: module.h:234
#define LOG_WARNING
Definition: logger.h:144
static int verify_key(const unsigned char *key)
Definition: loader.c:321
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char buildopt_sum[33]
Definition: loader.c:83
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * key
Definition: module.h:242
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
const char buildopt_sum[33]
Definition: module.h:246
static int key_matches ( const unsigned char *  key1,
const unsigned char *  key2 
)
static

Definition at line 309 of file loader.c.

Referenced by verify_key().

310 {
311  int x;
312 
313  for (x = 0; x < 16; x++) {
314  if (key1[x] != key2[x])
315  return 0;
316  }
317 
318  return 1;
319 }
static struct ast_module* load_dynamic_module ( const char *  resource_in,
unsigned int  global_symbols_only,
struct ast_heap resource_heap 
)
static

Definition at line 405 of file loader.c.

References ast_calloc, ast_config_AST_MODULE_DIR, ast_free, AST_LIST_LAST, ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_test_flag, close_lib(), find_resource(), ast_module::info, ast_module::lib, load_resource(), LOG_WARNING, ast_module_info::nonoptreq, ast_module::resource, resource_being_loaded, RTLD_LOCAL, RTLD_NOW, and strsep().

Referenced by load_resource().

406 {
407  char fn[PATH_MAX] = "";
408  void *lib = NULL;
409  struct ast_module *mod;
410  unsigned int wants_global;
411  int space; /* room needed for the descriptor */
412  int missing_so = 0;
413 
414  space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
415  if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
416  missing_so = 1;
417  space += 3; /* room for the extra ".so" */
418  }
419 
420  snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
421 
422  /* make a first load of the module in 'quiet' mode... don't try to resolve
423  any symbols, and don't export any symbols. this will allow us to peek into
424  the module's info block (if available) to see what flags it has set */
425 
426  resource_being_loaded = ast_calloc(1, space);
428  return NULL;
429  strcpy(resource_being_loaded->resource, resource_in);
430  if (missing_so)
431  strcat(resource_being_loaded->resource, ".so");
432 
433  if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
434  ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
436  return NULL;
437  }
438 
439  /* the dlopen() succeeded, let's find out if the module
440  registered itself */
441  /* note that this will only work properly as long as
442  ast_module_register() (which is called by the module's
443  constructor) places the new module at the tail of the
444  module_list
445  */
447  ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
448  /* no, it did not, so close it and return */
449  close_lib(resource_in, lib);
450  /* note that the module's destructor will call ast_module_unregister(),
451  which will free the structure we allocated in resource_being_loaded */
452  return NULL;
453  }
454 
455  wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
456 
457  /* if we are being asked only to load modules that provide global symbols,
458  and this one does not, then close it and return */
459  if (global_symbols_only && !wants_global) {
460  close_lib(resource_in, lib);
461  return NULL;
462  }
463 
464  /* This section is a workaround for a gcc 4.1 bug that has already been
465  * fixed in later versions. Unfortunately, some distributions, such as
466  * RHEL/CentOS 5, distribute gcc 4.1, so we're stuck with having to deal
467  * with this issue. This basically ensures that optional_api modules are
468  * loaded before any module which requires their functionality. */
469 #if !defined(HAVE_ATTRIBUTE_weak_import) && !defined(HAVE_ATTRIBUTE_weakref)
470  if (!ast_strlen_zero(mod->info->nonoptreq)) {
471  /* Force any required dependencies to load */
472  char *each, *required_resource = ast_strdupa(mod->info->nonoptreq);
473  while ((each = strsep(&required_resource, ","))) {
474  struct ast_module *dependency;
475  each = ast_strip(each);
476  dependency = find_resource(each, 0);
477  /* Is it already loaded? */
478  if (!dependency) {
479  load_resource(each, global_symbols_only, resource_heap, 1);
480  }
481  }
482  }
483 #endif
484 
485  close_lib(resource_in, lib);
486  resource_being_loaded = NULL;
487 
488  /* start the load process again */
489  resource_being_loaded = ast_calloc(1, space);
491  return NULL;
492  strcpy(resource_being_loaded->resource, resource_in);
493  if (missing_so)
494  strcat(resource_being_loaded->resource, ".so");
495 
496  if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
497  ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
499  return NULL;
500  }
501 
502  /* since the module was successfully opened, and it registered itself
503  the previous time we did that, we're going to assume it worked this
504  time too :) */
505 
506  AST_LIST_LAST(&module_list)->lib = lib;
507  resource_being_loaded = NULL;
508 
509  return AST_LIST_LAST(&module_list);
510 }
char * strsep(char **str, const char *delims)
#define ast_test_flag(p, flag)
Definition: utils.h:63
const char * ast_config_AST_MODULE_DIR
Definition: asterisk.c:258
const char * nonoptreq
Definition: module.h:258
static struct ast_module * resource_being_loaded
Definition: loader.c:143
#define LOG_WARNING
Definition: logger.h:144
static void close_lib(const char *name, void *lib)
Definition: loader.c:376
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:356
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
Definition: loader.c:893
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define RTLD_LOCAL
Definition: loader.c:69
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
#define RTLD_NOW
Definition: loader.c:65
struct ast_module_info * info
Definition: loader.c:90
void * lib
Definition: loader.c:91
char resource[0]
Definition: loader.c:99
int load_modules ( unsigned  int)

Provided by loader.c

Definition at line 1072 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_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), AST_MODULE_CONFIG, ast_opt_quiet, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, embedded_module_list, embedding, EVENT_FLAG_SYSTEM, find_resource(), module_list::first, ast_module::flags, module_list::last, ast_module::lib, load_resource_list(), LOG_NOTICE, LOG_WARNING, manager_event, ast_variable::name, ast_variable::next, ast_module::resource, load_order_entry::resource, resource_name_match(), ast_module::running, and ast_variable::value.

Referenced by main().

1073 {
1074  struct ast_config *cfg;
1075  struct ast_module *mod;
1076  struct load_order_entry *order;
1077  struct ast_variable *v;
1078  unsigned int load_count;
1079  struct load_order load_order;
1080  int res = 0;
1081  struct ast_flags config_flags = { 0 };
1082  int modulecount = 0;
1083 
1084 #ifdef LOADABLE_MODULES
1085  struct dirent *dirent;
1086  DIR *dir;
1087 #endif
1088 
1089  /* all embedded modules have registered themselves by now */
1090  embedding = 0;
1091 
1092  ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1093 
1095 
1097 
1101  embedded_module_list.first = NULL;
1102  }
1103 
1104  cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1106  ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1107  goto done;
1108  }
1109 
1110  /* first, find all the modules we have been explicitly requested to load */
1111  for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1112  if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1114  }
1115  if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1116  /* Add the module to the list and make sure it's required */
1118  ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1119  }
1120 
1121  }
1122 
1123  /* check if 'autoload' is on */
1124  if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1125  /* if so, first add all the embedded modules that are not already running to the load order */
1126  AST_LIST_TRAVERSE(&module_list, mod, entry) {
1127  /* if it's not embedded, skip it */
1128  if (mod->lib)
1129  continue;
1130 
1131  if (mod->flags.running)
1132  continue;
1133 
1135  }
1136 
1137 #ifdef LOADABLE_MODULES
1138  /* if we are allowed to load dynamic modules, scan the directory for
1139  for all available modules and add them as well */
1140  if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1141  while ((dirent = readdir(dir))) {
1142  int ld = strlen(dirent->d_name);
1143 
1144  /* Must end in .so to load it. */
1145 
1146  if (ld < 4)
1147  continue;
1148 
1149  if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1150  continue;
1151 
1152  /* if there is already a module by this name in the module_list,
1153  skip this file */
1154  if (find_resource(dirent->d_name, 0))
1155  continue;
1156 
1157  add_to_load_order(dirent->d_name, &load_order, 0);
1158  }
1159 
1160  closedir(dir);
1161  } else {
1162  if (!ast_opt_quiet)
1163  ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1165  }
1166 #endif
1167  }
1168 
1169  /* now scan the config for any modules we are prohibited from loading and
1170  remove them from the load order */
1171  for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1172  if (strcasecmp(v->name, "noload"))
1173  continue;
1174 
1175  AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1176  if (!resource_name_match(order->resource, v->value)) {
1177  AST_LIST_REMOVE_CURRENT(entry);
1178  ast_free(order->resource);
1179  ast_free(order);
1180  }
1181  }
1183  }
1184 
1185  /* we are done with the config now, all the information we need is in the
1186  load_order list */
1187  ast_config_destroy(cfg);
1188 
1189  load_count = 0;
1190  AST_LIST_TRAVERSE(&load_order, order, entry)
1191  load_count++;
1192 
1193  if (load_count)
1194  ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1195 
1196  /* first, load only modules that provide global symbols */
1197  if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1198  goto done;
1199  }
1200 
1201  /* now load everything else */
1202  if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1203  goto done;
1204  }
1205 
1206 done:
1207  while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1208  ast_free(order->resource);
1209  ast_free(order);
1210  }
1211 
1213 
1214  /* Tell manager clients that are aggressive at logging in that we're done
1215  loading modules. If there's a DNS problem in chan_sip, we might not
1216  even reach this */
1217  manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1218 
1219  return res;
1220 }
unsigned int running
Definition: loader.c:95
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
struct ast_module * last
Definition: loader.c:102
struct ast_module * first
Definition: loader.c:102
const char * ast_config_AST_MODULE_DIR
Definition: asterisk.c:258
#define LOG_WARNING
Definition: logger.h:144
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static int loaded
Definition: cdr_csv.c:56
Definition: loader.c:960
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:356
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int resource_name_match(const char *name1_in, const char *name2_in)
Definition: loader.c:338
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
char * resource
Definition: loader.c:961
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define ast_opt_quiet
Definition: options.h:106
const char * name
Definition: config.h:77
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct ast_module::@277 flags
static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
Definition: loader.c:1010
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#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:97
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
Structure used to handle boolean flags.
Definition: utils.h:200
static struct module_list embedded_module_list
Definition: loader.c:119
#define AST_MODULE_CONFIG
Module configuration file.
Definition: module.h:51
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
static struct load_order_entry * add_to_load_order(const char *resource, struct load_order *load_order, int required)
Definition: loader.c:968
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static unsigned int embedding
Definition: loader.c:85
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
void * lib
Definition: loader.c:91
char resource[0]
Definition: loader.c:99
static enum ast_module_load_result load_resource ( const char *  resource_name,
unsigned int  global_symbols_only,
struct ast_heap resource_heap,
int  required 
)
static

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

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

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

Definition at line 893 of file loader.c.

References ast_heap_push(), ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_test_flag, ast_module_info::backup_globals, ast_module::declined, find_resource(), ast_module::flags, ast_module::info, inspect_module(), ast_module::lib, load_dynamic_module(), LOG_WARNING, ast_module::running, start_resource(), and unload_dynamic_module().

Referenced by ast_load_resource(), load_dynamic_module(), and load_resource_list().

894 {
895  struct ast_module *mod;
897 
898  if ((mod = find_resource(resource_name, 0))) {
899  if (mod->flags.running) {
900  ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
902  }
903  if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
904  return AST_MODULE_LOAD_SKIP;
905  } else {
906 #ifdef LOADABLE_MODULES
907  if (!(mod = load_dynamic_module(resource_name, global_symbols_only, resource_heap))) {
908  /* don't generate a warning message during load_modules() */
909  if (!global_symbols_only) {
910  ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
912  } else {
913  return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
914  }
915  }
916 #else
917  ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
919 #endif
920  }
921 
922  if (inspect_module(mod)) {
923  ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
924 #ifdef LOADABLE_MODULES
926 #endif
928  }
929 
930  if (!mod->lib && mod->info->backup_globals && mod->info->backup_globals()) {
931  ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
933  }
934 
935  mod->flags.declined = 0;
936 
937  if (resource_heap) {
938  ast_heap_push(resource_heap, mod);
940  } else {
941  res = start_resource(mod);
942  }
943 
944  return res;
945 }
static enum ast_module_load_result start_resource(struct ast_module *mod)
Definition: loader.c:843
ast_module_load_result
Definition: module.h:60
unsigned int running
Definition: loader.c:95
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
int ast_heap_push(struct ast_heap *h, void *elm)
Push an element on to a heap.
Definition: heap.c:250
static struct ast_module * find_resource(const char *resource, int do_lock)
Definition: loader.c:356
unsigned int declined
Definition: loader.c:96
static void unload_dynamic_module(struct ast_module *mod)
Definition: loader.c:393
struct ast_module::@277 flags
static struct ast_module * load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, struct ast_heap *resource_heap)
Definition: loader.c:405
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int(* backup_globals)(void)
Definition: module.h:231
struct ast_module_info * info
Definition: loader.c:90
void * lib
Definition: loader.c:91
static unsigned int inspect_module(const struct ast_module *mod)
Definition: loader.c:816
static int load_resource_list ( struct load_order load_order,
unsigned int  global_symbols,
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 1010 of file loader.c.

References ast_free, ast_heap_create(), ast_heap_destroy(), ast_heap_pop(), 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, load_resource(), LOG_ERROR, mod_load_cmp(), load_order_entry::required, load_order_entry::resource, and start_resource().

Referenced by load_modules().

1011 {
1012  struct ast_heap *resource_heap;
1013  struct load_order_entry *order;
1014  struct ast_module *mod;
1015  int count = 0;
1016  int res = 0;
1017 
1018  if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
1019  return -1;
1020  }
1021 
1022  /* first, add find and add modules to heap */
1023  AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1024  switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
1028  ast_free(order->resource);
1029  ast_free(order);
1030  break;
1032  ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1033  fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1034  res = order->required ? -2 : -1;
1035  goto done;
1036  case AST_MODULE_LOAD_SKIP:
1037  break;
1040  ast_free(order->resource);
1041  ast_free(order);
1042  break;
1043  }
1044  }
1046 
1047  /* second remove modules from heap sorted by priority */
1048  while ((mod = ast_heap_pop(resource_heap))) {
1049  switch (start_resource(mod)) {
1051  count++;
1053  break;
1055  res = -1;
1056  goto done;
1057  case AST_MODULE_LOAD_SKIP:
1059  break;
1060  }
1061  }
1062 
1063 done:
1064  if (mod_count) {
1065  *mod_count += count;
1066  }
1067  ast_heap_destroy(resource_heap);
1068 
1069  return res;
1070 }
static enum ast_module_load_result start_resource(struct ast_module *mod)
Definition: loader.c:843
struct ast_module::@278 entry
Definition: heap.c:38
Definition: loader.c:960
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:163
void * ast_heap_pop(struct ast_heap *h)
Pop the max element off of the heap.
Definition: heap.c:295
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:600
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
Definition: loader.c:893
int required
Definition: loader.c:962
char * resource
Definition: loader.c:961
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:554
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
struct ast_heap * ast_heap_create(unsigned int init_height, ast_heap_cmp_fn cmp_fn, ssize_t index_offset)
Create a max heap.
Definition: heap.c:118
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
static int mod_load_cmp(void *a, void *b)
Definition: loader.c:991
static int mod_load_cmp ( void *  a,
void *  b 
)
static

Definition at line 991 of file loader.c.

References AST_MODFLAG_LOAD_ORDER, ast_test_flag, ast_module::info, and ast_module_info::load_pri.

Referenced by load_resource_list().

992 {
993  struct ast_module *a_mod = (struct ast_module *) a;
994  struct ast_module *b_mod = (struct ast_module *) b;
995  int res = -1;
996  /* if load_pri is not set, default is 128. Lower is better*/
997  unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
998  unsigned char b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
999  if (a_pri == b_pri) {
1000  res = 0;
1001  } else if (a_pri < b_pri) {
1002  res = 1;
1003  }
1004  return res;
1005 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned char load_pri
Definition: module.h:253
struct ast_module_info * info
Definition: loader.c:90
static int printdigest ( const unsigned char *  d)
static

Definition at line 296 of file loader.c.

References ast_debug.

Referenced by verify_key().

297 {
298  int x, pos;
299  char buf[256]; /* large enough so we don't have to worry */
300 
301  for (pos = 0, x = 0; x < 16; x++)
302  pos += sprintf(buf + pos, " %02x", (unsigned)*d++);
303 
304  ast_debug(1, "Unexpected signature:%s\n", buf);
305 
306  return 0;
307 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static void queue_reload_request ( const char *  module)
static

Definition at line 683 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(), do_full_reload, LOG_ERROR, and reload_queue_item::module.

Referenced by ast_module_reload().

684 {
685  struct reload_queue_item *item;
686 
688 
689  if (do_full_reload) {
691  return;
692  }
693 
694  if (ast_strlen_zero(module)) {
695  /* A full reload request (when module is NULL) wipes out any previous
696  reload requests and causes the queue to ignore future ones */
697  while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
698  ast_free(item);
699  }
700  do_full_reload = 1;
701  } else {
702  /* No reason to add the same module twice */
704  if (!strcasecmp(item->module, module)) {
706  return;
707  }
708  }
709  item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
710  if (!item) {
711  ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
713  return;
714  }
715  strcpy(item->module, module);
717  }
719 }
#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
char module[0]
Definition: loader.c:132
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
struct reload_queue_item::@280 entry
#define LOG_ERROR
Definition: logger.h:155
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#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:97
static int do_full_reload
Definition: loader.c:135
#define ast_calloc(a, b)
Definition: astmm.h:82
static int resource_name_match ( const char *  name1_in,
const char *  name2_in 
)
static

Definition at line 338 of file loader.c.

References ast_strdupa.

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

339 {
340  char *name1 = (char *) name1_in;
341  char *name2 = (char *) name2_in;
342 
343  /* trim off any .so extensions */
344  if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
345  name1 = ast_strdupa(name1);
346  name1[strlen(name1) - 3] = '\0';
347  }
348  if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
349  name2 = ast_strdupa(name2);
350  name2[strlen(name2) - 3] = '\0';
351  }
352 
353  return strcasecmp(name1, name2);
354 }
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static enum ast_module_load_result start_resource ( struct ast_module mod)
static

Definition at line 843 of file loader.c.

References ast_fully_booted, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_update_use_count(), ast_verb, ast_verbose(), COLOR_BLACK, COLOR_BROWN, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, ast_module_info::load, option_verbose, ast_module::resource, ast_module::running, and term_color().

Referenced by load_resource(), and load_resource_list().

844 {
845  char tmp[256];
846  enum ast_module_load_result res;
847 
848  if (mod->flags.running) {
850  }
851 
852  if (!mod->info->load) {
854  }
855 
856  res = mod->info->load();
857 
858  switch (res) {
860  if (!ast_fully_booted) {
861  ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
863  ast_verbose( ".");
864  } else {
865  ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
866  }
867 
868  mod->flags.running = 1;
869 
871  break;
873  mod->flags.declined = 1;
874  break;
876  case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
878  break;
879  }
880 
881  return res;
882 }
const char * description
Definition: module.h:234
ast_module_load_result
Definition: module.h:60
unsigned int running
Definition: loader.c:95
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
enum ast_module_load_result(* load)(void)
Definition: module.h:228
int option_verbose
Definition: asterisk.c:181
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
#define ast_verb(level,...)
Definition: logger.h:243
#define ast_opt_console
Definition: options.h:107
#define ast_fully_booted
Definition: options.h:113
unsigned int declined
Definition: loader.c:96
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Definition: term.c:184
struct ast_module::@277 flags
#define COLOR_BLACK
Definition: term.h:47
#define COLOR_BROWN
Definition: term.h:53
struct ast_module_info * info
Definition: loader.c:90
char resource[0]
Definition: loader.c:99
static void unload_dynamic_module ( struct ast_module mod)
static

Definition at line 393 of file loader.c.

References ast_module_name(), close_lib(), and ast_module::lib.

Referenced by ast_unload_resource(), and load_resource().

394 {
395  void *lib = mod->lib;
396 
397  /* WARNING: the structure pointed to by mod is going to
398  disappear when this operation succeeds, so we can't
399  dereference it */
400  close_lib(ast_module_name(mod), lib);
401 }
static void close_lib(const char *name, void *lib)
Definition: loader.c:376
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:104
void * lib
Definition: loader.c:91
static int verify_key ( const unsigned char *  key)
static

Definition at line 321 of file loader.c.

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

Referenced by inspect_module().

322 {
323  struct MD5Context c;
324  unsigned char digest[16];
325 
326  MD5Init(&c);
327  MD5Update(&c, key, strlen((char *)key));
328  MD5Final(digest, &c);
329 
330  if (key_matches(expected_key, digest))
331  return 0;
332 
333  printdigest(digest);
334 
335  return -1;
336 }
static int key_matches(const unsigned char *key1, const unsigned char *key2)
Definition: loader.c:309
static const unsigned char expected_key[]
Definition: loader.c:79
void MD5Final(unsigned char digest[16], struct MD5Context *context)
Definition: md5.c:122
void MD5Init(struct MD5Context *context)
Definition: md5.c:59
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
Definition: md5.c:74
Definition: md5.h:26
static int printdigest(const unsigned char *d)
Definition: loader.c:296

Variable Documentation

char buildopt_sum[33] = AST_BUILDOPT_SUM
static

Definition at line 83 of file loader.c.

Referenced by inspect_module().

int do_full_reload = 0
static

Definition at line 135 of file loader.c.

Referenced by ast_process_pending_reloads(), and queue_reload_request().

struct module_list embedded_module_list
static

Definition at line 119 of file loader.c.

Referenced by ast_module_register(), and load_modules().

unsigned int embedding = 1
static

Definition at line 85 of file loader.c.

Referenced by ast_module_register(), and load_modules().

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 79 of file loader.c.

Referenced by verify_key().

struct module_list module_list = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
struct reload_classes reload_classes[]
static
struct reload_queue reload_queue = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } , }
static
ast_mutex_t reloadlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 128 of file loader.c.

struct ast_module* resource_being_loaded
static

Definition at line 143 of file loader.c.

Referenced by ast_module_register(), and load_dynamic_module().

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