5d644ed6bc9dfb9f0644e1686ae73d0301a6981f
[asterisk/asterisk.git] / main / loader.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  * Kevin P. Fleming <kpfleming@digium.com>
8  * Luigi Rizzo <rizzo@icir.org>
9  *
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.
15  *
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.
19  */
20
21 /*! \file
22  *
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>
27  * - See ModMngMnt
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37
38 #include "asterisk/_private.h"
39 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
40 #include <dirent.h>
41
42 #include "asterisk/dlinkedlists.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_config.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"
59 #include "asterisk/sounds_index.h"
60
61 #include <dlfcn.h>
62
63 #include "asterisk/md5.h"
64 #include "asterisk/utils.h"
65
66 /*** DOCUMENTATION
67         <managerEvent language="en_US" name="Reload">
68                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
69                         <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
70                         <syntax>
71                                 <parameter name="Module">
72                                         <para>The name of the module that was reloaded, or
73                                         <literal>All</literal> if all modules were reloaded</para>
74                                 </parameter>
75                                 <parameter name="Status">
76                                         <para>The numeric status code denoting the success or failure
77                                         of the reload request.</para>
78                                         <enumlist>
79                                                 <enum name="0"><para>Success</para></enum>
80                                                 <enum name="1"><para>Request queued</para></enum>
81                                                 <enum name="2"><para>Module not found</para></enum>
82                                                 <enum name="3"><para>Error</para></enum>
83                                                 <enum name="4"><para>Reload already in progress</para></enum>
84                                                 <enum name="5"><para>Module uninitialized</para></enum>
85                                                 <enum name="6"><para>Reload not supported</para></enum>
86                                         </enumlist>
87                                 </parameter>
88                         </syntax>
89                 </managerEventInstance>
90         </managerEvent>
91  ***/
92
93 #ifndef RTLD_NOW
94 #define RTLD_NOW 0
95 #endif
96
97 #ifndef RTLD_LOCAL
98 #define RTLD_LOCAL 0
99 #endif
100
101 struct ast_module_user {
102         struct ast_channel *chan;
103         AST_LIST_ENTRY(ast_module_user) entry;
104 };
105
106 AST_DLLIST_HEAD(module_user_list, ast_module_user);
107
108 static const unsigned char expected_key[] =
109 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
110   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
111
112 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
113
114 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
115                                       since they are here before we dlopen() any
116                                    */
117
118 struct ast_module {
119         const struct ast_module_info *info;
120 #ifdef REF_DEBUG
121         /* Used to get module references into REF_DEBUG logs */
122         void *ref_debug;
123 #endif
124         void *lib;                                      /* the shared lib, or NULL if embedded */
125         int usecount;                                   /* the number of 'users' currently in this module */
126         struct module_user_list users;                  /* the list of users in the module */
127         struct {
128                 unsigned int running:1;
129                 unsigned int declined:1;
130                 unsigned int keepuntilshutdown:1;
131         } flags;
132         AST_LIST_ENTRY(ast_module) list_entry;
133         AST_DLLIST_ENTRY(ast_module) entry;
134         char resource[0];
135 };
136
137 static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
138
139 const char *ast_module_name(const struct ast_module *mod)
140 {
141         if (!mod || !mod->info) {
142                 return NULL;
143         }
144
145         return mod->info->name;
146 }
147
148 /*
149  * module_list is cleared by its constructor possibly after
150  * we start accumulating embedded modules, so we need to
151  * use another list (without the lock) to accumulate them.
152  * Then we update the main list when embedding is done.
153  */
154 static struct module_list embedded_module_list;
155
156 struct loadupdate {
157         int (*updater)(void);
158         AST_LIST_ENTRY(loadupdate) entry;
159 };
160
161 static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
162
163 AST_MUTEX_DEFINE_STATIC(reloadlock);
164
165 struct reload_queue_item {
166         AST_LIST_ENTRY(reload_queue_item) entry;
167         char module[0];
168 };
169
170 static int do_full_reload = 0;
171
172 static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
173
174 /* when dynamic modules are being loaded, ast_module_register() will
175    need to know what filename the module was loaded from while it
176    is being registered
177 */
178 static struct ast_module *resource_being_loaded;
179
180 /* XXX: should we check for duplicate resource names here? */
181
182 void ast_module_register(const struct ast_module_info *info)
183 {
184         struct ast_module *mod;
185
186         if (embedding) {
187                 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
188                         return;
189                 strcpy(mod->resource, info->name);
190         } else {
191                 mod = resource_being_loaded;
192         }
193
194         ast_debug(5, "Registering module %s\n", info->name);
195
196         mod->info = info;
197 #ifdef REF_DEBUG
198         mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
199 #endif
200         AST_LIST_HEAD_INIT(&mod->users);
201
202         /* during startup, before the loader has been initialized,
203            there are no threads, so there is no need to take the lock
204            on this list to manipulate it. it is also possible that it
205            might be unsafe to use the list lock at that point... so
206            let's avoid it altogether
207         */
208         if (embedding) {
209                 AST_DLLIST_INSERT_TAIL(&embedded_module_list, mod, entry);
210         } else {
211                 AST_DLLIST_LOCK(&module_list);
212                 /* it is paramount that the new entry be placed at the tail of
213                    the list, otherwise the code that uses dlopen() to load
214                    dynamic modules won't be able to find out if the module it
215                    just opened was registered or failed to load
216                 */
217                 AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
218                 AST_DLLIST_UNLOCK(&module_list);
219         }
220
221         /* give the module a copy of its own handle, for later use in registrations and the like */
222         *((struct ast_module **) &(info->self)) = mod;
223 }
224
225 void ast_module_unregister(const struct ast_module_info *info)
226 {
227         struct ast_module *mod = NULL;
228
229         /* it is assumed that the users list in the module structure
230            will already be empty, or we cannot have gotten to this
231            point
232         */
233         AST_DLLIST_LOCK(&module_list);
234         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
235                 if (mod->info == info) {
236                         AST_DLLIST_REMOVE_CURRENT(entry);
237                         break;
238                 }
239         }
240         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
241         AST_DLLIST_UNLOCK(&module_list);
242
243         if (mod) {
244                 ast_debug(5, "Unregistering module %s\n", info->name);
245                 AST_LIST_HEAD_DESTROY(&mod->users);
246 #ifdef REF_DEBUG
247                 ao2_cleanup(mod->ref_debug);
248 #endif
249                 ast_free(mod);
250         }
251 }
252
253 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
254 {
255         struct ast_module_user *u;
256
257         u = ast_calloc(1, sizeof(*u));
258         if (!u) {
259                 return NULL;
260         }
261
262         u->chan = chan;
263
264         AST_LIST_LOCK(&mod->users);
265         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
266         AST_LIST_UNLOCK(&mod->users);
267
268 #ifdef REF_DEBUG
269         ao2_ref(mod->ref_debug, +1);
270 #endif
271
272         ast_atomic_fetchadd_int(&mod->usecount, +1);
273
274         ast_update_use_count();
275
276         return u;
277 }
278
279 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
280 {
281         if (!u) {
282                 return;
283         }
284
285         AST_LIST_LOCK(&mod->users);
286         u = AST_LIST_REMOVE(&mod->users, u, entry);
287         AST_LIST_UNLOCK(&mod->users);
288         if (!u) {
289                 /*
290                  * Was not in the list.  Either a bad pointer or
291                  * __ast_module_user_hangup_all() has been called.
292                  */
293                 return;
294         }
295
296 #ifdef REF_DEBUG
297         ao2_ref(mod->ref_debug, -1);
298 #endif
299
300         ast_atomic_fetchadd_int(&mod->usecount, -1);
301         ast_free(u);
302
303         ast_update_use_count();
304 }
305
306 void __ast_module_user_hangup_all(struct ast_module *mod)
307 {
308         struct ast_module_user *u;
309
310         AST_LIST_LOCK(&mod->users);
311         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
312                 if (u->chan) {
313                         ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
314                 }
315
316 #ifdef REF_DEBUG
317                 ao2_ref(mod->ref_debug, -1);
318 #endif
319
320                 ast_atomic_fetchadd_int(&mod->usecount, -1);
321                 ast_free(u);
322         }
323         AST_LIST_UNLOCK(&mod->users);
324
325         ast_update_use_count();
326 }
327
328 /*! \note
329  * In addition to modules, the reload command handles some extra keywords
330  * which are listed here together with the corresponding handlers.
331  * This table is also used by the command completion code.
332  */
333 static struct reload_classes {
334         const char *name;
335         int (*reload_fn)(void);
336 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
337         { "acl",         ast_named_acl_reload },
338         { "cdr",         ast_cdr_engine_reload },
339         { "cel",         ast_cel_engine_reload },
340         { "dnsmgr",      dnsmgr_reload },
341         { "dsp",         ast_dsp_reload},
342         { "extconfig",   read_config_maps },
343         { "enum",        ast_enum_reload },
344         { "features",    ast_features_config_reload },
345         { "http",        ast_http_reload },
346         { "indications", ast_indications_reload },
347         { "logger",      logger_reload },
348         { "manager",     reload_manager },
349         { "plc",         ast_plc_reload },
350         { "sounds",      ast_sounds_reindex },
351         { "udptl",       ast_udptl_reload },
352         { NULL,          NULL }
353 };
354
355 static int printdigest(const unsigned char *d)
356 {
357         int x, pos;
358         char buf[256]; /* large enough so we don't have to worry */
359
360         for (pos = 0, x = 0; x < 16; x++)
361                 pos += sprintf(buf + pos, " %02hhx", *d++);
362
363         ast_debug(1, "Unexpected signature:%s\n", buf);
364
365         return 0;
366 }
367
368 static int key_matches(const unsigned char *key1, const unsigned char *key2)
369 {
370         int x;
371
372         for (x = 0; x < 16; x++) {
373                 if (key1[x] != key2[x])
374                         return 0;
375         }
376
377         return 1;
378 }
379
380 static int verify_key(const unsigned char *key)
381 {
382         struct MD5Context c;
383         unsigned char digest[16];
384
385         MD5Init(&c);
386         MD5Update(&c, key, strlen((char *)key));
387         MD5Final(digest, &c);
388
389         if (key_matches(expected_key, digest))
390                 return 0;
391
392         printdigest(digest);
393
394         return -1;
395 }
396
397 static int resource_name_match(const char *name1_in, const char *name2_in)
398 {
399         char *name1 = (char *) name1_in;
400         char *name2 = (char *) name2_in;
401
402         /* trim off any .so extensions */
403         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
404                 name1 = ast_strdupa(name1);
405                 name1[strlen(name1) - 3] = '\0';
406         }
407         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
408                 name2 = ast_strdupa(name2);
409                 name2[strlen(name2) - 3] = '\0';
410         }
411
412         return strcasecmp(name1, name2);
413 }
414
415 static struct ast_module *find_resource(const char *resource, int do_lock)
416 {
417         struct ast_module *cur;
418
419         if (do_lock) {
420                 AST_DLLIST_LOCK(&module_list);
421         }
422
423         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
424                 if (!resource_name_match(resource, cur->resource))
425                         break;
426         }
427
428         if (do_lock) {
429                 AST_DLLIST_UNLOCK(&module_list);
430         }
431
432         return cur;
433 }
434
435 #ifdef LOADABLE_MODULES
436
437 /*!
438  * \brief dlclose(), with failure logging.
439  */
440 static void logged_dlclose(const char *name, void *lib)
441 {
442         char *error;
443
444         if (!lib) {
445                 return;
446         }
447
448         /* Clear any existing error */
449         dlerror();
450         if (dlclose(lib)) {
451                 error = dlerror();
452                 ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
453                         S_OR(name, "unknown"), S_OR(error, "Unknown error"));
454         }
455 }
456
457 #if defined(HAVE_RTLD_NOLOAD)
458 /*!
459  * \brief Check to see if the given resource is loaded.
460  *
461  * \param resource_name Name of the resource, including .so suffix.
462  * \return False (0) if module is not loaded.
463  * \return True (non-zero) if module is loaded.
464  */
465 static int is_module_loaded(const char *resource_name)
466 {
467         char fn[PATH_MAX] = "";
468         void *lib;
469
470         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
471                 resource_name);
472
473         lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
474
475         if (lib) {
476                 logged_dlclose(resource_name, lib);
477                 return 1;
478         }
479
480         return 0;
481 }
482 #endif
483
484 static void unload_dynamic_module(struct ast_module *mod)
485 {
486         char *name = ast_strdupa(ast_module_name(mod));
487         void *lib = mod->lib;
488
489         /* WARNING: the structure pointed to by mod is going to
490            disappear when this operation succeeds, so we can't
491            dereference it */
492         logged_dlclose(ast_module_name(mod), lib);
493
494         /* There are several situations where the module might still be resident
495          * in memory.
496          *
497          * If somehow there was another dlopen() on the same module (unlikely,
498          * since that all is supposed to happen in loader.c).
499          *
500          * Or the lazy resolution of a global symbol (very likely, since that is
501          * how we load all of our modules that export global symbols).
502          *
503          * Avoid the temptation of repeating the dlclose(). The other code that
504          * dlopened the module still has its module reference, and should close
505          * it itself. In other situations, dlclose() will happily return success
506          * for as many times as you wish to call it.
507          */
508 #if defined(HAVE_RTLD_NOLOAD)
509         if (is_module_loaded(name)) {
510                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
511         }
512 #endif
513 }
514
515 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required);
516
517 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, struct ast_heap *resource_heap)
518 {
519         char fn[PATH_MAX] = "";
520         void *lib = NULL;
521         struct ast_module *mod;
522         unsigned int wants_global;
523         int space;      /* room needed for the descriptor */
524         int missing_so = 0;
525
526         space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
527         if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
528                 missing_so = 1;
529                 space += 3;     /* room for the extra ".so" */
530         }
531
532         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
533
534         /* make a first load of the module in 'quiet' mode... don't try to resolve
535            any symbols, and don't export any symbols. this will allow us to peek into
536            the module's info block (if available) to see what flags it has set */
537
538         resource_being_loaded = ast_calloc(1, space);
539         if (!resource_being_loaded)
540                 return NULL;
541         strcpy(resource_being_loaded->resource, resource_in);
542         if (missing_so)
543                 strcat(resource_being_loaded->resource, ".so");
544
545         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
546                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
547                 ast_free(resource_being_loaded);
548                 return NULL;
549         }
550
551         /* the dlopen() succeeded, let's find out if the module
552            registered itself */
553         /* note that this will only work properly as long as
554            ast_module_register() (which is called by the module's
555            constructor) places the new module at the tail of the
556            module_list
557         */
558         if (resource_being_loaded != (mod = AST_DLLIST_LAST(&module_list))) {
559                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
560                 /* no, it did not, so close it and return */
561                 logged_dlclose(resource_in, lib);
562                 /* note that the module's destructor will call ast_module_unregister(),
563                    which will free the structure we allocated in resource_being_loaded */
564                 return NULL;
565         }
566
567         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
568
569         /* if we are being asked only to load modules that provide global symbols,
570            and this one does not, then close it and return */
571         if (global_symbols_only && !wants_global) {
572                 logged_dlclose(resource_in, lib);
573                 return NULL;
574         }
575
576         logged_dlclose(resource_in, lib);
577         resource_being_loaded = NULL;
578
579         /* start the load process again */
580         resource_being_loaded = ast_calloc(1, space);
581         if (!resource_being_loaded)
582                 return NULL;
583         strcpy(resource_being_loaded->resource, resource_in);
584         if (missing_so)
585                 strcat(resource_being_loaded->resource, ".so");
586
587         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
588                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
589                 ast_free(resource_being_loaded);
590                 return NULL;
591         }
592
593         /* since the module was successfully opened, and it registered itself
594            the previous time we did that, we're going to assume it worked this
595            time too :) */
596
597         AST_DLLIST_LAST(&module_list)->lib = lib;
598         resource_being_loaded = NULL;
599
600         return AST_DLLIST_LAST(&module_list);
601 }
602
603 #endif
604
605 void ast_module_shutdown(void)
606 {
607         struct ast_module *mod;
608         int somethingchanged = 1, final = 0;
609
610         AST_DLLIST_LOCK(&module_list);
611
612         /*!\note Some resources, like timers, are started up dynamically, and thus
613          * may be still in use, even if all channels are dead.  We must therefore
614          * check the usecount before asking modules to unload. */
615         do {
616                 if (!somethingchanged) {
617                         /*!\note If we go through the entire list without changing
618                          * anything, ignore the usecounts and unload, then exit. */
619                         final = 1;
620                 }
621
622                 /* Reset flag before traversing the list */
623                 somethingchanged = 0;
624
625                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
626                         if (!final && mod->usecount) {
627                                 ast_debug(1, "Passing on %s: its use count is %d\n",
628                                         mod->resource, mod->usecount);
629                                 continue;
630                         }
631                         AST_DLLIST_REMOVE_CURRENT(entry);
632                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
633                                 ast_verb(1, "Unloading %s\n", mod->resource);
634                                 mod->info->unload();
635                         }
636                         AST_LIST_HEAD_DESTROY(&mod->users);
637 #ifdef REF_DEBUG
638                         ao2_cleanup(mod->ref_debug);
639 #endif
640                         ast_free(mod);
641                         somethingchanged = 1;
642                 }
643                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
644                 if (!somethingchanged) {
645                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
646                                 if (mod->flags.keepuntilshutdown) {
647                                         ast_module_unref(mod);
648                                         mod->flags.keepuntilshutdown = 0;
649                                         somethingchanged = 1;
650                                 }
651                         }
652                 }
653         } while (somethingchanged && !final);
654
655         AST_DLLIST_UNLOCK(&module_list);
656 }
657
658 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
659 {
660         struct ast_module *mod;
661         int res = -1;
662         int error = 0;
663
664         AST_DLLIST_LOCK(&module_list);
665
666         if (!(mod = find_resource(resource_name, 0))) {
667                 AST_DLLIST_UNLOCK(&module_list);
668                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
669                 return -1;
670         }
671
672         if (!mod->flags.running || mod->flags.declined) {
673                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
674                 error = 1;
675         }
676
677         if (!error && (mod->usecount > 0)) {
678                 if (force)
679                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
680                                 resource_name, mod->usecount);
681                 else {
682                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
683                                 mod->usecount);
684                         error = 1;
685                 }
686         }
687
688         if (!error) {
689                 /* Request any channels attached to the module to hangup. */
690                 __ast_module_user_hangup_all(mod);
691
692                 ast_verb(1, "Unloading %s\n", mod->resource);
693                 res = mod->info->unload();
694                 if (res) {
695                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
696                         if (force <= AST_FORCE_FIRM) {
697                                 error = 1;
698                         } else {
699                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
700                         }
701                 }
702
703                 if (!error) {
704                         /*
705                          * Request hangup on any channels that managed to get attached
706                          * while we called the module unload function.
707                          */
708                         __ast_module_user_hangup_all(mod);
709                         sched_yield();
710                 }
711         }
712
713         if (!error)
714                 mod->flags.running = mod->flags.declined = 0;
715
716         AST_DLLIST_UNLOCK(&module_list);
717
718         if (!error && !mod->lib && mod->info && mod->info->restore_globals)
719                 mod->info->restore_globals();
720
721 #ifdef LOADABLE_MODULES
722         if (!error) {
723                 unload_dynamic_module(mod);
724                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
725         }
726 #endif
727
728         if (!error)
729                 ast_update_use_count();
730
731         return res;
732 }
733
734 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
735 {
736         struct ast_module *cur;
737         int i, which=0, l = strlen(word);
738         char *ret = NULL;
739
740         if (pos != rpos)
741                 return NULL;
742
743         AST_DLLIST_LOCK(&module_list);
744         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
745                 if (!strncasecmp(word, cur->resource, l) &&
746                     (cur->info->reload || !needsreload) &&
747                     ++which > state) {
748                         ret = ast_strdup(cur->resource);
749                         break;
750                 }
751         }
752         AST_DLLIST_UNLOCK(&module_list);
753
754         if (!ret) {
755                 for (i=0; !ret && reload_classes[i].name; i++) {
756                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
757                                 ret = ast_strdup(reload_classes[i].name);
758                 }
759         }
760
761         return ret;
762 }
763
764 void ast_process_pending_reloads(void)
765 {
766         struct reload_queue_item *item;
767
768         if (!ast_fully_booted) {
769                 return;
770         }
771
772         AST_LIST_LOCK(&reload_queue);
773
774         if (do_full_reload) {
775                 do_full_reload = 0;
776                 AST_LIST_UNLOCK(&reload_queue);
777                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
778                 ast_module_reload(NULL);
779                 return;
780         }
781
782         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
783                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
784                 ast_module_reload(item->module);
785                 ast_free(item);
786         }
787
788         AST_LIST_UNLOCK(&reload_queue);
789 }
790
791 static void queue_reload_request(const char *module)
792 {
793         struct reload_queue_item *item;
794
795         AST_LIST_LOCK(&reload_queue);
796
797         if (do_full_reload) {
798                 AST_LIST_UNLOCK(&reload_queue);
799                 return;
800         }
801
802         if (ast_strlen_zero(module)) {
803                 /* A full reload request (when module is NULL) wipes out any previous
804                    reload requests and causes the queue to ignore future ones */
805                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
806                         ast_free(item);
807                 }
808                 do_full_reload = 1;
809         } else {
810                 /* No reason to add the same module twice */
811                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
812                         if (!strcasecmp(item->module, module)) {
813                                 AST_LIST_UNLOCK(&reload_queue);
814                                 return;
815                         }
816                 }
817                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
818                 if (!item) {
819                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
820                         AST_LIST_UNLOCK(&reload_queue);
821                         return;
822                 }
823                 strcpy(item->module, module);
824                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
825         }
826         AST_LIST_UNLOCK(&reload_queue);
827 }
828
829 /*!
830  * \since 12
831  * \internal
832  * \brief Publish a \ref stasis message regarding the reload result
833  */
834 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
835 {
836         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
837         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
838         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
839         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
840         char res_buffer[8];
841
842         if (!ast_manager_get_generic_type()) {
843                 return;
844         }
845
846         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
847         event_object = ast_json_pack("{s: s, s: s}",
848                         "Module", S_OR(name, "All"),
849                         "Status", res_buffer);
850         json_object = ast_json_pack("{s: s, s: i, s: O}",
851                         "type", "Reload",
852                         "class_type", EVENT_FLAG_SYSTEM,
853                         "event", event_object);
854
855         if (!json_object) {
856                 return;
857         }
858
859         payload = ast_json_payload_create(json_object);
860         if (!payload) {
861                 return;
862         }
863
864         message = stasis_message_create(ast_manager_get_generic_type(), payload);
865         if (!message) {
866                 return;
867         }
868
869         stasis_publish(ast_manager_get_topic(), message);
870 }
871
872 enum ast_module_reload_result ast_module_reload(const char *name)
873 {
874         struct ast_module *cur;
875         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
876         int i;
877
878         /* If we aren't fully booted, we just pretend we reloaded but we queue this
879            up to run once we are booted up. */
880         if (!ast_fully_booted) {
881                 queue_reload_request(name);
882                 res = AST_MODULE_RELOAD_QUEUED;
883                 goto module_reload_exit;
884         }
885
886         if (ast_mutex_trylock(&reloadlock)) {
887                 ast_verb(3, "The previous reload command didn't finish yet\n");
888                 res = AST_MODULE_RELOAD_IN_PROGRESS;
889                 goto module_reload_exit;
890         }
891         ast_lastreloadtime = ast_tvnow();
892
893         if (ast_opt_lock_confdir) {
894                 int try;
895                 int res;
896                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
897                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
898                         if (res == AST_LOCK_TIMEOUT) {
899                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
900                         }
901                 }
902                 if (res != AST_LOCK_SUCCESS) {
903                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
904                         ast_mutex_unlock(&reloadlock);
905                         res = AST_MODULE_RELOAD_ERROR;
906                         goto module_reload_exit;
907                 }
908         }
909
910         /* Call "predefined" reload here first */
911         for (i = 0; reload_classes[i].name; i++) {
912                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
913                         if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
914                                 res = AST_MODULE_RELOAD_SUCCESS;
915                         }
916                 }
917         }
918
919         if (name && res == AST_MODULE_RELOAD_SUCCESS) {
920                 if (ast_opt_lock_confdir) {
921                         ast_unlock_path(ast_config_AST_CONFIG_DIR);
922                 }
923                 ast_mutex_unlock(&reloadlock);
924                 goto module_reload_exit;
925         }
926
927         AST_DLLIST_LOCK(&module_list);
928         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
929                 const struct ast_module_info *info = cur->info;
930
931                 if (name && resource_name_match(name, cur->resource))
932                         continue;
933
934                 if (!cur->flags.running || cur->flags.declined) {
935                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
936                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
937                         }
938                         if (!name) {
939                                 continue;
940                         }
941                         break;
942                 }
943
944                 if (!info->reload) {    /* cannot be reloaded */
945                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
946                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
947                         }
948                         if (!name) {
949                                 continue;
950                         }
951                         break;
952                 }
953                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
954                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
955                         res = AST_MODULE_RELOAD_SUCCESS;
956                 }
957                 if (name) {
958                         break;
959                 }
960         }
961         AST_DLLIST_UNLOCK(&module_list);
962
963         if (ast_opt_lock_confdir) {
964                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
965         }
966         ast_mutex_unlock(&reloadlock);
967
968 module_reload_exit:
969         publish_reload_message(name, res);
970         return res;
971 }
972
973 static unsigned int inspect_module(const struct ast_module *mod)
974 {
975         if (!mod->info->description) {
976                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
977                 return 1;
978         }
979
980         if (!mod->info->key) {
981                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
982                 return 1;
983         }
984
985         if (verify_key((unsigned char *) mod->info->key)) {
986                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
987                 return 1;
988         }
989
990         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
991             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
992                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
993                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
994                 return 1;
995         }
996
997         return 0;
998 }
999
1000 static enum ast_module_load_result start_resource(struct ast_module *mod)
1001 {
1002         char tmp[256];
1003         enum ast_module_load_result res;
1004
1005         if (mod->flags.running) {
1006                 return AST_MODULE_LOAD_SUCCESS;
1007         }
1008
1009         if (!mod->info->load) {
1010                 return AST_MODULE_LOAD_FAILURE;
1011         }
1012
1013         if (!ast_fully_booted) {
1014                 ast_verb(1, "Loading %s.\n", mod->resource);
1015         }
1016         res = mod->info->load();
1017
1018         switch (res) {
1019         case AST_MODULE_LOAD_SUCCESS:
1020                 if (!ast_fully_booted) {
1021                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1022                 } else {
1023                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1024                 }
1025
1026                 mod->flags.running = 1;
1027
1028                 ast_update_use_count();
1029                 break;
1030         case AST_MODULE_LOAD_DECLINE:
1031                 mod->flags.declined = 1;
1032                 break;
1033         case AST_MODULE_LOAD_FAILURE:
1034         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1035         case AST_MODULE_LOAD_PRIORITY:
1036                 break;
1037         }
1038
1039         /* Make sure the newly started module is at the end of the list */
1040         AST_DLLIST_LOCK(&module_list);
1041         AST_DLLIST_REMOVE(&module_list, mod, entry);
1042         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1043         AST_DLLIST_UNLOCK(&module_list);
1044
1045         return res;
1046 }
1047
1048 /*! loads a resource based upon resource_name. If global_symbols_only is set
1049  *  only modules with global symbols will be loaded.
1050  *
1051  *  If the ast_heap is provided (not NULL) the module is found and added to the
1052  *  heap without running the module's load() function.  By doing this, modules
1053  *  added to the resource_heap can be initialized later in order by priority.
1054  *
1055  *  If the ast_heap is not provided, the module's load function will be executed
1056  *  immediately */
1057 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
1058 {
1059         struct ast_module *mod;
1060         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1061
1062         if ((mod = find_resource(resource_name, 0))) {
1063                 if (mod->flags.running) {
1064                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
1065                         return AST_MODULE_LOAD_DECLINE;
1066                 }
1067                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
1068                         return AST_MODULE_LOAD_SKIP;
1069         } else {
1070 #ifdef LOADABLE_MODULES
1071                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only, resource_heap))) {
1072                         /* don't generate a warning message during load_modules() */
1073                         if (!global_symbols_only) {
1074                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1075                                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1076                         } else {
1077                                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
1078                         }
1079                 }
1080 #else
1081                 ast_log(LOG_WARNING, "Module support is not available. Module '%s' could not be loaded.\n", resource_name);
1082                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1083 #endif
1084         }
1085
1086         if (inspect_module(mod)) {
1087                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1088 #ifdef LOADABLE_MODULES
1089                 unload_dynamic_module(mod);
1090 #endif
1091                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1092         }
1093
1094         if (!mod->lib && mod->info->backup_globals && mod->info->backup_globals()) {
1095                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
1096                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1097         }
1098
1099         mod->flags.declined = 0;
1100
1101         if (resource_heap) {
1102                 ast_heap_push(resource_heap, mod);
1103                 res = AST_MODULE_LOAD_PRIORITY;
1104         } else {
1105                 res = start_resource(mod);
1106         }
1107
1108         return res;
1109 }
1110
1111 int ast_load_resource(const char *resource_name)
1112 {
1113         int res;
1114         AST_DLLIST_LOCK(&module_list);
1115         res = load_resource(resource_name, 0, NULL, 0);
1116         if (!res) {
1117                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1118         }
1119         AST_DLLIST_UNLOCK(&module_list);
1120
1121         return res;
1122 }
1123
1124 struct load_order_entry {
1125         char *resource;
1126         int required;
1127         AST_LIST_ENTRY(load_order_entry) entry;
1128 };
1129
1130 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1131
1132 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
1133 {
1134         struct load_order_entry *order;
1135
1136         AST_LIST_TRAVERSE(load_order, order, entry) {
1137                 if (!resource_name_match(order->resource, resource)) {
1138                         /* Make sure we have the proper setting for the required field
1139                            (we might have both load= and required= lines in modules.conf) */
1140                         order->required |= required;
1141                         return NULL;
1142                 }
1143         }
1144
1145         if (!(order = ast_calloc(1, sizeof(*order))))
1146                 return NULL;
1147
1148         order->resource = ast_strdup(resource);
1149         order->required = required;
1150         AST_LIST_INSERT_TAIL(load_order, order, entry);
1151
1152         return order;
1153 }
1154
1155 static int mod_load_cmp(void *a, void *b)
1156 {
1157         struct ast_module *a_mod = (struct ast_module *) a;
1158         struct ast_module *b_mod = (struct ast_module *) b;
1159         /* if load_pri is not set, default is 128.  Lower is better */
1160         int a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
1161         int b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
1162
1163         /*
1164          * Returns comparison values for a min-heap
1165          * <0 a_pri > b_pri
1166          * =0 a_pri == b_pri
1167          * >0 a_pri < b_pri
1168          */
1169         return b_pri - a_pri;
1170 }
1171
1172 /*! loads modules in order by load_pri, updates mod_count
1173         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1174 */
1175 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
1176 {
1177         struct ast_heap *resource_heap;
1178         struct load_order_entry *order;
1179         struct ast_module *mod;
1180         int count = 0;
1181         int res = 0;
1182
1183         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
1184                 return -1;
1185         }
1186
1187         /* first, add find and add modules to heap */
1188         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1189                 switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
1190                 case AST_MODULE_LOAD_SUCCESS:
1191                 case AST_MODULE_LOAD_DECLINE:
1192                         AST_LIST_REMOVE_CURRENT(entry);
1193                         ast_free(order->resource);
1194                         ast_free(order);
1195                         break;
1196                 case AST_MODULE_LOAD_FAILURE:
1197                         ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1198                         fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
1199                         res = order->required ? -2 : -1;
1200                         goto done;
1201                 case AST_MODULE_LOAD_SKIP:
1202                         break;
1203                 case AST_MODULE_LOAD_PRIORITY:
1204                         AST_LIST_REMOVE_CURRENT(entry);
1205                         ast_free(order->resource);
1206                         ast_free(order);
1207                         break;
1208                 }
1209         }
1210         AST_LIST_TRAVERSE_SAFE_END;
1211
1212         /* second remove modules from heap sorted by priority */
1213         while ((mod = ast_heap_pop(resource_heap))) {
1214                 switch (start_resource(mod)) {
1215                 case AST_MODULE_LOAD_SUCCESS:
1216                         count++;
1217                 case AST_MODULE_LOAD_DECLINE:
1218                         break;
1219                 case AST_MODULE_LOAD_FAILURE:
1220                         res = -1;
1221                         goto done;
1222                 case AST_MODULE_LOAD_SKIP:
1223                 case AST_MODULE_LOAD_PRIORITY:
1224                         break;
1225                 }
1226         }
1227
1228 done:
1229         if (mod_count) {
1230                 *mod_count += count;
1231         }
1232         ast_heap_destroy(resource_heap);
1233
1234         return res;
1235 }
1236
1237 int load_modules(unsigned int preload_only)
1238 {
1239         struct ast_config *cfg;
1240         struct ast_module *mod;
1241         struct load_order_entry *order;
1242         struct ast_variable *v;
1243         unsigned int load_count;
1244         struct load_order load_order;
1245         int res = 0;
1246         struct ast_flags config_flags = { 0 };
1247         int modulecount = 0;
1248
1249 #ifdef LOADABLE_MODULES
1250         struct dirent *dirent;
1251         DIR *dir;
1252 #endif
1253
1254         /* all embedded modules have registered themselves by now */
1255         embedding = 0;
1256
1257         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1258
1259         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1260
1261         AST_DLLIST_LOCK(&module_list);
1262
1263         if (embedded_module_list.first) {
1264                 module_list.first = embedded_module_list.first;
1265                 module_list.last = embedded_module_list.last;
1266                 embedded_module_list.first = NULL;
1267         }
1268
1269         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1270         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1271                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1272                 goto done;
1273         }
1274
1275         /* first, find all the modules we have been explicitly requested to load */
1276         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1277                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1278                         add_to_load_order(v->value, &load_order, 0);
1279                 }
1280                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1281                         /* Add the module to the list and make sure it's required */
1282                         add_to_load_order(v->value, &load_order, 1);
1283                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1284                 }
1285
1286         }
1287
1288         /* check if 'autoload' is on */
1289         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1290                 /* if so, first add all the embedded modules that are not already running to the load order */
1291                 AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1292                         /* if it's not embedded, skip it */
1293                         if (mod->lib)
1294                                 continue;
1295
1296                         if (mod->flags.running)
1297                                 continue;
1298
1299                         add_to_load_order(mod->resource, &load_order, 0);
1300                 }
1301
1302 #ifdef LOADABLE_MODULES
1303                 /* if we are allowed to load dynamic modules, scan the directory for
1304                    for all available modules and add them as well */
1305                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1306                         while ((dirent = readdir(dir))) {
1307                                 int ld = strlen(dirent->d_name);
1308
1309                                 /* Must end in .so to load it.  */
1310
1311                                 if (ld < 4)
1312                                         continue;
1313
1314                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1315                                         continue;
1316
1317                                 /* if there is already a module by this name in the module_list,
1318                                    skip this file */
1319                                 if (find_resource(dirent->d_name, 0))
1320                                         continue;
1321
1322                                 add_to_load_order(dirent->d_name, &load_order, 0);
1323                         }
1324
1325                         closedir(dir);
1326                 } else {
1327                         if (!ast_opt_quiet)
1328                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1329                                         ast_config_AST_MODULE_DIR);
1330                 }
1331 #endif
1332         }
1333
1334         /* now scan the config for any modules we are prohibited from loading and
1335            remove them from the load order */
1336         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1337                 if (strcasecmp(v->name, "noload"))
1338                         continue;
1339
1340                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1341                         if (!resource_name_match(order->resource, v->value)) {
1342                                 AST_LIST_REMOVE_CURRENT(entry);
1343                                 ast_free(order->resource);
1344                                 ast_free(order);
1345                         }
1346                 }
1347                 AST_LIST_TRAVERSE_SAFE_END;
1348         }
1349
1350         /* we are done with the config now, all the information we need is in the
1351            load_order list */
1352         ast_config_destroy(cfg);
1353
1354         load_count = 0;
1355         AST_LIST_TRAVERSE(&load_order, order, entry)
1356                 load_count++;
1357
1358         if (load_count)
1359                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1360
1361         /* first, load only modules that provide global symbols */
1362         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1363                 goto done;
1364         }
1365
1366         /* now load everything else */
1367         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1368                 goto done;
1369         }
1370
1371 done:
1372         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1373                 ast_free(order->resource);
1374                 ast_free(order);
1375         }
1376
1377         AST_DLLIST_UNLOCK(&module_list);
1378         return res;
1379 }
1380
1381 void ast_update_use_count(void)
1382 {
1383         /* Notify any module monitors that the use count for a
1384            resource has changed */
1385         struct loadupdate *m;
1386
1387         AST_LIST_LOCK(&updaters);
1388         AST_LIST_TRAVERSE(&updaters, m, entry)
1389                 m->updater();
1390         AST_LIST_UNLOCK(&updaters);
1391 }
1392
1393 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1394                                            int usecnt, const char *status, const char *like,
1395                                                                                    enum ast_module_support_level support_level),
1396                            const char *like)
1397 {
1398         struct ast_module *cur;
1399         int unlock = -1;
1400         int total_mod_loaded = 0;
1401         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1402
1403         if (AST_DLLIST_TRYLOCK(&module_list)) {
1404                 unlock = 0;
1405         }
1406
1407         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1408                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1409         }
1410
1411         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1412                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1413                                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1414         }
1415
1416         if (unlock) {
1417                 AST_DLLIST_UNLOCK(&module_list);
1418         }
1419
1420         return total_mod_loaded;
1421 }
1422
1423 /*! \brief Check if module exists */
1424 int ast_module_check(const char *name)
1425 {
1426         struct ast_module *cur;
1427
1428         if (ast_strlen_zero(name))
1429                 return 0;       /* FALSE */
1430
1431         cur = find_resource(name, 1);
1432
1433         return (cur != NULL);
1434 }
1435
1436
1437 int ast_loader_register(int (*v)(void))
1438 {
1439         struct loadupdate *tmp;
1440
1441         if (!(tmp = ast_malloc(sizeof(*tmp))))
1442                 return -1;
1443
1444         tmp->updater = v;
1445         AST_LIST_LOCK(&updaters);
1446         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1447         AST_LIST_UNLOCK(&updaters);
1448
1449         return 0;
1450 }
1451
1452 int ast_loader_unregister(int (*v)(void))
1453 {
1454         struct loadupdate *cur;
1455
1456         AST_LIST_LOCK(&updaters);
1457         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1458                 if (cur->updater == v)  {
1459                         AST_LIST_REMOVE_CURRENT(entry);
1460                         break;
1461                 }
1462         }
1463         AST_LIST_TRAVERSE_SAFE_END;
1464         AST_LIST_UNLOCK(&updaters);
1465
1466         return cur ? 0 : -1;
1467 }
1468
1469 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
1470 {
1471         if (!mod) {
1472                 return NULL;
1473         }
1474
1475 #ifdef REF_DEBUG
1476         __ao2_ref_debug(mod->ref_debug, +1, "", file, line, func);
1477 #endif
1478
1479         ast_atomic_fetchadd_int(&mod->usecount, +1);
1480         ast_update_use_count();
1481
1482         return mod;
1483 }
1484
1485 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
1486 {
1487         if (!mod->flags.keepuntilshutdown) {
1488                 __ast_module_ref(mod, file, line, func);
1489                 mod->flags.keepuntilshutdown = 1;
1490         }
1491 }
1492
1493 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
1494 {
1495         if (!mod) {
1496                 return;
1497         }
1498
1499 #ifdef REF_DEBUG
1500         __ao2_ref_debug(mod->ref_debug, -1, "", file, line, func);
1501 #endif
1502
1503         ast_atomic_fetchadd_int(&mod->usecount, -1);
1504         ast_update_use_count();
1505 }
1506
1507 const char *support_level_map [] = {
1508         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
1509         [AST_MODULE_SUPPORT_CORE] = "core",
1510         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
1511         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
1512 };
1513
1514 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
1515 {
1516         return support_level_map[support_level];
1517 }