Merge "loader: Remove global symbol only startup phase."
[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 #include "asterisk/_private.h"
37 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
38 #include <dirent.h>
39 #include <editline/readline.h>
40
41 #include "asterisk/dlinkedlists.h"
42 #include "asterisk/module.h"
43 #include "asterisk/config.h"
44 #include "asterisk/channel.h"
45 #include "asterisk/term.h"
46 #include "asterisk/acl.h"
47 #include "asterisk/manager.h"
48 #include "asterisk/cdr.h"
49 #include "asterisk/enum.h"
50 #include "asterisk/http.h"
51 #include "asterisk/lock.h"
52 #include "asterisk/features_config.h"
53 #include "asterisk/dsp.h"
54 #include "asterisk/udptl.h"
55 #include "asterisk/vector.h"
56 #include "asterisk/app.h"
57 #include "asterisk/test.h"
58 #include "asterisk/sounds_index.h"
59
60 #include <dlfcn.h>
61
62 #include "asterisk/md5.h"
63 #include "asterisk/utils.h"
64
65 /*** DOCUMENTATION
66         <managerEvent language="en_US" name="Reload">
67                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
68                         <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
69                         <syntax>
70                                 <parameter name="Module">
71                                         <para>The name of the module that was reloaded, or
72                                         <literal>All</literal> if all modules were reloaded</para>
73                                 </parameter>
74                                 <parameter name="Status">
75                                         <para>The numeric status code denoting the success or failure
76                                         of the reload request.</para>
77                                         <enumlist>
78                                                 <enum name="0"><para>Success</para></enum>
79                                                 <enum name="1"><para>Request queued</para></enum>
80                                                 <enum name="2"><para>Module not found</para></enum>
81                                                 <enum name="3"><para>Error</para></enum>
82                                                 <enum name="4"><para>Reload already in progress</para></enum>
83                                                 <enum name="5"><para>Module uninitialized</para></enum>
84                                                 <enum name="6"><para>Reload not supported</para></enum>
85                                         </enumlist>
86                                 </parameter>
87                         </syntax>
88                 </managerEventInstance>
89         </managerEvent>
90  ***/
91
92 #ifndef RTLD_NOW
93 #define RTLD_NOW 0
94 #endif
95
96 #ifndef RTLD_LOCAL
97 #define RTLD_LOCAL 0
98 #endif
99
100 struct ast_module_user {
101         struct ast_channel *chan;
102         AST_LIST_ENTRY(ast_module_user) entry;
103 };
104
105 AST_DLLIST_HEAD(module_user_list, ast_module_user);
106
107 static const unsigned char expected_key[] =
108 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
109   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
110
111 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
112
113 AST_VECTOR(module_vector, struct ast_module *);
114
115 /*!
116  * \brief Internal flag to indicate all modules have been initially loaded.
117  */
118 static int modules_loaded;
119
120 struct ast_module {
121         const struct ast_module_info *info;
122         /*! Used to get module references into refs log */
123         void *ref_debug;
124         /*! The shared lib. */
125         void *lib;
126         /*! Number of 'users' and other references currently holding the module. */
127         int usecount;
128         /*! List of users holding the module. */
129         struct module_user_list users;
130
131         /*! List of required module names. */
132         struct ast_vector_string requires;
133         /*! List of optional api modules. */
134         struct ast_vector_string optional_modules;
135         /*! List of modules this enhances. */
136         struct ast_vector_string enhances;
137
138         /*!
139          * \brief Vector holding pointers to modules we have a reference to.
140          *
141          * When one module requires another, the required module gets added
142          * to this list with a reference.
143          */
144         struct module_vector reffed_deps;
145         struct {
146                 /*! The module running and ready to accept requests. */
147                 unsigned int running:1;
148                 /*! The module has declined to start. */
149                 unsigned int declined:1;
150                 /*! This module is being held open until it's time to shutdown. */
151                 unsigned int keepuntilshutdown:1;
152         } flags;
153         AST_DLLIST_ENTRY(ast_module) entry;
154         char resource[0];
155 };
156
157 static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
158
159 static int module_vector_strcasecmp(struct ast_module *a, struct ast_module *b)
160 {
161         return strcasecmp(a->resource, b->resource);
162 }
163
164 static int module_vector_cmp(struct ast_module *a, struct ast_module *b)
165 {
166         /* if load_pri is not set, default is 128.  Lower is better */
167         int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)
168                 ? a->info->load_pri : AST_MODPRI_DEFAULT;
169         int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)
170                 ? b->info->load_pri : AST_MODPRI_DEFAULT;
171
172         /*
173          * Returns comparison values for a vector sorted by priority.
174          * <0 a_pri < b_pri
175          * =0 a_pri == b_pri
176          * >0 a_pri > b_pri
177          */
178         return a_pri - b_pri;
179 }
180
181 static struct ast_module *find_resource(const char *resource, int do_lock);
182
183 /*!
184  * \internal
185  * \brief Add a reference from mod to dep.
186  *
187  * \param mod Owner of the new reference.
188  * \param dep Module to reference
189  * \param missing Vector to store name of \a dep if it is not running.
190  *
191  * This function returns failure if \a dep is not running and \a missing
192  * is NULL.  If \a missing is not NULL errors will only be returned for
193  * allocation failures.
194  *
195  * \retval 0 Success
196  * \retval -1 Failure
197  *
198  * \note Adding a second reference to the same dep will return success
199  *       without doing anything.
200  */
201 static int module_reffed_deps_add(struct ast_module *mod, struct ast_module *dep,
202         struct ast_vector_const_string *missing)
203 {
204         if (!dep->flags.running) {
205                 return !missing ? -1 : AST_VECTOR_APPEND(missing, dep->info->name);
206         }
207
208         if (AST_VECTOR_GET_CMP(&mod->reffed_deps, dep, AST_VECTOR_ELEM_DEFAULT_CMP)) {
209                 /* Skip duplicate. */
210                 return 0;
211         }
212
213         if (AST_VECTOR_APPEND(&mod->reffed_deps, dep)) {
214                 return -1;
215         }
216
217         ast_module_ref(dep);
218
219         return 0;
220 }
221
222 /*!
223  * \internal
224  * \brief Add references for modules that enhance a dependency.
225  *
226  * \param mod Owner of the new references.
227  * \param dep Module to check for enhancers.
228  * \param missing Vector to store name of any enhancer that is not running or declined.
229  *
230  * \retval 0 Success
231  * \retval -1 Failure
232  */
233 static int module_reffed_deps_add_dep_enhancers(struct ast_module *mod,
234         struct ast_module *dep, struct ast_vector_const_string *missing)
235 {
236         struct ast_module *cur;
237
238         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
239                 if (cur->flags.declined) {
240                         continue;
241                 }
242
243                 if (!AST_VECTOR_GET_CMP(&cur->enhances, dep->info->name, !strcasecmp)) {
244                         /* dep is not enhanced by cur. */
245                         continue;
246                 }
247
248                 /* dep is enhanced by cur, therefore mod requires cur. */
249                 if (module_reffed_deps_add(mod, cur, missing)) {
250                         return -1;
251                 }
252         }
253
254         return 0;
255 }
256
257 /*!
258  * \internal
259  * \brief Add references to a list of dependencies.
260  *
261  * \param mod Owner of the new references.
262  * \param vec List of required modules to process
263  * \param missing Vector to store names of modules that are not running.
264  * \param ref_enhancers Reference all enhancers of each required module.
265  * \param isoptional Modules that are not loaded can be ignored.
266  *
267  * \retval 0 Success
268  * \retval -1 Failure
269  */
270 static int module_deps_process_reqlist(struct ast_module *mod,
271         struct ast_vector_string *vec, struct ast_vector_const_string *missing,
272         int ref_enhancers, int isoptional)
273 {
274         int idx;
275
276         for (idx = 0; idx < AST_VECTOR_SIZE(vec); idx++) {
277                 const char *depname = AST_VECTOR_GET(vec, idx);
278                 struct ast_module *dep = find_resource(depname, 0);
279
280                 if (!dep || !dep->flags.running) {
281                         if (isoptional && !dep) {
282                                 continue;
283                         }
284
285                         if (missing && !AST_VECTOR_APPEND(missing, depname)) {
286                                 continue;
287                         }
288
289                         return -1;
290                 }
291
292                 if (module_reffed_deps_add(mod, dep, missing)) {
293                         return -1;
294                 }
295
296                 if (ref_enhancers && module_reffed_deps_add_dep_enhancers(mod, dep, missing)) {
297                         return -1;
298                 }
299         }
300
301         return 0;
302 }
303
304 /*!
305  * \internal
306  * \brief Grab all references required to start the module.
307  *
308  * \param mod The module we're trying to start.
309  * \param missing Vector to store a list of missing dependencies.
310  *
311  * \retval 0 Success
312  * \retval -1 Failure
313  *
314  * \note module_list must be locked.
315  *
316  * \note Caller is responsible for initializing and freeing the vector.
317  *       Elements are safely read only while module_list remains locked.
318  */
319 static int module_deps_reference(struct ast_module *mod, struct ast_vector_const_string *missing)
320 {
321         int res = 0;
322
323         /* Grab references to modules we enhance but not other enhancements. */
324         res |= module_deps_process_reqlist(mod, &mod->enhances, missing, 0, 0);
325
326         /* Grab references to modules we require plus enhancements. */
327         res |= module_deps_process_reqlist(mod, &mod->requires, missing, 1, 0);
328
329         /* Grab references to optional modules including enhancements. */
330         res |= module_deps_process_reqlist(mod, &mod->optional_modules, missing, 1, 1);
331
332         return res;
333 }
334
335 /*!
336  * \brief Recursively find required dependencies that are not running.
337  *
338  * \param mod Module to scan for dependencies.
339  * \param missingdeps Vector listing modules that must be started first.
340  *
341  * \retval 0 All dependencies resolved.
342  * \retval -1 Failed to resolve some dependencies.
343  *
344  * An error from this function usually means a required module is not even
345  * loaded.  This function is safe from infinite recursion, but dependency
346  * loops are not reported as an error from here.  On success missingdeps
347  * will contain a list of every module that needs to be running before this
348  * module can start.  missingdeps is sorted by load priority so any missing
349  * dependencies can be started if needed.
350  */
351 static int module_deps_missing_recursive(struct ast_module *mod, struct module_vector *missingdeps)
352 {
353         int i = 0;
354         int res = -1;
355         struct ast_vector_const_string localdeps;
356         struct ast_module *dep;
357
358         /*
359          * localdeps stores a copy of all dependencies that mod could not reference.
360          * First we discard modules that we've already found. We add all newly found
361          * modules to the missingdeps vector then scan them recursively.  This will
362          * ensure we quickly run out of stuff to do.
363          */
364         AST_VECTOR_INIT(&localdeps, 0);
365         if (module_deps_reference(mod, &localdeps)) {
366                 goto clean_return;
367         }
368
369         while (i < AST_VECTOR_SIZE(&localdeps)) {
370                 dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
371                 if (!dep) {
372                         goto clean_return;
373                 }
374
375                 if (AST_VECTOR_GET_CMP(missingdeps, dep, AST_VECTOR_ELEM_DEFAULT_CMP)) {
376                         /* Skip common dependency.  We have already searched it. */
377                         AST_VECTOR_REMOVE(&localdeps, i, 0);
378                 } else {
379                         /* missingdeps is the real list so keep it sorted. */
380                         if (AST_VECTOR_ADD_SORTED(missingdeps, dep, module_vector_cmp)) {
381                                 goto clean_return;
382                         }
383                         i++;
384                 }
385         }
386
387         res = 0;
388         for (i = 0; !res && i < AST_VECTOR_SIZE(&localdeps); i++) {
389                 dep = find_resource(AST_VECTOR_GET(&localdeps, i), 0);
390                 /* We've already confirmed dep is loaded in the first loop. */
391                 res = module_deps_missing_recursive(dep, missingdeps);
392         }
393
394 clean_return:
395         AST_VECTOR_FREE(&localdeps);
396
397         return res;
398 }
399
400 const char *ast_module_name(const struct ast_module *mod)
401 {
402         if (!mod || !mod->info) {
403                 return NULL;
404         }
405
406         return mod->info->name;
407 }
408
409 struct loadupdate {
410         int (*updater)(void);
411         AST_LIST_ENTRY(loadupdate) entry;
412 };
413
414 static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
415
416 AST_MUTEX_DEFINE_STATIC(reloadlock);
417
418 struct reload_queue_item {
419         AST_LIST_ENTRY(reload_queue_item) entry;
420         char module[0];
421 };
422
423 static int do_full_reload = 0;
424
425 static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
426
427 /*!
428  * \internal
429  *
430  * This variable is set by load_dynamic_module so ast_module_register
431  * can know what pointer is being registered.
432  *
433  * This is protected by the module_list lock.
434  */
435 static struct ast_module * volatile resource_being_loaded;
436
437 /*!
438  * \internal
439  * \brief Used by AST_MODULE_INFO to register with the module loader.
440  *
441  * This function is automatically called when each module is opened.
442  * It must never be used from outside AST_MODULE_INFO.
443  */
444 void ast_module_register(const struct ast_module_info *info)
445 {
446         struct ast_module *mod;
447
448         /*
449          * This lock protects resource_being_loaded as well as the module
450          * list.  Normally we already have a lock on module_list when we
451          * begin the load but locking again from here prevents corruption
452          * if an asterisk module is dlopen'ed from outside the module loader.
453          */
454         AST_DLLIST_LOCK(&module_list);
455         mod = resource_being_loaded;
456         if (!mod) {
457                 AST_DLLIST_UNLOCK(&module_list);
458                 return;
459         }
460
461         ast_debug(5, "Registering module %s\n", info->name);
462
463         /* This tells load_dynamic_module that we're registered. */
464         resource_being_loaded = NULL;
465
466         mod->info = info;
467         if (ast_opt_ref_debug) {
468                 mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
469         }
470         AST_LIST_HEAD_INIT(&mod->users);
471         AST_VECTOR_INIT(&mod->requires, 0);
472         AST_VECTOR_INIT(&mod->optional_modules, 0);
473         AST_VECTOR_INIT(&mod->enhances, 0);
474         AST_VECTOR_INIT(&mod->reffed_deps, 0);
475
476         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
477         AST_DLLIST_UNLOCK(&module_list);
478
479         /* give the module a copy of its own handle, for later use in registrations and the like */
480         *((struct ast_module **) &(info->self)) = mod;
481 }
482
483 static void module_destroy(struct ast_module *mod)
484 {
485         AST_VECTOR_CALLBACK_VOID(&mod->requires, ast_free);
486         AST_VECTOR_FREE(&mod->requires);
487
488         AST_VECTOR_CALLBACK_VOID(&mod->optional_modules, ast_free);
489         AST_VECTOR_FREE(&mod->optional_modules);
490
491         AST_VECTOR_CALLBACK_VOID(&mod->enhances, ast_free);
492         AST_VECTOR_FREE(&mod->enhances);
493
494         /* Release references to all dependencies. */
495         AST_VECTOR_CALLBACK_VOID(&mod->reffed_deps, ast_module_unref);
496         AST_VECTOR_FREE(&mod->reffed_deps);
497
498         AST_LIST_HEAD_DESTROY(&mod->users);
499         ao2_cleanup(mod->ref_debug);
500         ast_free(mod);
501 }
502
503 void ast_module_unregister(const struct ast_module_info *info)
504 {
505         struct ast_module *mod = NULL;
506
507         /* it is assumed that the users list in the module structure
508            will already be empty, or we cannot have gotten to this
509            point
510         */
511         AST_DLLIST_LOCK(&module_list);
512         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
513                 if (mod->info == info) {
514                         AST_DLLIST_REMOVE_CURRENT(entry);
515                         break;
516                 }
517         }
518         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
519         AST_DLLIST_UNLOCK(&module_list);
520
521         if (mod && !mod->usecount) {
522                 /*
523                  * We are intentionally leaking mod if usecount is not zero.
524                  * This is necessary if the module is being forcefully unloaded.
525                  * In addition module_destroy is not safe to run after exit()
526                  * is called.  ast_module_unregister is run during cleanup of
527                  * the process when libc releases each module's shared object
528                  * library.
529                  */
530                 ast_debug(5, "Unregistering module %s\n", info->name);
531                 module_destroy(mod);
532         }
533 }
534
535 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
536 {
537         struct ast_module_user *u;
538
539         u = ast_calloc(1, sizeof(*u));
540         if (!u) {
541                 return NULL;
542         }
543
544         u->chan = chan;
545
546         AST_LIST_LOCK(&mod->users);
547         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
548         AST_LIST_UNLOCK(&mod->users);
549
550         if (mod->ref_debug) {
551                 ao2_ref(mod->ref_debug, +1);
552         }
553
554         ast_atomic_fetchadd_int(&mod->usecount, +1);
555
556         ast_update_use_count();
557
558         return u;
559 }
560
561 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
562 {
563         if (!u) {
564                 return;
565         }
566
567         AST_LIST_LOCK(&mod->users);
568         u = AST_LIST_REMOVE(&mod->users, u, entry);
569         AST_LIST_UNLOCK(&mod->users);
570         if (!u) {
571                 /*
572                  * Was not in the list.  Either a bad pointer or
573                  * __ast_module_user_hangup_all() has been called.
574                  */
575                 return;
576         }
577
578         if (mod->ref_debug) {
579                 ao2_ref(mod->ref_debug, -1);
580         }
581
582         ast_atomic_fetchadd_int(&mod->usecount, -1);
583         ast_free(u);
584
585         ast_update_use_count();
586 }
587
588 void __ast_module_user_hangup_all(struct ast_module *mod)
589 {
590         struct ast_module_user *u;
591
592         AST_LIST_LOCK(&mod->users);
593         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
594                 if (u->chan) {
595                         ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
596                 }
597
598                 if (mod->ref_debug) {
599                         ao2_ref(mod->ref_debug, -1);
600                 }
601
602                 ast_atomic_fetchadd_int(&mod->usecount, -1);
603                 ast_free(u);
604         }
605         AST_LIST_UNLOCK(&mod->users);
606
607         ast_update_use_count();
608 }
609
610 /*! \note
611  * In addition to modules, the reload command handles some extra keywords
612  * which are listed here together with the corresponding handlers.
613  * This table is also used by the command completion code.
614  */
615 static struct reload_classes {
616         const char *name;
617         int (*reload_fn)(void);
618 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
619         { "acl",         ast_named_acl_reload },
620         { "cdr",         ast_cdr_engine_reload },
621         { "cel",         ast_cel_engine_reload },
622         { "dnsmgr",      dnsmgr_reload },
623         { "dsp",         ast_dsp_reload},
624         { "extconfig",   read_config_maps },
625         { "enum",        ast_enum_reload },
626         { "features",    ast_features_config_reload },
627         { "http",        ast_http_reload },
628         { "indications", ast_indications_reload },
629         { "logger",      logger_reload },
630         { "manager",     reload_manager },
631         { "plc",         ast_plc_reload },
632         { "sounds",      ast_sounds_reindex },
633         { "udptl",       ast_udptl_reload },
634         { NULL,          NULL }
635 };
636
637 static int printdigest(const unsigned char *d)
638 {
639         int x, pos;
640         char buf[256]; /* large enough so we don't have to worry */
641
642         for (pos = 0, x = 0; x < 16; x++)
643                 pos += sprintf(buf + pos, " %02hhx", *d++);
644
645         ast_debug(1, "Unexpected signature:%s\n", buf);
646
647         return 0;
648 }
649
650 static int key_matches(const unsigned char *key1, const unsigned char *key2)
651 {
652         int x;
653
654         for (x = 0; x < 16; x++) {
655                 if (key1[x] != key2[x])
656                         return 0;
657         }
658
659         return 1;
660 }
661
662 static int verify_key(const unsigned char *key)
663 {
664         struct MD5Context c;
665         unsigned char digest[16];
666
667         MD5Init(&c);
668         MD5Update(&c, key, strlen((char *)key));
669         MD5Final(digest, &c);
670
671         if (key_matches(expected_key, digest))
672                 return 0;
673
674         printdigest(digest);
675
676         return -1;
677 }
678
679 static size_t resource_name_baselen(const char *name)
680 {
681         size_t len = strlen(name);
682
683         if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
684                 return len - 3;
685         }
686
687         return len;
688 }
689
690 static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
691 {
692         if (baselen1 != resource_name_baselen(name2)) {
693                 return -1;
694         }
695
696         return strncasecmp(name1, name2, baselen1);
697 }
698
699 static struct ast_module *find_resource(const char *resource, int do_lock)
700 {
701         struct ast_module *cur;
702         size_t resource_baselen = resource_name_baselen(resource);
703
704         if (do_lock) {
705                 AST_DLLIST_LOCK(&module_list);
706         }
707
708         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
709                 if (!resource_name_match(resource, resource_baselen, cur->resource)) {
710                         break;
711                 }
712         }
713
714         if (do_lock) {
715                 AST_DLLIST_UNLOCK(&module_list);
716         }
717
718         return cur;
719 }
720
721 /*!
722  * \brief dlclose(), with failure logging.
723  */
724 static void logged_dlclose(const char *name, void *lib)
725 {
726         char *error;
727
728         if (!lib) {
729                 return;
730         }
731
732         /* Clear any existing error */
733         dlerror();
734         if (dlclose(lib)) {
735                 error = dlerror();
736                 ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
737                         S_OR(name, "unknown"), S_OR(error, "Unknown error"));
738         }
739 }
740
741 #if defined(HAVE_RTLD_NOLOAD)
742 /*!
743  * \brief Check to see if the given resource is loaded.
744  *
745  * \param resource_name Name of the resource, including .so suffix.
746  * \return False (0) if module is not loaded.
747  * \return True (non-zero) if module is loaded.
748  */
749 static int is_module_loaded(const char *resource_name)
750 {
751         char fn[PATH_MAX] = "";
752         void *lib;
753
754         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
755                 resource_name);
756
757         lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
758
759         if (lib) {
760                 logged_dlclose(resource_name, lib);
761                 return 1;
762         }
763
764         return 0;
765 }
766 #endif
767
768 static void unload_dynamic_module(struct ast_module *mod)
769 {
770 #if defined(HAVE_RTLD_NOLOAD)
771         char *name = ast_strdupa(ast_module_name(mod));
772 #endif
773         void *lib = mod->lib;
774
775         /* WARNING: the structure pointed to by mod is going to
776            disappear when this operation succeeds, so we can't
777            dereference it */
778         logged_dlclose(ast_module_name(mod), lib);
779
780         /* There are several situations where the module might still be resident
781          * in memory.
782          *
783          * If somehow there was another dlopen() on the same module (unlikely,
784          * since that all is supposed to happen in loader.c).
785          *
786          * Avoid the temptation of repeating the dlclose(). The other code that
787          * dlopened the module still has its module reference, and should close
788          * it itself. In other situations, dlclose() will happily return success
789          * for as many times as you wish to call it.
790          */
791 #if defined(HAVE_RTLD_NOLOAD)
792         if (is_module_loaded(name)) {
793                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
794         }
795 #endif
796 }
797
798 /*!
799  * \internal
800  * \brief Attempt to dlopen a module.
801  *
802  * \param resource_in The module name to load.
803  * \param so_ext ".so" or blank if ".so" is already part of resource_in.
804  * \param filename Passed directly to dlopen.
805  * \param flags Passed directly to dlopen.
806  * \param suppress_logging Do not log any error from dlopen.
807  *
808  * \return Pointer to opened module, NULL on error.
809  *
810  * \warning module_list must be locked before calling this function.
811  */
812 static struct ast_module *load_dlopen(const char *resource_in, const char *so_ext,
813         const char *filename, int flags, unsigned int suppress_logging)
814 {
815         struct ast_module *mod;
816
817         ast_assert(!resource_being_loaded);
818
819         mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1);
820         if (!mod) {
821                 return NULL;
822         }
823
824         sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */
825
826         resource_being_loaded = mod;
827         mod->lib = dlopen(filename, flags);
828         if (resource_being_loaded) {
829                 resource_being_loaded = NULL;
830                 if (mod->lib) {
831                         ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in);
832                         logged_dlclose(resource_in, mod->lib);
833                 } else if (!suppress_logging) {
834                         ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
835                 }
836                 ast_free(mod);
837
838                 return NULL;
839         }
840
841         return mod;
842 }
843
844 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int suppress_logging)
845 {
846         char fn[PATH_MAX];
847         struct ast_module *mod;
848         size_t resource_in_len = strlen(resource_in);
849         const char *so_ext = "";
850
851         if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) {
852                 so_ext = ".so";
853         }
854
855         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext);
856
857         /* Try loading in quiet mode first with RTLD_LOCAL.  The majority of modules do not
858          * export symbols so this allows the least number of calls to dlopen. */
859         mod = load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_LOCAL, suppress_logging);
860
861         if (!mod || !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
862                 return mod;
863         }
864
865         /* Close the module so we can reopen with correct flags. */
866         logged_dlclose(resource_in, mod->lib);
867
868         return load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_GLOBAL, 0);
869 }
870
871 int modules_shutdown(void)
872 {
873         struct ast_module *mod;
874         int somethingchanged;
875         int res;
876
877         AST_DLLIST_LOCK(&module_list);
878
879         /*!\note Some resources, like timers, are started up dynamically, and thus
880          * may be still in use, even if all channels are dead.  We must therefore
881          * check the usecount before asking modules to unload. */
882         do {
883                 /* Reset flag before traversing the list */
884                 somethingchanged = 0;
885
886                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
887                         if (mod->usecount) {
888                                 ast_debug(1, "Passing on %s: its use count is %d\n",
889                                         mod->resource, mod->usecount);
890                                 continue;
891                         }
892                         AST_DLLIST_REMOVE_CURRENT(entry);
893                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
894                                 ast_verb(1, "Unloading %s\n", mod->resource);
895                                 mod->info->unload();
896                         }
897                         module_destroy(mod);
898                         somethingchanged = 1;
899                 }
900                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
901                 if (!somethingchanged) {
902                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
903                                 if (mod->flags.keepuntilshutdown) {
904                                         ast_module_unref(mod);
905                                         mod->flags.keepuntilshutdown = 0;
906                                         somethingchanged = 1;
907                                 }
908                         }
909                 }
910         } while (somethingchanged);
911
912         res = AST_DLLIST_EMPTY(&module_list);
913         AST_DLLIST_UNLOCK(&module_list);
914
915         return !res;
916 }
917
918 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
919 {
920         struct ast_module *mod;
921         int res = -1;
922         int error = 0;
923
924         AST_DLLIST_LOCK(&module_list);
925
926         if (!(mod = find_resource(resource_name, 0))) {
927                 AST_DLLIST_UNLOCK(&module_list);
928                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
929                 return -1;
930         }
931
932         if (!mod->flags.running || mod->flags.declined) {
933                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
934                 error = 1;
935         }
936
937         if (!error && (mod->usecount > 0)) {
938                 if (force)
939                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
940                                 resource_name, mod->usecount);
941                 else {
942                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
943                                 mod->usecount);
944                         error = 1;
945                 }
946         }
947
948         if (!error) {
949                 /* Request any channels attached to the module to hangup. */
950                 __ast_module_user_hangup_all(mod);
951
952                 ast_verb(1, "Unloading %s\n", mod->resource);
953                 res = mod->info->unload();
954                 if (res) {
955                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
956                         if (force <= AST_FORCE_FIRM) {
957                                 error = 1;
958                         } else {
959                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
960                         }
961                 }
962
963                 if (!error) {
964                         /*
965                          * Request hangup on any channels that managed to get attached
966                          * while we called the module unload function.
967                          */
968                         __ast_module_user_hangup_all(mod);
969                         sched_yield();
970                 }
971         }
972
973         if (!error)
974                 mod->flags.running = mod->flags.declined = 0;
975
976         AST_DLLIST_UNLOCK(&module_list);
977
978         if (!error) {
979                 unload_dynamic_module(mod);
980                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
981                 ast_update_use_count();
982         }
983
984         return res;
985 }
986
987 static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
988 {
989         switch (type) {
990         case AST_MODULE_HELPER_UNLOAD:
991                 return !mod->usecount && mod->flags.running && !mod->flags.declined;
992
993         case AST_MODULE_HELPER_RELOAD:
994                 return mod->flags.running && mod->info->reload;
995
996         case AST_MODULE_HELPER_RUNNING:
997                 return mod->flags.running;
998
999         case AST_MODULE_HELPER_LOADED:
1000                 /* if we have a 'struct ast_module' then we're loaded. */
1001                 return 1;
1002         default:
1003                 /* This function is not called for AST_MODULE_HELPER_LOAD. */
1004                 /* Unknown ast_module_helper_type. Assume it doesn't match. */
1005                 ast_assert(0);
1006
1007                 return 0;
1008         }
1009 }
1010
1011 static char *module_load_helper(const char *word, int state)
1012 {
1013         struct ast_module *mod;
1014         int which = 0;
1015         char *name;
1016         char *ret = NULL;
1017         char *editline_ret;
1018         char fullpath[PATH_MAX];
1019         int idx = 0;
1020         /* This is needed to avoid listing modules that are already running. */
1021         AST_VECTOR(, char *) running_modules;
1022
1023         AST_VECTOR_INIT(&running_modules, 200);
1024
1025         AST_DLLIST_LOCK(&module_list);
1026         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1027                 if (mod->flags.running) {
1028                         AST_VECTOR_APPEND(&running_modules, mod->resource);
1029                 }
1030         }
1031
1032         if (word[0] == '/') {
1033                 /* BUGBUG: we should not support this. */
1034                 ast_copy_string(fullpath, word, sizeof(fullpath));
1035         } else {
1036                 snprintf(fullpath, sizeof(fullpath), "%s/%s", ast_config_AST_MODULE_DIR, word);
1037         }
1038
1039         /*
1040          * This is ugly that we keep calling filename_completion_function.
1041          * The only way to avoid this would be to make a copy of the function
1042          * that skips matches found in the running_modules vector.
1043          */
1044         while (!ret && (name = editline_ret = filename_completion_function(fullpath, idx++))) {
1045                 if (word[0] != '/') {
1046                         name += (strlen(ast_config_AST_MODULE_DIR) + 1);
1047                 }
1048
1049                 /* Don't list files that are already loaded! */
1050                 if (!AST_VECTOR_GET_CMP(&running_modules, name, !strcasecmp) && ++which > state) {
1051                         ret = ast_strdup(name);
1052                 }
1053
1054                 ast_std_free(editline_ret);
1055         }
1056
1057         /* Do not clean-up the elements, they belong to module_list. */
1058         AST_VECTOR_FREE(&running_modules);
1059         AST_DLLIST_UNLOCK(&module_list);
1060
1061         return ret;
1062 }
1063
1064 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
1065 {
1066         struct ast_module *mod;
1067         int which = 0;
1068         int wordlen = strlen(word);
1069         char *ret = NULL;
1070
1071         if (pos != rpos) {
1072                 return NULL;
1073         }
1074
1075         if (type == AST_MODULE_HELPER_LOAD) {
1076                 return module_load_helper(word, state);
1077         }
1078
1079         if (type == AST_MODULE_HELPER_RELOAD) {
1080                 int idx;
1081
1082                 for (idx = 0; reload_classes[idx].name; idx++) {
1083                         if (!strncasecmp(word, reload_classes[idx].name, wordlen) && ++which > state) {
1084                                 return ast_strdup(reload_classes[idx].name);
1085                         }
1086                 }
1087         }
1088
1089         AST_DLLIST_LOCK(&module_list);
1090         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1091                 if (!module_matches_helper_type(mod, type)) {
1092                         continue;
1093                 }
1094
1095                 if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
1096                         ret = ast_strdup(mod->resource);
1097                         break;
1098                 }
1099         }
1100         AST_DLLIST_UNLOCK(&module_list);
1101
1102         return ret;
1103 }
1104
1105 void ast_process_pending_reloads(void)
1106 {
1107         struct reload_queue_item *item;
1108
1109         modules_loaded = 1;
1110
1111         AST_LIST_LOCK(&reload_queue);
1112
1113         if (do_full_reload) {
1114                 do_full_reload = 0;
1115                 AST_LIST_UNLOCK(&reload_queue);
1116                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
1117                 ast_module_reload(NULL);
1118                 return;
1119         }
1120
1121         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1122                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
1123                 ast_module_reload(item->module);
1124                 ast_free(item);
1125         }
1126
1127         AST_LIST_UNLOCK(&reload_queue);
1128 }
1129
1130 static void queue_reload_request(const char *module)
1131 {
1132         struct reload_queue_item *item;
1133
1134         AST_LIST_LOCK(&reload_queue);
1135
1136         if (do_full_reload) {
1137                 AST_LIST_UNLOCK(&reload_queue);
1138                 return;
1139         }
1140
1141         if (ast_strlen_zero(module)) {
1142                 /* A full reload request (when module is NULL) wipes out any previous
1143                    reload requests and causes the queue to ignore future ones */
1144                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1145                         ast_free(item);
1146                 }
1147                 do_full_reload = 1;
1148         } else {
1149                 /* No reason to add the same module twice */
1150                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
1151                         if (!strcasecmp(item->module, module)) {
1152                                 AST_LIST_UNLOCK(&reload_queue);
1153                                 return;
1154                         }
1155                 }
1156                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
1157                 if (!item) {
1158                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
1159                         AST_LIST_UNLOCK(&reload_queue);
1160                         return;
1161                 }
1162                 strcpy(item->module, module);
1163                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
1164         }
1165         AST_LIST_UNLOCK(&reload_queue);
1166 }
1167
1168 /*!
1169  * \since 12
1170  * \internal
1171  * \brief Publish a \ref stasis message regarding the reload result
1172  */
1173 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
1174 {
1175         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1176         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
1177         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1178         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
1179         char res_buffer[8];
1180
1181         if (!ast_manager_get_generic_type()) {
1182                 return;
1183         }
1184
1185         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
1186         event_object = ast_json_pack("{s: s, s: s}",
1187                         "Module", S_OR(name, "All"),
1188                         "Status", res_buffer);
1189         json_object = ast_json_pack("{s: s, s: i, s: o}",
1190                         "type", "Reload",
1191                         "class_type", EVENT_FLAG_SYSTEM,
1192                         "event", ast_json_ref(event_object));
1193
1194         if (!json_object) {
1195                 return;
1196         }
1197
1198         payload = ast_json_payload_create(json_object);
1199         if (!payload) {
1200                 return;
1201         }
1202
1203         message = stasis_message_create(ast_manager_get_generic_type(), payload);
1204         if (!message) {
1205                 return;
1206         }
1207
1208         stasis_publish(ast_manager_get_topic(), message);
1209 }
1210
1211 enum ast_module_reload_result ast_module_reload(const char *name)
1212 {
1213         struct ast_module *cur;
1214         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
1215         int i;
1216         size_t name_baselen = name ? resource_name_baselen(name) : 0;
1217
1218         /* If we aren't fully booted, we just pretend we reloaded but we queue this
1219            up to run once we are booted up. */
1220         if (!modules_loaded) {
1221                 queue_reload_request(name);
1222                 res = AST_MODULE_RELOAD_QUEUED;
1223                 goto module_reload_exit;
1224         }
1225
1226         if (ast_mutex_trylock(&reloadlock)) {
1227                 ast_verb(3, "The previous reload command didn't finish yet\n");
1228                 res = AST_MODULE_RELOAD_IN_PROGRESS;
1229                 goto module_reload_exit;
1230         }
1231         ast_sd_notify("RELOAD=1");
1232         ast_lastreloadtime = ast_tvnow();
1233
1234         if (ast_opt_lock_confdir) {
1235                 int try;
1236                 int res;
1237                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
1238                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
1239                         if (res == AST_LOCK_TIMEOUT) {
1240                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
1241                         }
1242                 }
1243                 if (res != AST_LOCK_SUCCESS) {
1244                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
1245                         res = AST_MODULE_RELOAD_ERROR;
1246                         goto module_reload_done;
1247                 }
1248         }
1249
1250         /* Call "predefined" reload here first */
1251         for (i = 0; reload_classes[i].name; i++) {
1252                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
1253                         if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
1254                                 res = AST_MODULE_RELOAD_SUCCESS;
1255                         }
1256                 }
1257         }
1258
1259         if (name && res == AST_MODULE_RELOAD_SUCCESS) {
1260                 if (ast_opt_lock_confdir) {
1261                         ast_unlock_path(ast_config_AST_CONFIG_DIR);
1262                 }
1263                 goto module_reload_done;
1264         }
1265
1266         AST_DLLIST_LOCK(&module_list);
1267         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1268                 const struct ast_module_info *info = cur->info;
1269
1270                 if (name && resource_name_match(name, name_baselen, cur->resource)) {
1271                         continue;
1272                 }
1273
1274                 if (!cur->flags.running || cur->flags.declined) {
1275                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1276                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
1277                         }
1278                         if (!name) {
1279                                 continue;
1280                         }
1281                         break;
1282                 }
1283
1284                 if (!info->reload) {    /* cannot be reloaded */
1285                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1286                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
1287                         }
1288                         if (!name) {
1289                                 continue;
1290                         }
1291                         break;
1292                 }
1293                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
1294                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
1295                         res = AST_MODULE_RELOAD_SUCCESS;
1296                 }
1297                 if (name) {
1298                         break;
1299                 }
1300         }
1301         AST_DLLIST_UNLOCK(&module_list);
1302
1303         if (ast_opt_lock_confdir) {
1304                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
1305         }
1306 module_reload_done:
1307         ast_mutex_unlock(&reloadlock);
1308         ast_sd_notify("READY=1");
1309
1310 module_reload_exit:
1311         publish_reload_message(name, res);
1312         return res;
1313 }
1314
1315 static unsigned int inspect_module(const struct ast_module *mod)
1316 {
1317         if (!mod->info->description) {
1318                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
1319                 return 1;
1320         }
1321
1322         if (!mod->info->key) {
1323                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
1324                 return 1;
1325         }
1326
1327         if (verify_key((unsigned char *) mod->info->key)) {
1328                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
1329                 return 1;
1330         }
1331
1332         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
1333             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
1334                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
1335                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
1336                 return 1;
1337         }
1338
1339         return 0;
1340 }
1341
1342 static enum ast_module_load_result start_resource(struct ast_module *mod)
1343 {
1344         char tmp[256];
1345         enum ast_module_load_result res;
1346
1347         if (mod->flags.running) {
1348                 return AST_MODULE_LOAD_SUCCESS;
1349         }
1350
1351         if (!mod->info->load) {
1352                 return AST_MODULE_LOAD_FAILURE;
1353         }
1354
1355         if (module_deps_reference(mod, NULL)) {
1356                 struct module_vector missing;
1357                 int i;
1358
1359                 AST_VECTOR_INIT(&missing, 0);
1360                 if (module_deps_missing_recursive(mod, &missing)) {
1361                         ast_log(LOG_ERROR, "%s has one or more unknown dependencies.\n", mod->info->name);
1362                 }
1363                 for (i = 0; i < AST_VECTOR_SIZE(&missing); i++) {
1364                         ast_log(LOG_ERROR, "%s loaded before dependency %s!\n", mod->info->name,
1365                                 AST_VECTOR_GET(&missing, i)->info->name);
1366                 }
1367                 AST_VECTOR_FREE(&missing);
1368
1369                 return AST_MODULE_LOAD_FAILURE;
1370         }
1371
1372         if (!ast_fully_booted) {
1373                 ast_verb(1, "Loading %s.\n", mod->resource);
1374         }
1375         res = mod->info->load();
1376
1377         switch (res) {
1378         case AST_MODULE_LOAD_SUCCESS:
1379                 if (!ast_fully_booted) {
1380                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1381                 } else {
1382                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1383                 }
1384
1385                 mod->flags.running = 1;
1386
1387                 ast_update_use_count();
1388                 break;
1389         case AST_MODULE_LOAD_DECLINE:
1390                 mod->flags.declined = 1;
1391                 break;
1392         case AST_MODULE_LOAD_FAILURE:
1393         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1394         case AST_MODULE_LOAD_PRIORITY:
1395                 break;
1396         }
1397
1398         /* Make sure the newly started module is at the end of the list */
1399         AST_DLLIST_LOCK(&module_list);
1400         AST_DLLIST_REMOVE(&module_list, mod, entry);
1401         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1402         AST_DLLIST_UNLOCK(&module_list);
1403
1404         return res;
1405 }
1406
1407 /*! loads a resource based upon resource_name. If global_symbols_only is set
1408  *  only modules with global symbols will be loaded.
1409  *
1410  *  If the module_vector is provided (not NULL) the module is found and added to the
1411  *  vector without running the module's load() function.  By doing this, modules
1412  *  can be initialized later in order by priority and dependencies.
1413  *
1414  *  If the module_vector is not provided, the module's load function will be executed
1415  *  immediately */
1416 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging, struct module_vector *resource_heap, int required)
1417 {
1418         struct ast_module *mod;
1419         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1420
1421         if ((mod = find_resource(resource_name, 0))) {
1422                 if (mod->flags.running) {
1423                         ast_log(LOG_WARNING, "Module '%s' already loaded and running.\n", resource_name);
1424                         return AST_MODULE_LOAD_DECLINE;
1425                 }
1426         } else {
1427                 mod = load_dynamic_module(resource_name, suppress_logging);
1428                 if (!mod) {
1429                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1430                 }
1431
1432                 /* Split lists from mod->info. */
1433                 res  = ast_vector_string_split(&mod->requires, mod->info->requires, ",", 0, strcasecmp);
1434                 res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp);
1435                 res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp);
1436                 if (res) {
1437                         ast_log(LOG_WARNING, "Failed to initialize dependency structures for module '%s'.\n", resource_name);
1438                         unload_dynamic_module(mod);
1439
1440                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1441                 }
1442         }
1443
1444         if (inspect_module(mod)) {
1445                 goto prestart_error;
1446         }
1447
1448         mod->flags.declined = 0;
1449
1450         if (resource_heap) {
1451                 if (AST_VECTOR_ADD_SORTED(resource_heap, mod, module_vector_cmp)) {
1452                         goto prestart_error;
1453                 }
1454                 res = AST_MODULE_LOAD_PRIORITY;
1455         } else {
1456                 res = start_resource(mod);
1457         }
1458
1459         return res;
1460
1461 prestart_error:
1462         ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1463         unload_dynamic_module(mod);
1464         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1465 }
1466
1467 int ast_load_resource(const char *resource_name)
1468 {
1469         int res;
1470         AST_DLLIST_LOCK(&module_list);
1471         res = load_resource(resource_name, 0, NULL, 0);
1472         if (!res) {
1473                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1474         }
1475         AST_DLLIST_UNLOCK(&module_list);
1476
1477         return res;
1478 }
1479
1480 struct load_order_entry {
1481         char *resource;
1482         int required;
1483         AST_LIST_ENTRY(load_order_entry) entry;
1484 };
1485
1486 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1487
1488 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
1489 {
1490         struct load_order_entry *order;
1491         size_t resource_baselen = resource_name_baselen(resource);
1492
1493         AST_LIST_TRAVERSE(load_order, order, entry) {
1494                 if (!resource_name_match(resource, resource_baselen, order->resource)) {
1495                         /* Make sure we have the proper setting for the required field
1496                            (we might have both load= and required= lines in modules.conf) */
1497                         order->required |= required;
1498                         return NULL;
1499                 }
1500         }
1501
1502         if (!(order = ast_calloc(1, sizeof(*order))))
1503                 return NULL;
1504
1505         order->resource = ast_strdup(resource);
1506         if (!order->resource) {
1507                 ast_free(order);
1508
1509                 return NULL;
1510         }
1511         order->required = required;
1512         AST_LIST_INSERT_TAIL(load_order, order, entry);
1513
1514         return order;
1515 }
1516
1517 AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
1518
1519 static enum ast_module_load_result start_resource_attempt(struct ast_module *mod, int *count)
1520 {
1521         enum ast_module_load_result lres;
1522
1523         /* Try to grab required references. */
1524         if (module_deps_reference(mod, NULL)) {
1525                 /* We're likely to retry so not an error. */
1526                 ast_debug(1, "Module %s is missing dependencies\n", mod->resource);
1527                 return AST_MODULE_LOAD_SKIP;
1528         }
1529
1530         lres = start_resource(mod);
1531         ast_debug(3, "START: %-46s[%d] %d\n",
1532                 mod->resource,
1533                 ast_test_flag(mod->info, AST_MODFLAG_LOAD_ORDER) ? mod->info->load_pri : AST_MODPRI_DEFAULT,
1534                 lres);
1535
1536         if (lres == AST_MODULE_LOAD_SUCCESS) {
1537                 (*count)++;
1538         } else if (lres == AST_MODULE_LOAD_FAILURE) {
1539                 ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
1540         }
1541
1542         return lres;
1543 }
1544
1545 static int start_resource_list(struct module_vector *resources, int *mod_count)
1546 {
1547         struct module_vector missingdeps;
1548         int res = 0;
1549
1550         AST_VECTOR_INIT(&missingdeps, 0);
1551         while (AST_VECTOR_SIZE(resources)) {
1552                 struct ast_module *mod = AST_VECTOR_REMOVE(resources, 0, 1);
1553                 enum ast_module_load_result lres;
1554
1555                 lres = start_resource_attempt(mod, mod_count);
1556                 if (lres == AST_MODULE_LOAD_SUCCESS) {
1557                         /* No missing dependencies, successful. */
1558                         continue;
1559                 }
1560
1561                 if (lres == AST_MODULE_LOAD_FAILURE) {
1562                         ast_log(LOG_ERROR, "Failed to load %s.\n", ast_module_name(mod));
1563                         res = -1;
1564                         break;
1565                 }
1566
1567                 if (lres == AST_MODULE_LOAD_DECLINE) {
1568                         continue;
1569                 }
1570
1571                 res = module_deps_missing_recursive(mod, &missingdeps);
1572                 if (res) {
1573                         break;
1574                 }
1575
1576                 if (!AST_VECTOR_SIZE(&missingdeps)) {
1577                         ast_log(LOG_WARNING, "%s isn't missing any dependencies but still didn't start\n",
1578                                 ast_module_name(mod));
1579                         /* Dependencies were met but the module failed to start. */
1580                         res = -1;
1581                         break;
1582                 }
1583
1584                 ast_debug(1, "%s has %d dependencies\n",
1585                         ast_module_name(mod), (int)AST_VECTOR_SIZE(&missingdeps));
1586                 while (AST_VECTOR_SIZE(&missingdeps)) {
1587                         int didwork = 0;
1588                         int i = 0;
1589
1590                         while (i < AST_VECTOR_SIZE(&missingdeps)) {
1591                                 struct ast_module *dep = AST_VECTOR_GET(&missingdeps, i);
1592
1593                                 ast_debug(1, "%s trying to start %s\n", ast_module_name(mod), ast_module_name(dep));
1594                                 if (!start_resource_attempt(dep, mod_count)) {
1595                                         ast_debug(1, "%s started %s\n", ast_module_name(mod), ast_module_name(dep));
1596                                         AST_VECTOR_REMOVE(&missingdeps, i, 1);
1597                                         AST_VECTOR_REMOVE_CMP_ORDERED(resources, dep,
1598                                                 AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_ELEM_CLEANUP_NOOP);
1599                                         didwork++;
1600                                         continue;
1601                                 }
1602                                 ast_debug(1, "%s failed to start %s\n", ast_module_name(mod), ast_module_name(dep));
1603                                 i++;
1604                         }
1605
1606                         if (!didwork) {
1607                                 break;
1608                         }
1609                 }
1610
1611                 if (AST_VECTOR_SIZE(&missingdeps)) {
1612                         ast_log(LOG_ERROR, "Failed to load %s due to unfilled dependencies.\n",
1613                                 ast_module_name(mod));
1614                         res = -1;
1615                         break;
1616                 }
1617
1618                 res = start_resource_attempt(mod, mod_count);
1619                 if (res) {
1620                         ast_log(LOG_ERROR, "Failed to load %s: %d\n", ast_module_name(mod), res);
1621                         break;
1622                 }
1623         }
1624
1625         AST_VECTOR_FREE(&missingdeps);
1626
1627         return res;
1628 }
1629
1630 /*! loads modules in order by load_pri, updates mod_count
1631         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1632 */
1633 static int load_resource_list(struct load_order *load_order, int *mod_count)
1634 {
1635         struct module_vector resource_heap;
1636         struct load_order_entry *order;
1637         struct load_retries load_retries;
1638         int count = 0;
1639         int res = 0;
1640         int i = 0;
1641 #define LOAD_RETRIES 4
1642
1643         AST_LIST_HEAD_INIT_NOLOCK(&load_retries);
1644
1645         if (AST_VECTOR_INIT(&resource_heap, 500)) {
1646                 ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
1647
1648                 return -1;
1649         }
1650
1651         /* first, add find and add modules to heap */
1652         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1653                 enum ast_module_load_result lres;
1654
1655                 /* Suppress log messages unless this is the last pass */
1656                 lres = load_resource(order->resource, 1, &resource_heap, order->required);
1657                 ast_debug(3, "PASS 0: %-46s %d\n", order->resource, lres);
1658                 switch (lres) {
1659                 case AST_MODULE_LOAD_SUCCESS:
1660                         /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */
1661                         break;
1662                 case AST_MODULE_LOAD_FAILURE:
1663                 case AST_MODULE_LOAD_DECLINE:
1664                         /*
1665                          * DECLINE or FAILURE means there was an issue with dlopen or module_register
1666                          * which might be retryable.  LOAD_FAILURE only happens for required modules
1667                          * but we're still going to retry.  We need to remove the entry from the
1668                          * load_order list and add it to the load_retries list.
1669                          */
1670                         AST_LIST_REMOVE_CURRENT(entry);
1671                         AST_LIST_INSERT_TAIL(&load_retries, order, entry);
1672                         break;
1673                 case AST_MODULE_LOAD_SKIP:
1674                         /*
1675                          * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.
1676                          * Leave it in load_order for the next call of load_resource_list.
1677                          */
1678                         break;
1679                 case AST_MODULE_LOAD_PRIORITY:
1680                         /* load_resource worked and the module was added to the priority vector */
1681                         AST_LIST_REMOVE_CURRENT(entry);
1682                         ast_free(order->resource);
1683                         ast_free(order);
1684                         break;
1685                 }
1686         }
1687         AST_LIST_TRAVERSE_SAFE_END;
1688
1689         /* Retry the failures until the list is empty or we reach LOAD_RETRIES */
1690         for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {
1691                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {
1692                         enum ast_module_load_result lres;
1693
1694                         /* Suppress log messages unless this is the last pass */
1695                         lres = load_resource(order->resource, (i < LOAD_RETRIES - 1), &resource_heap, order->required);
1696                         ast_debug(3, "PASS %d %-46s %d\n", i + 1, order->resource, lres);
1697                         switch (lres) {
1698                         /* These are all retryable. */
1699                         case AST_MODULE_LOAD_SUCCESS:
1700                         case AST_MODULE_LOAD_DECLINE:
1701                                 break;
1702                         case AST_MODULE_LOAD_FAILURE:
1703                                 /* LOAD_FAILURE only happens for required modules */
1704                                 if (i == LOAD_RETRIES - 1) {
1705                                         /* This was the last chance to load a required module*/
1706                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1707                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1708                                         res =  -2;
1709                                         goto done;
1710                                 }
1711                                 break;;
1712                         case AST_MODULE_LOAD_SKIP:
1713                                 /*
1714                                  * SKIP means that dlopen worked but global_symbols was set and this module
1715                                  * doesn't qualify.  Put it back in load_order for the next call of
1716                                  * load_resource_list.
1717                                  */
1718                                 AST_LIST_REMOVE_CURRENT(entry);
1719                                 AST_LIST_INSERT_TAIL(load_order, order, entry);
1720                                 break;
1721                         case AST_MODULE_LOAD_PRIORITY:
1722                                 /* load_resource worked and the module was added to the priority heap */
1723                                 AST_LIST_REMOVE_CURRENT(entry);
1724                                 ast_free(order->resource);
1725                                 ast_free(order);
1726                                 break;
1727                         }
1728                 }
1729                 AST_LIST_TRAVERSE_SAFE_END;
1730         }
1731
1732         res = start_resource_list(&resource_heap, &count);
1733
1734 done:
1735         while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {
1736                 ast_free(order->resource);
1737                 ast_free(order);
1738         }
1739
1740         if (mod_count) {
1741                 *mod_count += count;
1742         }
1743         AST_VECTOR_FREE(&resource_heap);
1744
1745         return res;
1746 }
1747
1748 int load_modules(unsigned int preload_only)
1749 {
1750         struct ast_config *cfg;
1751         struct load_order_entry *order;
1752         struct ast_variable *v;
1753         unsigned int load_count;
1754         struct load_order load_order;
1755         int res = 0;
1756         struct ast_flags config_flags = { 0 };
1757         int modulecount = 0;
1758         struct dirent *dirent;
1759         DIR *dir;
1760
1761         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1762
1763         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1764
1765         AST_DLLIST_LOCK(&module_list);
1766
1767         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1768         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1769                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1770                 goto done;
1771         }
1772
1773         /* first, find all the modules we have been explicitly requested to load */
1774         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1775                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1776                         add_to_load_order(v->value, &load_order, 0);
1777                 }
1778                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1779                         /* Add the module to the list and make sure it's required */
1780                         add_to_load_order(v->value, &load_order, 1);
1781                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1782                 }
1783         }
1784
1785         /* check if 'autoload' is on */
1786         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1787                 /* if we are allowed to load dynamic modules, scan the directory for
1788                    for all available modules and add them as well */
1789                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1790                         while ((dirent = readdir(dir))) {
1791                                 int ld = strlen(dirent->d_name);
1792
1793                                 /* Must end in .so to load it.  */
1794
1795                                 if (ld < 4)
1796                                         continue;
1797
1798                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1799                                         continue;
1800
1801                                 /* if there is already a module by this name in the module_list,
1802                                    skip this file */
1803                                 if (find_resource(dirent->d_name, 0))
1804                                         continue;
1805
1806                                 add_to_load_order(dirent->d_name, &load_order, 0);
1807                         }
1808
1809                         closedir(dir);
1810                 } else {
1811                         if (!ast_opt_quiet)
1812                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1813                                         ast_config_AST_MODULE_DIR);
1814                 }
1815         }
1816
1817         /* now scan the config for any modules we are prohibited from loading and
1818            remove them from the load order */
1819         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1820                 size_t baselen;
1821
1822                 if (strcasecmp(v->name, "noload")) {
1823                         continue;
1824                 }
1825
1826                 baselen = resource_name_baselen(v->value);
1827                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1828                         if (!resource_name_match(v->value, baselen, order->resource)) {
1829                                 AST_LIST_REMOVE_CURRENT(entry);
1830                                 ast_free(order->resource);
1831                                 ast_free(order);
1832                         }
1833                 }
1834                 AST_LIST_TRAVERSE_SAFE_END;
1835         }
1836
1837         /* we are done with the config now, all the information we need is in the
1838            load_order list */
1839         ast_config_destroy(cfg);
1840
1841         load_count = 0;
1842         AST_LIST_TRAVERSE(&load_order, order, entry)
1843                 load_count++;
1844
1845         if (load_count)
1846                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1847
1848         res = load_resource_list(&load_order, &modulecount);
1849
1850 done:
1851         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1852                 ast_free(order->resource);
1853                 ast_free(order);
1854         }
1855
1856         AST_DLLIST_UNLOCK(&module_list);
1857         return res;
1858 }
1859
1860 void ast_update_use_count(void)
1861 {
1862         /* Notify any module monitors that the use count for a
1863            resource has changed */
1864         struct loadupdate *m;
1865
1866         AST_LIST_LOCK(&updaters);
1867         AST_LIST_TRAVERSE(&updaters, m, entry)
1868                 m->updater();
1869         AST_LIST_UNLOCK(&updaters);
1870 }
1871
1872 /*!
1873  * \internal
1874  * \brief Build an alpha sorted list of modules.
1875  *
1876  * \param alpha_module_list Pointer to uninitialized module_vector.
1877  *
1878  * This function always initializes alpha_module_list.
1879  *
1880  * \pre module_list must be locked.
1881  */
1882 static int alpha_module_list_create(struct module_vector *alpha_module_list)
1883 {
1884         struct ast_module *cur;
1885
1886         if (AST_VECTOR_INIT(alpha_module_list, 32)) {
1887                 return -1;
1888         }
1889
1890         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1891                 if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
1892                         return -1;
1893                 }
1894         }
1895
1896         return 0;
1897 }
1898
1899 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1900                                            int usecnt, const char *status, const char *like,
1901                                                                                    enum ast_module_support_level support_level),
1902                            const char *like)
1903 {
1904         int total_mod_loaded = 0;
1905         struct module_vector alpha_module_list;
1906
1907         AST_DLLIST_LOCK(&module_list);
1908
1909         if (!alpha_module_list_create(&alpha_module_list)) {
1910                 int idx;
1911
1912                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1913                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1914
1915                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1916                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1917                 }
1918         }
1919
1920         AST_DLLIST_UNLOCK(&module_list);
1921         AST_VECTOR_FREE(&alpha_module_list);
1922
1923         return total_mod_loaded;
1924 }
1925
1926 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
1927                                                 int usecnt, const char *status, const char *like,
1928                                                 enum ast_module_support_level support_level,
1929                                                 void *data),
1930                                 const char *like, void *data)
1931 {
1932         int total_mod_loaded = 0;
1933         struct module_vector alpha_module_list;
1934
1935         AST_DLLIST_LOCK(&module_list);
1936
1937         if (!alpha_module_list_create(&alpha_module_list)) {
1938                 int idx;
1939
1940                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1941                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1942
1943                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1944                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
1945                 }
1946         }
1947
1948         AST_DLLIST_UNLOCK(&module_list);
1949         AST_VECTOR_FREE(&alpha_module_list);
1950
1951         return total_mod_loaded;
1952 }
1953
1954 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
1955                                                      int usecnt, const char *status,
1956                                                      const char *like,
1957                                                      enum ast_module_support_level support_level,
1958                                                      void *data, const char *condition),
1959                                      const char *like, void *data, const char *condition)
1960 {
1961         int conditions_met = 0;
1962         struct module_vector alpha_module_list;
1963
1964         AST_DLLIST_LOCK(&module_list);
1965
1966         if (!alpha_module_list_create(&alpha_module_list)) {
1967                 int idx;
1968
1969                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1970                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1971
1972                         conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
1973                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
1974                                 condition);
1975                 }
1976         }
1977
1978         AST_DLLIST_UNLOCK(&module_list);
1979         AST_VECTOR_FREE(&alpha_module_list);
1980
1981         return conditions_met;
1982 }
1983
1984 /*! \brief Check if module exists */
1985 int ast_module_check(const char *name)
1986 {
1987         struct ast_module *cur;
1988
1989         if (ast_strlen_zero(name))
1990                 return 0;       /* FALSE */
1991
1992         cur = find_resource(name, 1);
1993
1994         return (cur != NULL);
1995 }
1996
1997
1998 int ast_loader_register(int (*v)(void))
1999 {
2000         struct loadupdate *tmp;
2001
2002         if (!(tmp = ast_malloc(sizeof(*tmp))))
2003                 return -1;
2004
2005         tmp->updater = v;
2006         AST_LIST_LOCK(&updaters);
2007         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
2008         AST_LIST_UNLOCK(&updaters);
2009
2010         return 0;
2011 }
2012
2013 int ast_loader_unregister(int (*v)(void))
2014 {
2015         struct loadupdate *cur;
2016
2017         AST_LIST_LOCK(&updaters);
2018         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
2019                 if (cur->updater == v)  {
2020                         AST_LIST_REMOVE_CURRENT(entry);
2021                         break;
2022                 }
2023         }
2024         AST_LIST_TRAVERSE_SAFE_END;
2025         AST_LIST_UNLOCK(&updaters);
2026
2027         return cur ? 0 : -1;
2028 }
2029
2030 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
2031 {
2032         if (!mod) {
2033                 return NULL;
2034         }
2035
2036         if (mod->ref_debug) {
2037                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
2038         }
2039
2040         ast_atomic_fetchadd_int(&mod->usecount, +1);
2041         ast_update_use_count();
2042
2043         return mod;
2044 }
2045
2046 struct ast_module *__ast_module_running_ref(struct ast_module *mod,
2047         const char *file, int line, const char *func)
2048 {
2049         if (!mod || !mod->flags.running) {
2050                 return NULL;
2051         }
2052
2053         return __ast_module_ref(mod, file, line, func);
2054 }
2055
2056 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
2057 {
2058         if (!mod || mod->flags.keepuntilshutdown) {
2059                 return;
2060         }
2061
2062         __ast_module_ref(mod, file, line, func);
2063         mod->flags.keepuntilshutdown = 1;
2064 }
2065
2066 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
2067 {
2068         if (!mod) {
2069                 return;
2070         }
2071
2072         if (mod->ref_debug) {
2073                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
2074         }
2075
2076         ast_atomic_fetchadd_int(&mod->usecount, -1);
2077         ast_update_use_count();
2078 }
2079
2080 const char *support_level_map [] = {
2081         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
2082         [AST_MODULE_SUPPORT_CORE] = "core",
2083         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
2084         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
2085 };
2086
2087 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
2088 {
2089         return support_level_map[support_level];
2090 }