2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
7 * Kevin P. Fleming <kpfleming@digium.com>
8 * Luigi Rizzo <rizzo@icir.org>
10 * See http://www.asterisk.org for more information about
11 * the Asterisk project. Please do not directly contact
12 * any of the maintainers of this project for assistance;
13 * the project provides a web site, mailing lists and IRC
14 * channels for your use.
16 * This program is free software, distributed under the terms of
17 * the GNU General Public License Version 2. See the LICENSE file
18 * at the top of the source tree.
23 * \brief Module Loader
24 * \author Mark Spencer <markster@digium.com>
25 * \author Kevin P. Fleming <kpfleming@digium.com>
26 * \author Luigi Rizzo <rizzo@icir.org>
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34 #include "asterisk/_private.h"
35 #include "asterisk/paths.h" /* use ast_config_AST_MODULE_DIR */
38 #include "asterisk/linkedlists.h"
39 #include "asterisk/module.h"
40 #include "asterisk/config.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/term.h"
43 #include "asterisk/manager.h"
44 #include "asterisk/cdr.h"
45 #include "asterisk/enum.h"
46 #include "asterisk/http.h"
47 #include "asterisk/lock.h"
48 #include "asterisk/features.h"
49 #include "asterisk/dsp.h"
50 #include "asterisk/udptl.h"
51 #include "asterisk/heap.h"
52 #include "asterisk/app.h"
56 #include "asterisk/md5.h"
57 #include "asterisk/utils.h"
67 struct ast_module_user {
68 struct ast_channel *chan;
69 AST_LIST_ENTRY(ast_module_user) entry;
72 AST_LIST_HEAD(module_user_list, ast_module_user);
74 static const unsigned char expected_key[] =
75 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
76 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
78 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
80 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
81 since they are here before we dlopen() any
85 const struct ast_module_info *info;
86 void *lib; /* the shared lib, or NULL if embedded */
87 int usecount; /* the number of 'users' currently in this module */
88 struct module_user_list users; /* the list of users in the module */
90 unsigned int running:1;
91 unsigned int declined:1;
93 AST_LIST_ENTRY(ast_module) entry;
97 static AST_LIST_HEAD_STATIC(module_list, ast_module);
99 const char *ast_module_name(const struct ast_module *mod)
101 if (!mod || !mod->info) {
105 return mod->info->name;
109 * module_list is cleared by its constructor possibly after
110 * we start accumulating embedded modules, so we need to
111 * use another list (without the lock) to accumulate them.
112 * Then we update the main list when embedding is done.
114 static struct module_list embedded_module_list;
117 int (*updater)(void);
118 AST_LIST_ENTRY(loadupdate) entry;
121 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
123 AST_MUTEX_DEFINE_STATIC(reloadlock);
125 struct reload_queue_item {
126 AST_LIST_ENTRY(reload_queue_item) entry;
130 static int do_full_reload = 0;
132 static AST_LIST_HEAD_STATIC(reload_queue, reload_queue_item);
134 /* when dynamic modules are being loaded, ast_module_register() will
135 need to know what filename the module was loaded from while it
138 static struct ast_module *resource_being_loaded;
140 /* XXX: should we check for duplicate resource names here? */
142 void ast_module_register(const struct ast_module_info *info)
144 struct ast_module *mod;
147 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
149 strcpy(mod->resource, info->name);
151 mod = resource_being_loaded;
155 AST_LIST_HEAD_INIT(&mod->users);
157 /* during startup, before the loader has been initialized,
158 there are no threads, so there is no need to take the lock
159 on this list to manipulate it. it is also possible that it
160 might be unsafe to use the list lock at that point... so
161 let's avoid it altogether
164 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
166 AST_LIST_LOCK(&module_list);
167 /* it is paramount that the new entry be placed at the tail of
168 the list, otherwise the code that uses dlopen() to load
169 dynamic modules won't be able to find out if the module it
170 just opened was registered or failed to load
172 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
173 AST_LIST_UNLOCK(&module_list);
176 /* give the module a copy of its own handle, for later use in registrations and the like */
177 *((struct ast_module **) &(info->self)) = mod;
180 void ast_module_unregister(const struct ast_module_info *info)
182 struct ast_module *mod = NULL;
184 /* it is assumed that the users list in the module structure
185 will already be empty, or we cannot have gotten to this
188 AST_LIST_LOCK(&module_list);
189 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
190 if (mod->info == info) {
191 AST_LIST_REMOVE_CURRENT(entry);
195 AST_LIST_TRAVERSE_SAFE_END;
196 AST_LIST_UNLOCK(&module_list);
199 AST_LIST_HEAD_DESTROY(&mod->users);
204 struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
205 struct ast_channel *chan)
207 struct ast_module_user *u = ast_calloc(1, sizeof(*u));
214 AST_LIST_LOCK(&mod->users);
215 AST_LIST_INSERT_HEAD(&mod->users, u, entry);
216 AST_LIST_UNLOCK(&mod->users);
218 ast_atomic_fetchadd_int(&mod->usecount, +1);
220 ast_update_use_count();
225 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
227 AST_LIST_LOCK(&mod->users);
228 AST_LIST_REMOVE(&mod->users, u, entry);
229 AST_LIST_UNLOCK(&mod->users);
230 ast_atomic_fetchadd_int(&mod->usecount, -1);
233 ast_update_use_count();
236 void __ast_module_user_hangup_all(struct ast_module *mod)
238 struct ast_module_user *u;
240 AST_LIST_LOCK(&mod->users);
241 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
243 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
245 ast_atomic_fetchadd_int(&mod->usecount, -1);
248 AST_LIST_UNLOCK(&mod->users);
250 ast_update_use_count();
254 * In addition to modules, the reload command handles some extra keywords
255 * which are listed here together with the corresponding handlers.
256 * This table is also used by the command completion code.
258 static struct reload_classes {
260 int (*reload_fn)(void);
261 } reload_classes[] = { /* list in alpha order, longest match first for cli completion */
262 { "cdr", ast_cdr_engine_reload },
263 { "dnsmgr", dnsmgr_reload },
264 { "extconfig", read_config_maps },
265 { "enum", ast_enum_reload },
266 { "manager", reload_manager },
267 { "http", ast_http_reload },
268 { "logger", logger_reload },
269 { "features", ast_features_reload },
270 { "dsp", ast_dsp_reload},
271 { "udptl", ast_udptl_reload },
272 { "indications", ast_indications_reload },
273 { "cel", ast_cel_engine_reload },
274 { "plc", ast_plc_reload },
278 static int printdigest(const unsigned char *d)
281 char buf[256]; /* large enough so we don't have to worry */
283 for (pos = 0, x = 0; x < 16; x++)
284 pos += sprintf(buf + pos, " %02x", *d++);
286 ast_debug(1, "Unexpected signature:%s\n", buf);
291 static int key_matches(const unsigned char *key1, const unsigned char *key2)
295 for (x = 0; x < 16; x++) {
296 if (key1[x] != key2[x])
303 static int verify_key(const unsigned char *key)
306 unsigned char digest[16];
309 MD5Update(&c, key, strlen((char *)key));
310 MD5Final(digest, &c);
312 if (key_matches(expected_key, digest))
320 static int resource_name_match(const char *name1_in, const char *name2_in)
322 char *name1 = (char *) name1_in;
323 char *name2 = (char *) name2_in;
325 /* trim off any .so extensions */
326 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
327 name1 = ast_strdupa(name1);
328 name1[strlen(name1) - 3] = '\0';
330 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
331 name2 = ast_strdupa(name2);
332 name2[strlen(name2) - 3] = '\0';
335 return strcasecmp(name1, name2);
338 static struct ast_module *find_resource(const char *resource, int do_lock)
340 struct ast_module *cur;
343 AST_LIST_LOCK(&module_list);
345 AST_LIST_TRAVERSE(&module_list, cur, entry) {
346 if (!resource_name_match(resource, cur->resource))
351 AST_LIST_UNLOCK(&module_list);
356 #ifdef LOADABLE_MODULES
357 static void unload_dynamic_module(struct ast_module *mod)
359 void *lib = mod->lib;
361 /* WARNING: the structure pointed to by mod is going to
362 disappear when this operation succeeds, so we can't
366 while (!dlclose(lib));
369 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
371 char fn[PATH_MAX] = "";
373 struct ast_module *mod;
374 unsigned int wants_global;
375 int space; /* room needed for the descriptor */
378 space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
379 if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
381 space += 3; /* room for the extra ".so" */
384 snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
386 /* make a first load of the module in 'quiet' mode... don't try to resolve
387 any symbols, and don't export any symbols. this will allow us to peek into
388 the module's info block (if available) to see what flags it has set */
390 resource_being_loaded = ast_calloc(1, space);
391 if (!resource_being_loaded)
393 strcpy(resource_being_loaded->resource, resource_in);
395 strcat(resource_being_loaded->resource, ".so");
397 if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
398 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
399 ast_free(resource_being_loaded);
403 /* the dlopen() succeeded, let's find out if the module
405 /* note that this will only work properly as long as
406 ast_module_register() (which is called by the module's
407 constructor) places the new module at the tail of the
410 if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
411 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
412 /* no, it did not, so close it and return */
413 while (!dlclose(lib));
414 /* note that the module's destructor will call ast_module_unregister(),
415 which will free the structure we allocated in resource_being_loaded */
419 wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
421 /* if we are being asked only to load modules that provide global symbols,
422 and this one does not, then close it and return */
423 if (global_symbols_only && !wants_global) {
424 while (!dlclose(lib));
428 /* This section is a workaround for a gcc 4.1 bug that has already been
429 * fixed in later versions. Unfortunately, some distributions, such as
430 * RHEL/CentOS 5, distribute gcc 4.1, so we're stuck with having to deal
431 * with this issue. This basically ensures that optional_api modules are
432 * loaded before any module which requires their functionality. */
433 #if !defined(HAVE_ATTRIBUTE_weak_import) && !defined(HAVE_ATTRIBUTE_weakref)
434 if (!ast_strlen_zero(mod->info->nonoptreq)) {
435 /* Force any required dependencies to load */
436 char *each, *required_resource = ast_strdupa(mod->info->nonoptreq);
437 while ((each = strsep(&required_resource, ","))) {
438 each = ast_strip(each);
440 /* Is it already loaded? */
441 if (!find_resource(each, 0)) {
442 load_dynamic_module(each, global_symbols_only);
448 while (!dlclose(lib));
449 resource_being_loaded = NULL;
451 /* start the load process again */
452 resource_being_loaded = ast_calloc(1, space);
453 if (!resource_being_loaded)
455 strcpy(resource_being_loaded->resource, resource_in);
457 strcat(resource_being_loaded->resource, ".so");
459 if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
460 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
461 ast_free(resource_being_loaded);
465 /* since the module was successfully opened, and it registered itself
466 the previous time we did that, we're going to assume it worked this
469 AST_LIST_LAST(&module_list)->lib = lib;
470 resource_being_loaded = NULL;
472 return AST_LIST_LAST(&module_list);
476 void ast_module_shutdown(void)
478 struct ast_module *mod;
479 int somethingchanged = 1, final = 0;
481 AST_LIST_LOCK(&module_list);
483 /*!\note Some resources, like timers, are started up dynamically, and thus
484 * may be still in use, even if all channels are dead. We must therefore
485 * check the usecount before asking modules to unload. */
487 if (!somethingchanged) {
488 /*!\note If we go through the entire list without changing
489 * anything, ignore the usecounts and unload, then exit. */
493 /* Reset flag before traversing the list */
494 somethingchanged = 0;
496 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
497 if (!final && mod->usecount) {
500 AST_LIST_REMOVE_CURRENT(entry);
501 if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
504 AST_LIST_HEAD_DESTROY(&mod->users);
506 somethingchanged = 1;
508 AST_LIST_TRAVERSE_SAFE_END;
509 } while (somethingchanged && !final);
511 AST_LIST_UNLOCK(&module_list);
514 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
516 struct ast_module *mod;
520 AST_LIST_LOCK(&module_list);
522 if (!(mod = find_resource(resource_name, 0))) {
523 AST_LIST_UNLOCK(&module_list);
524 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
528 if (!mod->flags.running || mod->flags.declined) {
529 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
533 if (!error && (mod->usecount > 0)) {
535 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
536 resource_name, mod->usecount);
538 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
545 __ast_module_user_hangup_all(mod);
546 res = mod->info->unload();
549 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
550 if (force <= AST_FORCE_FIRM)
553 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
558 mod->flags.running = mod->flags.declined = 0;
560 AST_LIST_UNLOCK(&module_list);
562 if (!error && !mod->lib && mod->info && mod->info->restore_globals)
563 mod->info->restore_globals();
565 #ifdef LOADABLE_MODULES
567 unload_dynamic_module(mod);
571 ast_update_use_count();
576 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
578 struct ast_module *cur;
579 int i, which=0, l = strlen(word);
585 AST_LIST_LOCK(&module_list);
586 AST_LIST_TRAVERSE(&module_list, cur, entry) {
587 if (!strncasecmp(word, cur->resource, l) &&
588 (cur->info->reload || !needsreload) &&
590 ret = ast_strdup(cur->resource);
594 AST_LIST_UNLOCK(&module_list);
597 for (i=0; !ret && reload_classes[i].name; i++) {
598 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
599 ret = ast_strdup(reload_classes[i].name);
606 void ast_process_pending_reloads(void)
608 struct reload_queue_item *item;
610 if (!ast_fully_booted) {
614 AST_LIST_LOCK(&reload_queue);
616 if (do_full_reload) {
618 AST_LIST_UNLOCK(&reload_queue);
619 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
620 ast_module_reload(NULL);
624 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
625 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
626 ast_module_reload(item->module);
630 AST_LIST_UNLOCK(&reload_queue);
633 static void queue_reload_request(const char *module)
635 struct reload_queue_item *item;
637 AST_LIST_LOCK(&reload_queue);
639 if (do_full_reload) {
640 AST_LIST_UNLOCK(&reload_queue);
644 if (ast_strlen_zero(module)) {
645 /* A full reload request (when module is NULL) wipes out any previous
646 reload requests and causes the queue to ignore future ones */
647 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
652 /* No reason to add the same module twice */
653 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
654 if (!strcasecmp(item->module, module)) {
655 AST_LIST_UNLOCK(&reload_queue);
659 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
661 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
662 AST_LIST_UNLOCK(&reload_queue);
665 strcpy(item->module, module);
666 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
668 AST_LIST_UNLOCK(&reload_queue);
671 int ast_module_reload(const char *name)
673 struct ast_module *cur;
674 int res = 0; /* return value. 0 = not found, others, see below */
677 /* If we aren't fully booted, we just pretend we reloaded but we queue this
678 up to run once we are booted up. */
679 if (!ast_fully_booted) {
680 queue_reload_request(name);
684 if (ast_mutex_trylock(&reloadlock)) {
685 ast_verbose("The previous reload command didn't finish yet\n");
686 return -1; /* reload already in progress */
688 ast_lastreloadtime = ast_tvnow();
690 if (ast_opt_lock_confdir) {
693 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
694 res = ast_lock_path(ast_config_AST_CONFIG_DIR);
695 if (res == AST_LOCK_TIMEOUT) {
696 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
699 if (res != AST_LOCK_SUCCESS) {
700 ast_verbose("Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
701 ast_mutex_unlock(&reloadlock);
706 /* Call "predefined" reload here first */
707 for (i = 0; reload_classes[i].name; i++) {
708 if (!name || !strcasecmp(name, reload_classes[i].name)) {
709 reload_classes[i].reload_fn(); /* XXX should check error ? */
710 res = 2; /* found and reloaded */
715 if (ast_opt_lock_confdir) {
716 ast_unlock_path(ast_config_AST_CONFIG_DIR);
718 ast_mutex_unlock(&reloadlock);
722 AST_LIST_LOCK(&module_list);
723 AST_LIST_TRAVERSE(&module_list, cur, entry) {
724 const struct ast_module_info *info = cur->info;
726 if (name && resource_name_match(name, cur->resource))
729 if (!cur->flags.running || cur->flags.declined) {
732 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. "
733 "Before reloading the module, you must run \"module load %s\" "
734 "and fix whatever is preventing the module from being initialized.\n",
736 res = 2; /* Don't report that the module was not found */
740 if (!info->reload) { /* cannot be reloaded */
741 if (res < 1) /* store result if possible */
742 res = 1; /* 1 = no reload() method */
747 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
750 AST_LIST_UNLOCK(&module_list);
752 if (ast_opt_lock_confdir) {
753 ast_unlock_path(ast_config_AST_CONFIG_DIR);
755 ast_mutex_unlock(&reloadlock);
760 static unsigned int inspect_module(const struct ast_module *mod)
762 if (!mod->info->description) {
763 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
767 if (!mod->info->key) {
768 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
772 if (verify_key((unsigned char *) mod->info->key)) {
773 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
777 if (!ast_strlen_zero(mod->info->buildopt_sum) &&
778 strcmp(buildopt_sum, mod->info->buildopt_sum)) {
779 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
780 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
787 static enum ast_module_load_result start_resource(struct ast_module *mod)
790 enum ast_module_load_result res;
792 if (!mod->info->load) {
793 return AST_MODULE_LOAD_FAILURE;
796 res = mod->info->load();
799 case AST_MODULE_LOAD_SUCCESS:
800 if (!ast_fully_booted) {
801 ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
802 if (ast_opt_console && !option_verbose) {
803 /* This never looks good on anything but the root console, so
804 * it's best not to try to funnel it through the logger. */
805 fprintf(stdout, ".");
808 ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
811 mod->flags.running = 1;
813 ast_update_use_count();
815 case AST_MODULE_LOAD_DECLINE:
816 mod->flags.declined = 1;
818 case AST_MODULE_LOAD_FAILURE:
819 case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
820 case AST_MODULE_LOAD_PRIORITY:
827 /*! loads a resource based upon resource_name. If global_symbols_only is set
828 * only modules with global symbols will be loaded.
830 * If the ast_heap is provided (not NULL) the module is found and added to the
831 * heap without running the module's load() function. By doing this, modules
832 * added to the resource_heap can be initialized later in order by priority.
834 * If the ast_heap is not provided, the module's load function will be executed
836 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
838 struct ast_module *mod;
839 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
841 if ((mod = find_resource(resource_name, 0))) {
842 if (mod->flags.running) {
843 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
844 return AST_MODULE_LOAD_DECLINE;
846 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
847 return AST_MODULE_LOAD_SKIP;
849 #ifdef LOADABLE_MODULES
850 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
851 /* don't generate a warning message during load_modules() */
852 if (!global_symbols_only) {
853 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
854 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
856 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
860 ast_log(LOG_WARNING, "Module support is not available. Module '%s' could not be loaded.\n", resource_name);
861 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
865 if (inspect_module(mod)) {
866 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
867 #ifdef LOADABLE_MODULES
868 unload_dynamic_module(mod);
870 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
873 if (!mod->lib && mod->info->backup_globals && mod->info->backup_globals()) {
874 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
875 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
878 mod->flags.declined = 0;
881 ast_heap_push(resource_heap, mod);
882 res = AST_MODULE_LOAD_PRIORITY;
884 res = start_resource(mod);
887 /* Now make sure that the list is sorted */
888 AST_LIST_LOCK(&module_list);
889 AST_LIST_REMOVE(&module_list, mod, entry);
890 AST_LIST_INSERT_SORTALPHA(&module_list, mod, entry, resource);
891 AST_LIST_UNLOCK(&module_list);
896 int ast_load_resource(const char *resource_name)
899 AST_LIST_LOCK(&module_list);
900 res = load_resource(resource_name, 0, NULL, 0);
901 AST_LIST_UNLOCK(&module_list);
906 struct load_order_entry {
909 AST_LIST_ENTRY(load_order_entry) entry;
912 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
914 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
916 struct load_order_entry *order;
918 AST_LIST_TRAVERSE(load_order, order, entry) {
919 if (!resource_name_match(order->resource, resource)) {
920 /* Make sure we have the proper setting for the required field
921 (we might have both load= and required= lines in modules.conf) */
922 order->required |= required;
927 if (!(order = ast_calloc(1, sizeof(*order))))
930 order->resource = ast_strdup(resource);
931 order->required = required;
932 AST_LIST_INSERT_TAIL(load_order, order, entry);
937 static int mod_load_cmp(void *a, void *b)
939 struct ast_module *a_mod = (struct ast_module *) a;
940 struct ast_module *b_mod = (struct ast_module *) b;
942 /* if load_pri is not set, default is 128. Lower is better*/
943 unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
944 unsigned char b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
945 if (a_pri == b_pri) {
947 } else if (a_pri < b_pri) {
953 /*! loads modules in order by load_pri, updates mod_count
954 \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
956 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
958 struct ast_heap *resource_heap;
959 struct load_order_entry *order;
960 struct ast_module *mod;
964 if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
968 /* first, add find and add modules to heap */
969 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
970 switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
971 case AST_MODULE_LOAD_SUCCESS:
972 case AST_MODULE_LOAD_DECLINE:
973 AST_LIST_REMOVE_CURRENT(entry);
974 ast_free(order->resource);
977 case AST_MODULE_LOAD_FAILURE:
978 ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
979 fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
980 res = order->required ? -2 : -1;
982 case AST_MODULE_LOAD_SKIP:
984 case AST_MODULE_LOAD_PRIORITY:
985 AST_LIST_REMOVE_CURRENT(entry);
989 AST_LIST_TRAVERSE_SAFE_END;
991 /* second remove modules from heap sorted by priority */
992 while ((mod = ast_heap_pop(resource_heap))) {
993 switch (start_resource(mod)) {
994 case AST_MODULE_LOAD_SUCCESS:
996 case AST_MODULE_LOAD_DECLINE:
998 case AST_MODULE_LOAD_FAILURE:
1001 case AST_MODULE_LOAD_SKIP:
1002 case AST_MODULE_LOAD_PRIORITY:
1009 *mod_count += count;
1011 ast_heap_destroy(resource_heap);
1016 int load_modules(unsigned int preload_only)
1018 struct ast_config *cfg;
1019 struct ast_module *mod;
1020 struct load_order_entry *order;
1021 struct ast_variable *v;
1022 unsigned int load_count;
1023 struct load_order load_order;
1025 struct ast_flags config_flags = { 0 };
1026 int modulecount = 0;
1028 #ifdef LOADABLE_MODULES
1029 struct dirent *dirent;
1033 /* all embedded modules have registered themselves by now */
1036 ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1038 AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1040 AST_LIST_LOCK(&module_list);
1042 if (embedded_module_list.first) {
1043 module_list.first = embedded_module_list.first;
1044 module_list.last = embedded_module_list.last;
1045 embedded_module_list.first = NULL;
1048 cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1049 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1050 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1054 /* first, find all the modules we have been explicitly requested to load */
1055 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1056 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1057 add_to_load_order(v->value, &load_order, 0);
1059 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1060 /* Add the module to the list and make sure it's required */
1061 add_to_load_order(v->value, &load_order, 1);
1062 ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1067 /* check if 'autoload' is on */
1068 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1069 /* if so, first add all the embedded modules that are not already running to the load order */
1070 AST_LIST_TRAVERSE(&module_list, mod, entry) {
1071 /* if it's not embedded, skip it */
1075 if (mod->flags.running)
1078 order = add_to_load_order(mod->resource, &load_order, 0);
1081 #ifdef LOADABLE_MODULES
1082 /* if we are allowed to load dynamic modules, scan the directory for
1083 for all available modules and add them as well */
1084 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1085 while ((dirent = readdir(dir))) {
1086 int ld = strlen(dirent->d_name);
1088 /* Must end in .so to load it. */
1093 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1096 /* if there is already a module by this name in the module_list,
1098 if (find_resource(dirent->d_name, 0))
1101 add_to_load_order(dirent->d_name, &load_order, 0);
1107 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1108 ast_config_AST_MODULE_DIR);
1113 /* now scan the config for any modules we are prohibited from loading and
1114 remove them from the load order */
1115 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1116 if (strcasecmp(v->name, "noload"))
1119 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1120 if (!resource_name_match(order->resource, v->value)) {
1121 AST_LIST_REMOVE_CURRENT(entry);
1122 ast_free(order->resource);
1126 AST_LIST_TRAVERSE_SAFE_END;
1129 /* we are done with the config now, all the information we need is in the
1131 ast_config_destroy(cfg);
1134 AST_LIST_TRAVERSE(&load_order, order, entry)
1138 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1140 /* first, load only modules that provide global symbols */
1141 if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1145 /* now load everything else */
1146 if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1151 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1152 ast_free(order->resource);
1156 AST_LIST_UNLOCK(&module_list);
1158 /* Tell manager clients that are aggressive at logging in that we're done
1159 loading modules. If there's a DNS problem in chan_sip, we might not
1161 manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1166 void ast_update_use_count(void)
1168 /* Notify any module monitors that the use count for a
1169 resource has changed */
1170 struct loadupdate *m;
1172 AST_LIST_LOCK(&updaters);
1173 AST_LIST_TRAVERSE(&updaters, m, entry)
1175 AST_LIST_UNLOCK(&updaters);
1178 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
1181 struct ast_module *cur;
1183 int total_mod_loaded = 0;
1185 if (AST_LIST_TRYLOCK(&module_list))
1188 AST_LIST_TRAVERSE(&module_list, cur, entry) {
1189 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1193 AST_LIST_UNLOCK(&module_list);
1195 return total_mod_loaded;
1198 /*! \brief Check if module exists */
1199 int ast_module_check(const char *name)
1201 struct ast_module *cur;
1203 if (ast_strlen_zero(name))
1204 return 0; /* FALSE */
1206 cur = find_resource(name, 1);
1208 return (cur != NULL);
1212 int ast_loader_register(int (*v)(void))
1214 struct loadupdate *tmp;
1216 if (!(tmp = ast_malloc(sizeof(*tmp))))
1220 AST_LIST_LOCK(&updaters);
1221 AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1222 AST_LIST_UNLOCK(&updaters);
1227 int ast_loader_unregister(int (*v)(void))
1229 struct loadupdate *cur;
1231 AST_LIST_LOCK(&updaters);
1232 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1233 if (cur->updater == v) {
1234 AST_LIST_REMOVE_CURRENT(entry);
1238 AST_LIST_TRAVERSE_SAFE_END;
1239 AST_LIST_UNLOCK(&updaters);
1241 return cur ? 0 : -1;
1244 struct ast_module *ast_module_ref(struct ast_module *mod)
1250 ast_atomic_fetchadd_int(&mod->usecount, +1);
1251 ast_update_use_count();
1256 void ast_module_unref(struct ast_module *mod)
1262 ast_atomic_fetchadd_int(&mod->usecount, -1);
1263 ast_update_use_count();