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>
31 <support_level>core</support_level>
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38 #include "asterisk/_private.h"
39 #include "asterisk/paths.h" /* use ast_config_AST_MODULE_DIR */
42 #include "asterisk/linkedlists.h"
43 #include "asterisk/module.h"
44 #include "asterisk/config.h"
45 #include "asterisk/channel.h"
46 #include "asterisk/term.h"
47 #include "asterisk/acl.h"
48 #include "asterisk/manager.h"
49 #include "asterisk/cdr.h"
50 #include "asterisk/enum.h"
51 #include "asterisk/http.h"
52 #include "asterisk/lock.h"
53 #include "asterisk/features.h"
54 #include "asterisk/dsp.h"
55 #include "asterisk/udptl.h"
56 #include "asterisk/heap.h"
57 #include "asterisk/app.h"
58 #include "asterisk/test.h"
62 #include "asterisk/md5.h"
63 #include "asterisk/utils.h"
76 struct ast_module_user {
77 struct ast_channel *chan;
78 AST_LIST_ENTRY(ast_module_user) entry;
81 AST_LIST_HEAD(module_user_list, ast_module_user);
83 static const unsigned char expected_key[] =
84 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
85 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
87 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
89 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
90 since they are here before we dlopen() any
94 const struct ast_module_info *info;
95 void *lib; /* the shared lib, or NULL if embedded */
96 int usecount; /* the number of 'users' currently in this module */
97 struct module_user_list users; /* the list of users in the module */
99 unsigned int running:1;
100 unsigned int declined:1;
102 AST_LIST_ENTRY(ast_module) entry;
106 static AST_LIST_HEAD_STATIC(module_list, ast_module);
108 const char *ast_module_name(const struct ast_module *mod)
110 if (!mod || !mod->info) {
114 return mod->info->name;
118 * module_list is cleared by its constructor possibly after
119 * we start accumulating embedded modules, so we need to
120 * use another list (without the lock) to accumulate them.
121 * Then we update the main list when embedding is done.
123 static struct module_list embedded_module_list;
126 int (*updater)(void);
127 AST_LIST_ENTRY(loadupdate) entry;
130 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
132 AST_MUTEX_DEFINE_STATIC(reloadlock);
134 struct reload_queue_item {
135 AST_LIST_ENTRY(reload_queue_item) entry;
139 static int do_full_reload = 0;
141 static AST_LIST_HEAD_STATIC(reload_queue, reload_queue_item);
143 /* when dynamic modules are being loaded, ast_module_register() will
144 need to know what filename the module was loaded from while it
147 static struct ast_module *resource_being_loaded;
149 /* XXX: should we check for duplicate resource names here? */
151 void ast_module_register(const struct ast_module_info *info)
153 struct ast_module *mod;
156 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
158 strcpy(mod->resource, info->name);
160 mod = resource_being_loaded;
164 AST_LIST_HEAD_INIT(&mod->users);
166 /* during startup, before the loader has been initialized,
167 there are no threads, so there is no need to take the lock
168 on this list to manipulate it. it is also possible that it
169 might be unsafe to use the list lock at that point... so
170 let's avoid it altogether
173 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
175 AST_LIST_LOCK(&module_list);
176 /* it is paramount that the new entry be placed at the tail of
177 the list, otherwise the code that uses dlopen() to load
178 dynamic modules won't be able to find out if the module it
179 just opened was registered or failed to load
181 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
182 AST_LIST_UNLOCK(&module_list);
185 /* give the module a copy of its own handle, for later use in registrations and the like */
186 *((struct ast_module **) &(info->self)) = mod;
189 void ast_module_unregister(const struct ast_module_info *info)
191 struct ast_module *mod = NULL;
193 /* it is assumed that the users list in the module structure
194 will already be empty, or we cannot have gotten to this
197 AST_LIST_LOCK(&module_list);
198 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
199 if (mod->info == info) {
200 AST_LIST_REMOVE_CURRENT(entry);
204 AST_LIST_TRAVERSE_SAFE_END;
205 AST_LIST_UNLOCK(&module_list);
208 AST_LIST_HEAD_DESTROY(&mod->users);
213 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
215 struct ast_module_user *u;
217 u = ast_calloc(1, sizeof(*u));
224 AST_LIST_LOCK(&mod->users);
225 AST_LIST_INSERT_HEAD(&mod->users, u, entry);
226 AST_LIST_UNLOCK(&mod->users);
228 ast_atomic_fetchadd_int(&mod->usecount, +1);
230 ast_update_use_count();
235 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
241 AST_LIST_LOCK(&mod->users);
242 u = AST_LIST_REMOVE(&mod->users, u, entry);
243 AST_LIST_UNLOCK(&mod->users);
246 * Was not in the list. Either a bad pointer or
247 * __ast_module_user_hangup_all() has been called.
252 ast_atomic_fetchadd_int(&mod->usecount, -1);
255 ast_update_use_count();
258 void __ast_module_user_hangup_all(struct ast_module *mod)
260 struct ast_module_user *u;
262 AST_LIST_LOCK(&mod->users);
263 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
265 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
267 ast_atomic_fetchadd_int(&mod->usecount, -1);
270 AST_LIST_UNLOCK(&mod->users);
272 ast_update_use_count();
276 * In addition to modules, the reload command handles some extra keywords
277 * which are listed here together with the corresponding handlers.
278 * This table is also used by the command completion code.
280 static struct reload_classes {
282 int (*reload_fn)(void);
283 } reload_classes[] = { /* list in alpha order, longest match first for cli completion */
284 { "cdr", ast_cdr_engine_reload },
285 { "dnsmgr", dnsmgr_reload },
286 { "extconfig", read_config_maps },
287 { "enum", ast_enum_reload },
288 { "acl", ast_named_acl_reload },
289 { "manager", reload_manager },
290 { "http", ast_http_reload },
291 { "logger", logger_reload },
292 { "features", ast_features_reload },
293 { "dsp", ast_dsp_reload},
294 { "udptl", ast_udptl_reload },
295 { "indications", ast_indications_reload },
296 { "cel", ast_cel_engine_reload },
297 { "plc", ast_plc_reload },
301 static int printdigest(const unsigned char *d)
304 char buf[256]; /* large enough so we don't have to worry */
306 for (pos = 0, x = 0; x < 16; x++)
307 pos += sprintf(buf + pos, " %02x", *d++);
309 ast_debug(1, "Unexpected signature:%s\n", buf);
314 static int key_matches(const unsigned char *key1, const unsigned char *key2)
318 for (x = 0; x < 16; x++) {
319 if (key1[x] != key2[x])
326 static int verify_key(const unsigned char *key)
329 unsigned char digest[16];
332 MD5Update(&c, key, strlen((char *)key));
333 MD5Final(digest, &c);
335 if (key_matches(expected_key, digest))
343 static int resource_name_match(const char *name1_in, const char *name2_in)
345 char *name1 = (char *) name1_in;
346 char *name2 = (char *) name2_in;
348 /* trim off any .so extensions */
349 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
350 name1 = ast_strdupa(name1);
351 name1[strlen(name1) - 3] = '\0';
353 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
354 name2 = ast_strdupa(name2);
355 name2[strlen(name2) - 3] = '\0';
358 return strcasecmp(name1, name2);
361 static struct ast_module *find_resource(const char *resource, int do_lock)
363 struct ast_module *cur;
366 AST_LIST_LOCK(&module_list);
368 AST_LIST_TRAVERSE(&module_list, cur, entry) {
369 if (!resource_name_match(resource, cur->resource))
374 AST_LIST_UNLOCK(&module_list);
379 #ifdef LOADABLE_MODULES
380 static void unload_dynamic_module(struct ast_module *mod)
382 void *lib = mod->lib;
384 /* WARNING: the structure pointed to by mod is going to
385 disappear when this operation succeeds, so we can't
389 while (!dlclose(lib));
392 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required);
394 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, struct ast_heap *resource_heap)
396 char fn[PATH_MAX] = "";
398 struct ast_module *mod;
399 unsigned int wants_global;
400 int space; /* room needed for the descriptor */
403 space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
404 if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
406 space += 3; /* room for the extra ".so" */
409 snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
411 /* make a first load of the module in 'quiet' mode... don't try to resolve
412 any symbols, and don't export any symbols. this will allow us to peek into
413 the module's info block (if available) to see what flags it has set */
415 resource_being_loaded = ast_calloc(1, space);
416 if (!resource_being_loaded)
418 strcpy(resource_being_loaded->resource, resource_in);
420 strcat(resource_being_loaded->resource, ".so");
422 if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
423 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
424 ast_free(resource_being_loaded);
428 /* the dlopen() succeeded, let's find out if the module
430 /* note that this will only work properly as long as
431 ast_module_register() (which is called by the module's
432 constructor) places the new module at the tail of the
435 if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
436 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
437 /* no, it did not, so close it and return */
438 while (!dlclose(lib));
439 /* note that the module's destructor will call ast_module_unregister(),
440 which will free the structure we allocated in resource_being_loaded */
444 wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
446 /* if we are being asked only to load modules that provide global symbols,
447 and this one does not, then close it and return */
448 if (global_symbols_only && !wants_global) {
449 while (!dlclose(lib));
453 /* This section is a workaround for a gcc 4.1 bug that has already been
454 * fixed in later versions. Unfortunately, some distributions, such as
455 * RHEL/CentOS 5, distribute gcc 4.1, so we're stuck with having to deal
456 * with this issue. This basically ensures that optional_api modules are
457 * loaded before any module which requires their functionality. */
458 #if !defined(HAVE_ATTRIBUTE_weak_import) && !defined(HAVE_ATTRIBUTE_weakref)
459 if (!ast_strlen_zero(mod->info->nonoptreq)) {
460 /* Force any required dependencies to load */
461 char *each, *required_resource = ast_strdupa(mod->info->nonoptreq);
462 while ((each = strsep(&required_resource, ","))) {
463 struct ast_module *dependency;
464 each = ast_strip(each);
465 dependency = find_resource(each, 0);
466 /* Is it already loaded? */
468 load_resource(each, global_symbols_only, resource_heap, 1);
474 while (!dlclose(lib));
475 resource_being_loaded = NULL;
477 /* start the load process again */
478 resource_being_loaded = ast_calloc(1, space);
479 if (!resource_being_loaded)
481 strcpy(resource_being_loaded->resource, resource_in);
483 strcat(resource_being_loaded->resource, ".so");
485 if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
486 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
487 ast_free(resource_being_loaded);
491 /* since the module was successfully opened, and it registered itself
492 the previous time we did that, we're going to assume it worked this
495 AST_LIST_LAST(&module_list)->lib = lib;
496 resource_being_loaded = NULL;
498 return AST_LIST_LAST(&module_list);
502 void ast_module_shutdown(void)
504 struct ast_module *mod;
505 int somethingchanged = 1, final = 0;
507 AST_LIST_LOCK(&module_list);
509 /*!\note Some resources, like timers, are started up dynamically, and thus
510 * may be still in use, even if all channels are dead. We must therefore
511 * check the usecount before asking modules to unload. */
513 if (!somethingchanged) {
514 /*!\note If we go through the entire list without changing
515 * anything, ignore the usecounts and unload, then exit. */
519 /* Reset flag before traversing the list */
520 somethingchanged = 0;
522 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
523 if (!final && mod->usecount) {
526 AST_LIST_REMOVE_CURRENT(entry);
527 if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
530 AST_LIST_HEAD_DESTROY(&mod->users);
532 somethingchanged = 1;
534 AST_LIST_TRAVERSE_SAFE_END;
535 } while (somethingchanged && !final);
537 AST_LIST_UNLOCK(&module_list);
540 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
542 struct ast_module *mod;
546 AST_LIST_LOCK(&module_list);
548 if (!(mod = find_resource(resource_name, 0))) {
549 AST_LIST_UNLOCK(&module_list);
550 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
554 if (!mod->flags.running || mod->flags.declined) {
555 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
559 if (!error && (mod->usecount > 0)) {
561 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
562 resource_name, mod->usecount);
564 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
571 /* Request any channels attached to the module to hangup. */
572 __ast_module_user_hangup_all(mod);
574 res = mod->info->unload();
576 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
577 if (force <= AST_FORCE_FIRM) {
580 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
586 * Request hangup on any channels that managed to get attached
587 * while we called the module unload function.
589 __ast_module_user_hangup_all(mod);
595 mod->flags.running = mod->flags.declined = 0;
597 AST_LIST_UNLOCK(&module_list);
599 if (!error && !mod->lib && mod->info && mod->info->restore_globals)
600 mod->info->restore_globals();
602 #ifdef LOADABLE_MODULES
604 unload_dynamic_module(mod);
605 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
610 ast_update_use_count();
615 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
617 struct ast_module *cur;
618 int i, which=0, l = strlen(word);
624 AST_LIST_LOCK(&module_list);
625 AST_LIST_TRAVERSE(&module_list, cur, entry) {
626 if (!strncasecmp(word, cur->resource, l) &&
627 (cur->info->reload || !needsreload) &&
629 ret = ast_strdup(cur->resource);
633 AST_LIST_UNLOCK(&module_list);
636 for (i=0; !ret && reload_classes[i].name; i++) {
637 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
638 ret = ast_strdup(reload_classes[i].name);
645 void ast_process_pending_reloads(void)
647 struct reload_queue_item *item;
649 if (!ast_fully_booted) {
653 AST_LIST_LOCK(&reload_queue);
655 if (do_full_reload) {
657 AST_LIST_UNLOCK(&reload_queue);
658 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
659 ast_module_reload(NULL);
663 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
664 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
665 ast_module_reload(item->module);
669 AST_LIST_UNLOCK(&reload_queue);
672 static void queue_reload_request(const char *module)
674 struct reload_queue_item *item;
676 AST_LIST_LOCK(&reload_queue);
678 if (do_full_reload) {
679 AST_LIST_UNLOCK(&reload_queue);
683 if (ast_strlen_zero(module)) {
684 /* A full reload request (when module is NULL) wipes out any previous
685 reload requests and causes the queue to ignore future ones */
686 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
691 /* No reason to add the same module twice */
692 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
693 if (!strcasecmp(item->module, module)) {
694 AST_LIST_UNLOCK(&reload_queue);
698 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
700 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
701 AST_LIST_UNLOCK(&reload_queue);
704 strcpy(item->module, module);
705 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
707 AST_LIST_UNLOCK(&reload_queue);
710 int ast_module_reload(const char *name)
712 struct ast_module *cur;
713 int res = 0; /* return value. 0 = not found, others, see below */
716 /* If we aren't fully booted, we just pretend we reloaded but we queue this
717 up to run once we are booted up. */
718 if (!ast_fully_booted) {
719 queue_reload_request(name);
723 if (ast_mutex_trylock(&reloadlock)) {
724 ast_verbose("The previous reload command didn't finish yet\n");
725 return -1; /* reload already in progress */
727 ast_lastreloadtime = ast_tvnow();
729 if (ast_opt_lock_confdir) {
732 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
733 res = ast_lock_path(ast_config_AST_CONFIG_DIR);
734 if (res == AST_LOCK_TIMEOUT) {
735 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
738 if (res != AST_LOCK_SUCCESS) {
739 ast_verbose("Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
740 ast_mutex_unlock(&reloadlock);
745 /* Call "predefined" reload here first */
746 for (i = 0; reload_classes[i].name; i++) {
747 if (!name || !strcasecmp(name, reload_classes[i].name)) {
748 if (!reload_classes[i].reload_fn()) {
749 ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", name);
751 res = 2; /* found and reloaded */
756 if (ast_opt_lock_confdir) {
757 ast_unlock_path(ast_config_AST_CONFIG_DIR);
759 ast_mutex_unlock(&reloadlock);
763 AST_LIST_LOCK(&module_list);
764 AST_LIST_TRAVERSE(&module_list, cur, entry) {
765 const struct ast_module_info *info = cur->info;
767 if (name && resource_name_match(name, cur->resource))
770 if (!cur->flags.running || cur->flags.declined) {
773 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. "
774 "Before reloading the module, you must run \"module load %s\" "
775 "and fix whatever is preventing the module from being initialized.\n",
777 res = 2; /* Don't report that the module was not found */
781 if (!info->reload) { /* cannot be reloaded */
782 /* Nothing to reload, so reload is successful */
783 ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource);
784 if (res < 1) /* store result if possible */
785 res = 1; /* 1 = no reload() method */
790 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
791 if (!info->reload()) {
792 ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource);
795 AST_LIST_UNLOCK(&module_list);
797 if (ast_opt_lock_confdir) {
798 ast_unlock_path(ast_config_AST_CONFIG_DIR);
800 ast_mutex_unlock(&reloadlock);
805 static unsigned int inspect_module(const struct ast_module *mod)
807 if (!mod->info->description) {
808 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
812 if (!mod->info->key) {
813 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
817 if (verify_key((unsigned char *) mod->info->key)) {
818 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
822 if (!ast_strlen_zero(mod->info->buildopt_sum) &&
823 strcmp(buildopt_sum, mod->info->buildopt_sum)) {
824 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
825 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
832 static enum ast_module_load_result start_resource(struct ast_module *mod)
835 enum ast_module_load_result res;
837 if (mod->flags.running) {
838 return AST_MODULE_LOAD_SUCCESS;
841 if (!mod->info->load) {
842 return AST_MODULE_LOAD_FAILURE;
845 res = mod->info->load();
848 case AST_MODULE_LOAD_SUCCESS:
849 if (!ast_fully_booted) {
850 ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
851 if (ast_opt_console && !option_verbose) {
852 /* This never looks good on anything but the root console, so
853 * it's best not to try to funnel it through the logger. */
854 fprintf(stdout, ".");
857 ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
860 mod->flags.running = 1;
862 ast_update_use_count();
864 case AST_MODULE_LOAD_DECLINE:
865 mod->flags.declined = 1;
867 case AST_MODULE_LOAD_FAILURE:
868 case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
869 case AST_MODULE_LOAD_PRIORITY:
876 /*! loads a resource based upon resource_name. If global_symbols_only is set
877 * only modules with global symbols will be loaded.
879 * If the ast_heap is provided (not NULL) the module is found and added to the
880 * heap without running the module's load() function. By doing this, modules
881 * added to the resource_heap can be initialized later in order by priority.
883 * If the ast_heap is not provided, the module's load function will be executed
885 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
887 struct ast_module *mod;
888 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
890 if ((mod = find_resource(resource_name, 0))) {
891 if (mod->flags.running) {
892 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
893 return AST_MODULE_LOAD_DECLINE;
895 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
896 return AST_MODULE_LOAD_SKIP;
898 #ifdef LOADABLE_MODULES
899 if (!(mod = load_dynamic_module(resource_name, global_symbols_only, resource_heap))) {
900 /* don't generate a warning message during load_modules() */
901 if (!global_symbols_only) {
902 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
903 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
905 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
909 ast_log(LOG_WARNING, "Module support is not available. Module '%s' could not be loaded.\n", resource_name);
910 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
914 if (inspect_module(mod)) {
915 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
916 #ifdef LOADABLE_MODULES
917 unload_dynamic_module(mod);
919 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
922 if (!mod->lib && mod->info->backup_globals && mod->info->backup_globals()) {
923 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
924 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
927 mod->flags.declined = 0;
930 ast_heap_push(resource_heap, mod);
931 res = AST_MODULE_LOAD_PRIORITY;
933 res = start_resource(mod);
936 /* Now make sure that the list is sorted */
937 AST_LIST_LOCK(&module_list);
938 AST_LIST_REMOVE(&module_list, mod, entry);
939 AST_LIST_INSERT_SORTALPHA(&module_list, mod, entry, resource);
940 AST_LIST_UNLOCK(&module_list);
945 int ast_load_resource(const char *resource_name)
948 AST_LIST_LOCK(&module_list);
949 res = load_resource(resource_name, 0, NULL, 0);
951 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
953 AST_LIST_UNLOCK(&module_list);
958 struct load_order_entry {
961 AST_LIST_ENTRY(load_order_entry) entry;
964 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
966 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
968 struct load_order_entry *order;
970 AST_LIST_TRAVERSE(load_order, order, entry) {
971 if (!resource_name_match(order->resource, resource)) {
972 /* Make sure we have the proper setting for the required field
973 (we might have both load= and required= lines in modules.conf) */
974 order->required |= required;
979 if (!(order = ast_calloc(1, sizeof(*order))))
982 order->resource = ast_strdup(resource);
983 order->required = required;
984 AST_LIST_INSERT_TAIL(load_order, order, entry);
989 static int mod_load_cmp(void *a, void *b)
991 struct ast_module *a_mod = (struct ast_module *) a;
992 struct ast_module *b_mod = (struct ast_module *) b;
994 /* if load_pri is not set, default is 128. Lower is better*/
995 unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
996 unsigned char b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
997 if (a_pri == b_pri) {
999 } else if (a_pri < b_pri) {
1005 /*! loads modules in order by load_pri, updates mod_count
1006 \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1008 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
1010 struct ast_heap *resource_heap;
1011 struct load_order_entry *order;
1012 struct ast_module *mod;
1016 if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
1020 /* first, add find and add modules to heap */
1021 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1022 switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
1023 case AST_MODULE_LOAD_SUCCESS:
1024 case AST_MODULE_LOAD_DECLINE:
1025 AST_LIST_REMOVE_CURRENT(entry);
1026 ast_free(order->resource);
1029 case AST_MODULE_LOAD_FAILURE:
1030 ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1031 fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1032 res = order->required ? -2 : -1;
1034 case AST_MODULE_LOAD_SKIP:
1036 case AST_MODULE_LOAD_PRIORITY:
1037 AST_LIST_REMOVE_CURRENT(entry);
1041 AST_LIST_TRAVERSE_SAFE_END;
1043 /* second remove modules from heap sorted by priority */
1044 while ((mod = ast_heap_pop(resource_heap))) {
1045 switch (start_resource(mod)) {
1046 case AST_MODULE_LOAD_SUCCESS:
1048 case AST_MODULE_LOAD_DECLINE:
1050 case AST_MODULE_LOAD_FAILURE:
1053 case AST_MODULE_LOAD_SKIP:
1054 case AST_MODULE_LOAD_PRIORITY:
1061 *mod_count += count;
1063 ast_heap_destroy(resource_heap);
1068 int load_modules(unsigned int preload_only)
1070 struct ast_config *cfg;
1071 struct ast_module *mod;
1072 struct load_order_entry *order;
1073 struct ast_variable *v;
1074 unsigned int load_count;
1075 struct load_order load_order;
1077 struct ast_flags config_flags = { 0 };
1078 int modulecount = 0;
1080 #ifdef LOADABLE_MODULES
1081 struct dirent *dirent;
1085 /* all embedded modules have registered themselves by now */
1088 ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1090 AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1092 AST_LIST_LOCK(&module_list);
1094 if (embedded_module_list.first) {
1095 module_list.first = embedded_module_list.first;
1096 module_list.last = embedded_module_list.last;
1097 embedded_module_list.first = NULL;
1100 cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1101 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1102 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1106 /* first, find all the modules we have been explicitly requested to load */
1107 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1108 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1109 add_to_load_order(v->value, &load_order, 0);
1111 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1112 /* Add the module to the list and make sure it's required */
1113 add_to_load_order(v->value, &load_order, 1);
1114 ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1119 /* check if 'autoload' is on */
1120 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1121 /* if so, first add all the embedded modules that are not already running to the load order */
1122 AST_LIST_TRAVERSE(&module_list, mod, entry) {
1123 /* if it's not embedded, skip it */
1127 if (mod->flags.running)
1130 add_to_load_order(mod->resource, &load_order, 0);
1133 #ifdef LOADABLE_MODULES
1134 /* if we are allowed to load dynamic modules, scan the directory for
1135 for all available modules and add them as well */
1136 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1137 while ((dirent = readdir(dir))) {
1138 int ld = strlen(dirent->d_name);
1140 /* Must end in .so to load it. */
1145 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1148 /* if there is already a module by this name in the module_list,
1150 if (find_resource(dirent->d_name, 0))
1153 add_to_load_order(dirent->d_name, &load_order, 0);
1159 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1160 ast_config_AST_MODULE_DIR);
1165 /* now scan the config for any modules we are prohibited from loading and
1166 remove them from the load order */
1167 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1168 if (strcasecmp(v->name, "noload"))
1171 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1172 if (!resource_name_match(order->resource, v->value)) {
1173 AST_LIST_REMOVE_CURRENT(entry);
1174 ast_free(order->resource);
1178 AST_LIST_TRAVERSE_SAFE_END;
1181 /* we are done with the config now, all the information we need is in the
1183 ast_config_destroy(cfg);
1186 AST_LIST_TRAVERSE(&load_order, order, entry)
1190 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1192 /* first, load only modules that provide global symbols */
1193 if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1197 /* now load everything else */
1198 if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1203 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1204 ast_free(order->resource);
1208 AST_LIST_UNLOCK(&module_list);
1210 /* Tell manager clients that are aggressive at logging in that we're done
1211 loading modules. If there's a DNS problem in chan_sip, we might not
1214 <managerEventInstance>
1215 <synopsis>Raised when all dynamic modules have finished their initial loading.</synopsis>
1217 <parameter name="ModuleSelection">
1219 <enum name="Preload"/>
1224 </managerEventInstance>
1226 manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1231 void ast_update_use_count(void)
1233 /* Notify any module monitors that the use count for a
1234 resource has changed */
1235 struct loadupdate *m;
1237 AST_LIST_LOCK(&updaters);
1238 AST_LIST_TRAVERSE(&updaters, m, entry)
1240 AST_LIST_UNLOCK(&updaters);
1243 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *status, const char *like),
1246 struct ast_module *cur;
1248 int total_mod_loaded = 0;
1250 if (AST_LIST_TRYLOCK(&module_list))
1253 AST_LIST_TRAVERSE(&module_list, cur, entry) {
1254 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1255 cur->flags.running ? "Running" : "Not Running", like);
1259 AST_LIST_UNLOCK(&module_list);
1261 return total_mod_loaded;
1264 /*! \brief Check if module exists */
1265 int ast_module_check(const char *name)
1267 struct ast_module *cur;
1269 if (ast_strlen_zero(name))
1270 return 0; /* FALSE */
1272 cur = find_resource(name, 1);
1274 return (cur != NULL);
1278 int ast_loader_register(int (*v)(void))
1280 struct loadupdate *tmp;
1282 if (!(tmp = ast_malloc(sizeof(*tmp))))
1286 AST_LIST_LOCK(&updaters);
1287 AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1288 AST_LIST_UNLOCK(&updaters);
1293 int ast_loader_unregister(int (*v)(void))
1295 struct loadupdate *cur;
1297 AST_LIST_LOCK(&updaters);
1298 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1299 if (cur->updater == v) {
1300 AST_LIST_REMOVE_CURRENT(entry);
1304 AST_LIST_TRAVERSE_SAFE_END;
1305 AST_LIST_UNLOCK(&updaters);
1307 return cur ? 0 : -1;
1310 struct ast_module *ast_module_ref(struct ast_module *mod)
1316 ast_atomic_fetchadd_int(&mod->usecount, +1);
1317 ast_update_use_count();
1322 void ast_module_unref(struct ast_module *mod)
1328 ast_atomic_fetchadd_int(&mod->usecount, -1);
1329 ast_update_use_count();