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$")
41 #include "asterisk/linkedlists.h"
42 #include "asterisk/module.h"
43 #include "asterisk/options.h"
44 #include "asterisk/config.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/term.h"
48 #include "asterisk/manager.h"
49 #include "asterisk/cdr.h"
50 #include "asterisk/enum.h"
51 #include "asterisk/rtp.h"
52 #include "asterisk/http.h"
53 #include "asterisk/lock.h"
56 #include "asterisk/dlfcn-compat.h"
61 #include "asterisk/md5.h"
62 #include "asterisk/utils.h"
68 struct ast_module_user {
69 struct ast_channel *chan;
70 AST_LIST_ENTRY(ast_module_user) entry;
73 AST_LIST_HEAD(module_user_list, ast_module_user);
75 static unsigned char expected_key[] =
76 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
77 0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
79 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
80 since they are here before we dlopen() any
84 FLAG_RUNNING = (1 << 1), /* module successfully initialized */
85 FLAG_DECLINED = (1 << 2), /* module declined to initialize */
89 const struct ast_module_info *info;
90 void *lib; /* the shared lib, or NULL if embedded */
91 int usecount; /* the number of 'users' currently in this module */
92 struct module_user_list users; /* the list of users in the module */
93 unsigned int flags; /* flags for this module */
94 AST_LIST_ENTRY(ast_module) entry;
98 static AST_LIST_HEAD_STATIC(module_list, ast_module);
101 int (*updater)(void);
102 AST_LIST_ENTRY(loadupdate) entry;
105 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
107 AST_MUTEX_DEFINE_STATIC(reloadlock);
109 /* when dynamic modules are being loaded, ast_module_register() will
110 need to know what filename the module was loaded from while it
113 struct ast_module *resource_being_loaded;
115 /* XXX: should we check for duplicate resource names here? */
117 void ast_module_register(const struct ast_module_info *info)
119 struct ast_module *mod;
122 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
124 strcpy(mod->resource, info->name);
126 mod = resource_being_loaded;
130 AST_LIST_HEAD_INIT(&mod->users);
132 /* during startup, before the loader has been initialized,
133 there are no threads, so there is no need to take the lock
134 on this list to manipulate it. it is also possible that it
135 might be unsafe to use the list lock at that point... so
136 let's avoid it altogether
139 AST_LIST_LOCK(&module_list);
141 /* it is paramount that the new entry be placed at the tail of
142 the list, otherwise the code that uses dlopen() to load
143 dynamic modules won't be able to find out if the module it
144 just opened was registered or failed to load
146 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
149 AST_LIST_UNLOCK(&module_list);
151 /* give the module a copy of its own handle, for later use in registrations and the like */
152 *((struct ast_module **) &(info->self)) = mod;
155 void ast_module_unregister(const struct ast_module_info *info)
157 struct ast_module *mod = NULL;
159 /* it is assumed that the users list in the module structure
160 will already be empty, or we cannot have gotten to this
163 AST_LIST_LOCK(&module_list);
164 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
165 if (mod->info == info) {
166 AST_LIST_REMOVE_CURRENT(&module_list, entry);
170 AST_LIST_TRAVERSE_SAFE_END;
171 AST_LIST_UNLOCK(&module_list);
174 AST_LIST_HEAD_DESTROY(&mod->users);
179 struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
180 struct ast_channel *chan)
182 struct ast_module_user *u = ast_calloc(1, sizeof(*u));
189 AST_LIST_LOCK(&mod->users);
190 AST_LIST_INSERT_HEAD(&mod->users, u, entry);
191 AST_LIST_UNLOCK(&mod->users);
193 ast_atomic_fetchadd_int(&mod->usecount, +1);
195 ast_update_use_count();
200 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
202 AST_LIST_LOCK(&mod->users);
203 AST_LIST_REMOVE(&mod->users, u, entry);
204 AST_LIST_UNLOCK(&mod->users);
205 ast_atomic_fetchadd_int(&mod->usecount, -1);
208 ast_update_use_count();
211 void __ast_module_user_hangup_all(struct ast_module *mod)
213 struct ast_module_user *u;
215 AST_LIST_LOCK(&mod->users);
216 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
217 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
218 ast_atomic_fetchadd_int(&mod->usecount, -1);
221 AST_LIST_UNLOCK(&mod->users);
223 ast_update_use_count();
227 * In addition to modules, the reload command handles some extra keywords
228 * which are listed here together with the corresponding handlers.
229 * This table is also used by the command completion code.
231 static struct reload_classes {
233 int (*reload_fn)(void);
234 } reload_classes[] = { /* list in alpha order, longest match first for cli completion */
235 { "cdr", ast_cdr_engine_reload },
236 { "dnsmgr", dnsmgr_reload },
237 { "extconfig", read_config_maps },
238 { "enum", ast_enum_reload },
239 { "manager", reload_manager },
240 { "rtp", ast_rtp_reload },
241 { "http", ast_http_reload },
245 static int printdigest(const unsigned char *d)
248 char buf[256]; /* large enough so we don't have to worry */
250 for (pos = 0, x = 0; x < 16; x++)
251 pos += sprintf(buf + pos, " %02x", *d++);
253 ast_log(LOG_DEBUG, "Unexpected signature:%s\n", buf);
258 static int key_matches(const unsigned char *key1, const unsigned char *key2)
262 for (x = 0; x < 16; x++) {
263 if (key1[x] != key2[x])
270 static int verify_key(const unsigned char *key)
273 unsigned char digest[16];
276 MD5Update(&c, key, strlen((char *)key));
277 MD5Final(digest, &c);
279 if (key_matches(expected_key, digest))
287 static int resource_name_match(const char *name1_in, const char *name2_in)
289 char *name1 = (char *) name1_in;
290 char *name2 = (char *) name2_in;
292 /* trim off any .so extensions */
293 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
294 name1 = ast_strdupa(name1);
295 name1[strlen(name1) - 3] = '\0';
297 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
298 name2 = ast_strdupa(name2);
299 name2[strlen(name2) - 3] = '\0';
302 return strcasecmp(name1, name2);
305 static struct ast_module *find_resource(const char *resource, int do_lock)
307 struct ast_module *cur;
310 AST_LIST_LOCK(&module_list);
312 AST_LIST_TRAVERSE(&module_list, cur, entry) {
313 if (!resource_name_match(resource, cur->resource))
318 AST_LIST_UNLOCK(&module_list);
324 static void unload_dynamic_module(struct ast_module *mod)
326 void *lib = mod->lib;
328 /* WARNING: the structure pointed to by mod is going to
329 disappear when this operation succeeds, so we can't
333 while (!dlclose(lib));
336 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
340 struct ast_module *mod;
341 char *resource = (char *) resource_in;
342 unsigned int wants_global;
344 if (strcasecmp(resource + strlen(resource) - 3, ".so")) {
345 resource = alloca(strlen(resource_in) + 3);
346 strcpy(resource, resource_in);
347 strcat(resource, ".so");
350 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR, resource);
352 /* make a first load of the module in 'quiet' mode... don't try to resolve
353 any symbols, and don't export any symbols. this will allow us to peek into
354 the module's info block (if available) to see what flags it has set */
356 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
359 strcpy(resource_being_loaded->resource, resource);
361 if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
362 ast_log(LOG_WARNING, "%s\n", dlerror());
363 free(resource_being_loaded);
367 /* the dlopen() succeeded, let's find out if the module
369 /* note that this will only work properly as long as
370 ast_module_register() (which is called by the module's
371 constructor) places the new module at the tail of the
374 if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
375 /* no, it did not, so close it and return */
376 while (!dlclose(lib));
377 /* note that the module's destructor will call ast_module_unregister(),
378 which will free the structure we allocated in resource_being_loaded */
382 wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
384 /* if we are being asked only to load modules that provide global symbols,
385 and this one does not, then close it and return */
386 if (global_symbols_only && !wants_global) {
387 while (!dlclose(lib));
391 /* if the system supports RTLD_NOLOAD, we can just 'promote' the flags
392 on the already-opened library to what we want... if not, we have to
393 close it and start over
396 if (!dlopen(fn, RTLD_NOLOAD | (wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
397 ast_log(LOG_WARNING, "%s\n", dlerror());
398 while (!dlclose(lib));
399 free(resource_being_loaded);
403 while (!dlclose(lib));
404 resource_being_loaded = NULL;
406 /* start the load process again */
408 if (!(resource_being_loaded = ast_calloc(1, sizeof(*resource_being_loaded) + strlen(resource) + 1)))
411 strcpy(resource_being_loaded->resource, resource);
413 if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
414 ast_log(LOG_WARNING, "%s\n", dlerror());
415 free(resource_being_loaded);
419 /* since the module was successfully opened, and it registered itself
420 the previous time we did that, we're going to assume it worked this
424 AST_LIST_LAST(&module_list)->lib = lib;
425 resource_being_loaded = NULL;
427 return AST_LIST_LAST(&module_list);
431 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
433 struct ast_module *mod;
437 AST_LIST_LOCK(&module_list);
439 if (!(mod = find_resource(resource_name, 0))) {
440 AST_LIST_UNLOCK(&module_list);
444 if (!ast_test_flag(mod, FLAG_RUNNING | FLAG_DECLINED))
447 if (!error && (mod->usecount > 0)) {
449 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n",
450 resource_name, mod->usecount);
452 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
459 __ast_module_user_hangup_all(mod);
460 res = mod->info->unload();
463 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
464 if (force <= AST_FORCE_FIRM)
467 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
472 ast_clear_flag(mod, FLAG_RUNNING | FLAG_DECLINED);
474 AST_LIST_UNLOCK(&module_list);
478 unload_dynamic_module(mod);
482 ast_update_use_count();
487 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
489 struct ast_module *cur;
490 int i, which=0, l = strlen(word);
496 AST_LIST_LOCK(&module_list);
497 AST_LIST_TRAVERSE(&module_list, cur, entry) {
498 if (!strncasecmp(word, cur->resource, l) &&
499 (cur->info->reload || !needsreload) &&
501 ret = strdup(cur->resource);
505 AST_LIST_UNLOCK(&module_list);
508 for (i=0; !ret && reload_classes[i].name; i++) {
509 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
510 ret = strdup(reload_classes[i].name);
517 int ast_module_reload(const char *name)
519 struct ast_module *cur;
520 int res = 0; /* return value. 0 = not found, others, see below */
523 if (ast_mutex_trylock(&reloadlock)) {
524 ast_verbose("The previous reload command didn't finish yet\n");
525 return -1; /* reload already in progress */
528 /* Call "predefined" reload here first */
529 for (i = 0; reload_classes[i].name; i++) {
530 if (!name || !strcasecmp(name, reload_classes[i].name)) {
531 reload_classes[i].reload_fn(); /* XXX should check error ? */
532 res = 2; /* found and reloaded */
535 ast_lastreloadtime = time(NULL);
540 AST_LIST_LOCK(&module_list);
541 AST_LIST_TRAVERSE(&module_list, cur, entry) {
542 const struct ast_module_info *info = cur->info;
544 if (name && resource_name_match(name, cur->resource))
547 if (!ast_test_flag(cur, FLAG_RUNNING | FLAG_DECLINED))
550 if (!info->reload) { /* cannot be reloaded */
551 if (res < 1) /* store result if possible */
552 res = 1; /* 1 = no reload() method */
557 if (option_verbose > 2)
558 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", cur->resource, info->description);
561 AST_LIST_UNLOCK(&module_list);
563 ast_mutex_unlock(&reloadlock);
568 static unsigned int inspect_module(const struct ast_module *mod)
570 if (!mod->info->description) {
571 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
575 if (!mod->info->key) {
576 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
580 if (verify_key((unsigned char *) mod->info->key)) {
581 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
588 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only)
590 struct ast_module *mod;
591 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
594 if ((mod = find_resource(resource_name, 0))) {
595 if (ast_test_flag(mod, FLAG_RUNNING)) {
596 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
597 return AST_MODULE_LOAD_DECLINE;
599 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
600 return AST_MODULE_LOAD_SKIP;
603 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
604 /* don't generate a warning message during load_modules() */
605 if (!global_symbols_only) {
606 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
607 return AST_MODULE_LOAD_DECLINE;
609 return AST_MODULE_LOAD_SKIP;
613 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
614 return AST_MODULE_LOAD_DECLINE;
618 if (inspect_module(mod)) {
619 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
621 unload_dynamic_module(mod);
623 return AST_MODULE_LOAD_DECLINE;
626 ast_clear_flag(mod, FLAG_DECLINED);
629 res = mod->info->load();
632 case AST_MODULE_LOAD_SUCCESS:
633 if (!ast_fully_booted) {
635 ast_verbose("%s => (%s)\n", resource_name, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
636 if (ast_opt_console && !option_verbose)
640 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", resource_name, mod->info->description);
643 ast_set_flag(mod, FLAG_RUNNING);
645 ast_update_use_count();
647 case AST_MODULE_LOAD_DECLINE:
648 ast_set_flag(mod, FLAG_DECLINED);
650 case AST_MODULE_LOAD_FAILURE:
652 case AST_MODULE_LOAD_SKIP:
653 /* modules should never return this value */
660 int ast_load_resource(const char *resource_name)
662 AST_LIST_LOCK(&module_list);
663 load_resource(resource_name, 0);
664 AST_LIST_UNLOCK(&module_list);
669 struct load_order_entry {
671 AST_LIST_ENTRY(load_order_entry) entry;
674 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
676 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
678 struct load_order_entry *order;
680 AST_LIST_TRAVERSE(load_order, order, entry) {
681 if (!resource_name_match(order->resource, resource))
685 if (!(order = ast_calloc(1, sizeof(*order))))
688 order->resource = ast_strdup(resource);
689 AST_LIST_INSERT_TAIL(load_order, order, entry);
694 int load_modules(unsigned int preload_only)
696 struct ast_config *cfg;
697 struct ast_module *mod;
698 struct load_order_entry *order;
699 struct ast_variable *v;
700 unsigned int load_count;
701 struct load_order load_order;
704 struct dirent *dirent;
708 /* all embedded modules have registered themselves by now */
712 ast_verbose("Asterisk Dynamic Loader Starting:\n");
714 AST_LIST_TRAVERSE(&module_list, mod, entry) {
715 if (option_debug > 1)
716 ast_log(LOG_DEBUG, "Embedded module found: %s\n", mod->resource);
719 if (!(cfg = ast_config_load(AST_MODULE_CONFIG))) {
720 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
724 AST_LIST_HEAD_INIT_NOLOCK(&load_order);
726 /* first, find all the modules we have been explicitly requested to load */
727 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
728 if (!strcasecmp(v->name, preload_only ? "preload" : "load"))
729 add_to_load_order(v->value, &load_order);
732 /* check if 'autoload' is on */
733 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
734 /* if so, first add all the embedded modules to the load order */
735 AST_LIST_TRAVERSE(&module_list, mod, entry)
736 order = add_to_load_order(mod->resource, &load_order);
739 /* if we are allowed to load dynamic modules, scan the directory for
740 for all available modules and add them as well */
741 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
742 while ((dirent = readdir(dir))) {
743 int ld = strlen(dirent->d_name);
745 /* Must end in .so to load it. */
750 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
753 add_to_load_order(dirent->d_name, &load_order);
760 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
761 ast_config_AST_MODULE_DIR);
766 /* now scan the config for any modules we are prohibited from loading and
767 remove them from the load order */
768 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
769 if (strcasecmp(v->name, "noload"))
772 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
773 if (!resource_name_match(order->resource, v->value)) {
774 AST_LIST_REMOVE_CURRENT(&load_order, entry);
775 free(order->resource);
779 AST_LIST_TRAVERSE_SAFE_END;
782 /* we are done with the config now, all the information we need is in the
784 ast_config_destroy(cfg);
787 AST_LIST_TRAVERSE(&load_order, order, entry)
791 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
793 /* first, load only modules that provide global symbols */
794 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
795 switch (load_resource(order->resource, 1)) {
796 case AST_MODULE_LOAD_SUCCESS:
797 case AST_MODULE_LOAD_DECLINE:
798 AST_LIST_REMOVE_CURRENT(&load_order, entry);
799 free(order->resource);
802 case AST_MODULE_LOAD_FAILURE:
805 case AST_MODULE_LOAD_SKIP:
806 /* try again later */
810 AST_LIST_TRAVERSE_SAFE_END;
812 /* now load everything else */
813 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
814 switch (load_resource(order->resource, 0)) {
815 case AST_MODULE_LOAD_SUCCESS:
816 case AST_MODULE_LOAD_DECLINE:
817 AST_LIST_REMOVE_CURRENT(&load_order, entry);
818 free(order->resource);
821 case AST_MODULE_LOAD_FAILURE:
824 case AST_MODULE_LOAD_SKIP:
825 /* should not happen */
829 AST_LIST_TRAVERSE_SAFE_END;
832 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
833 free(order->resource);
840 void ast_update_use_count(void)
842 /* Notify any module monitors that the use count for a
843 resource has changed */
844 struct loadupdate *m;
846 AST_LIST_LOCK(&module_list);
847 AST_LIST_TRAVERSE(&updaters, m, entry)
849 AST_LIST_UNLOCK(&module_list);
852 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
855 struct ast_module *cur;
857 int total_mod_loaded = 0;
859 if (AST_LIST_TRYLOCK(&module_list))
862 AST_LIST_TRAVERSE(&module_list, cur, entry) {
863 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
867 AST_LIST_UNLOCK(&module_list);
869 return total_mod_loaded;
872 int ast_loader_register(int (*v)(void))
874 struct loadupdate *tmp;
876 if (!(tmp = ast_malloc(sizeof(*tmp))))
880 AST_LIST_LOCK(&module_list);
881 AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
882 AST_LIST_UNLOCK(&module_list);
887 int ast_loader_unregister(int (*v)(void))
889 struct loadupdate *cur;
891 AST_LIST_LOCK(&module_list);
892 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
893 if (cur->updater == v) {
894 AST_LIST_REMOVE_CURRENT(&updaters, entry);
898 AST_LIST_TRAVERSE_SAFE_END;
899 AST_LIST_UNLOCK(&module_list);
904 struct ast_module *ast_module_ref(struct ast_module *mod)
906 ast_atomic_fetchadd_int(&mod->usecount, +1);
907 ast_update_use_count();
912 void ast_module_unref(struct ast_module *mod)
914 ast_atomic_fetchadd_int(&mod->usecount, -1);
915 ast_update_use_count();