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          * Or the lazy resolution of a global symbol (very likely, since that is
787          * how we load all of our modules that export global symbols).
788          *
789          * Avoid the temptation of repeating the dlclose(). The other code that
790          * dlopened the module still has its module reference, and should close
791          * it itself. In other situations, dlclose() will happily return success
792          * for as many times as you wish to call it.
793          */
794 #if defined(HAVE_RTLD_NOLOAD)
795         if (is_module_loaded(name)) {
796                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
797         }
798 #endif
799 }
800
801 /*!
802  * \internal
803  * \brief Attempt to dlopen a module.
804  *
805  * \param resource_in The module name to load.
806  * \param so_ext ".so" or blank if ".so" is already part of resource_in.
807  * \param filename Passed directly to dlopen.
808  * \param flags Passed directly to dlopen.
809  * \param suppress_logging Do not log any error from dlopen.
810  *
811  * \return Pointer to opened module, NULL on error.
812  *
813  * \warning module_list must be locked before calling this function.
814  */
815 static struct ast_module *load_dlopen(const char *resource_in, const char *so_ext,
816         const char *filename, int flags, unsigned int suppress_logging)
817 {
818         struct ast_module *mod;
819
820         ast_assert(!resource_being_loaded);
821
822         mod = ast_calloc(1, sizeof(*mod) + strlen(resource_in) + strlen(so_ext) + 1);
823         if (!mod) {
824                 return NULL;
825         }
826
827         sprintf(mod->resource, "%s%s", resource_in, so_ext); /* safe */
828
829         resource_being_loaded = mod;
830         mod->lib = dlopen(filename, flags);
831         if (resource_being_loaded) {
832                 resource_being_loaded = NULL;
833                 if (mod->lib) {
834                         ast_log(LOG_ERROR, "Module '%s' did not register itself during load\n", resource_in);
835                         logged_dlclose(resource_in, mod->lib);
836                 } else if (!suppress_logging) {
837                         ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
838                 }
839                 ast_free(mod);
840
841                 return NULL;
842         }
843
844         return mod;
845 }
846
847 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int suppress_logging)
848 {
849         char fn[PATH_MAX];
850         struct ast_module *mod;
851         size_t resource_in_len = strlen(resource_in);
852         const char *so_ext = "";
853
854         if (resource_in_len < 4 || strcasecmp(resource_in + resource_in_len - 3, ".so")) {
855                 so_ext = ".so";
856         }
857
858         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, so_ext);
859
860         /* Try loading in quiet mode first with RTLD_LOCAL.  The majority of modules do not
861          * export symbols so this allows the least number of calls to dlopen. */
862         mod = load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_LOCAL, suppress_logging);
863
864         if (!mod || !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) {
865                 return mod;
866         }
867
868         /* Close the module so we can reopen with correct flags. */
869         logged_dlclose(resource_in, mod->lib);
870
871         return load_dlopen(resource_in, so_ext, fn, RTLD_NOW | RTLD_GLOBAL, 0);
872 }
873
874 int modules_shutdown(void)
875 {
876         struct ast_module *mod;
877         int somethingchanged = 1, final = 0;
878
879         AST_DLLIST_LOCK(&module_list);
880
881         /*!\note Some resources, like timers, are started up dynamically, and thus
882          * may be still in use, even if all channels are dead.  We must therefore
883          * check the usecount before asking modules to unload. */
884         do {
885                 if (!somethingchanged) {
886                         /*!\note If we go through the entire list without changing
887                          * anything, ignore the usecounts and unload, then exit. */
888                         final = 1;
889                 }
890
891                 /* Reset flag before traversing the list */
892                 somethingchanged = 0;
893
894                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
895                         if (!final && mod->usecount) {
896                                 ast_debug(1, "Passing on %s: its use count is %d\n",
897                                         mod->resource, mod->usecount);
898                                 continue;
899                         }
900                         AST_DLLIST_REMOVE_CURRENT(entry);
901                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
902                                 ast_verb(1, "Unloading %s\n", mod->resource);
903                                 mod->info->unload();
904                         }
905                         module_destroy(mod);
906                         somethingchanged = 1;
907                 }
908                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
909                 if (!somethingchanged) {
910                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
911                                 if (mod->flags.keepuntilshutdown) {
912                                         ast_module_unref(mod);
913                                         mod->flags.keepuntilshutdown = 0;
914                                         somethingchanged = 1;
915                                 }
916                         }
917                 }
918         } while (somethingchanged && !final);
919
920         final = AST_DLLIST_EMPTY(&module_list);
921         AST_DLLIST_UNLOCK(&module_list);
922
923         return !final;
924 }
925
926 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
927 {
928         struct ast_module *mod;
929         int res = -1;
930         int error = 0;
931
932         AST_DLLIST_LOCK(&module_list);
933
934         if (!(mod = find_resource(resource_name, 0))) {
935                 AST_DLLIST_UNLOCK(&module_list);
936                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
937                 return -1;
938         }
939
940         if (!mod->flags.running || mod->flags.declined) {
941                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
942                 error = 1;
943         }
944
945         if (!error && (mod->usecount > 0)) {
946                 if (force)
947                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
948                                 resource_name, mod->usecount);
949                 else {
950                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
951                                 mod->usecount);
952                         error = 1;
953                 }
954         }
955
956         if (!error) {
957                 /* Request any channels attached to the module to hangup. */
958                 __ast_module_user_hangup_all(mod);
959
960                 ast_verb(1, "Unloading %s\n", mod->resource);
961                 res = mod->info->unload();
962                 if (res) {
963                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
964                         if (force <= AST_FORCE_FIRM) {
965                                 error = 1;
966                         } else {
967                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
968                         }
969                 }
970
971                 if (!error) {
972                         /*
973                          * Request hangup on any channels that managed to get attached
974                          * while we called the module unload function.
975                          */
976                         __ast_module_user_hangup_all(mod);
977                         sched_yield();
978                 }
979         }
980
981         if (!error)
982                 mod->flags.running = mod->flags.declined = 0;
983
984         AST_DLLIST_UNLOCK(&module_list);
985
986         if (!error) {
987                 unload_dynamic_module(mod);
988                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
989                 ast_update_use_count();
990         }
991
992         return res;
993 }
994
995 static int module_matches_helper_type(struct ast_module *mod, enum ast_module_helper_type type)
996 {
997         switch (type) {
998         case AST_MODULE_HELPER_UNLOAD:
999                 return !mod->usecount && mod->flags.running && !mod->flags.declined;
1000
1001         case AST_MODULE_HELPER_RELOAD:
1002                 return mod->flags.running && mod->info->reload;
1003
1004         case AST_MODULE_HELPER_RUNNING:
1005                 return mod->flags.running;
1006
1007         case AST_MODULE_HELPER_LOADED:
1008                 /* if we have a 'struct ast_module' then we're loaded. */
1009                 return 1;
1010         default:
1011                 /* This function is not called for AST_MODULE_HELPER_LOAD. */
1012                 /* Unknown ast_module_helper_type. Assume it doesn't match. */
1013                 ast_assert(0);
1014
1015                 return 0;
1016         }
1017 }
1018
1019 static char *module_load_helper(const char *word, int state)
1020 {
1021         struct ast_module *mod;
1022         int which = 0;
1023         char *name;
1024         char *ret = NULL;
1025         char *editline_ret;
1026         char fullpath[PATH_MAX];
1027         int idx = 0;
1028         /* This is needed to avoid listing modules that are already running. */
1029         AST_VECTOR(, char *) running_modules;
1030
1031         AST_VECTOR_INIT(&running_modules, 200);
1032
1033         AST_DLLIST_LOCK(&module_list);
1034         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1035                 if (mod->flags.running) {
1036                         AST_VECTOR_APPEND(&running_modules, mod->resource);
1037                 }
1038         }
1039
1040         if (word[0] == '/') {
1041                 /* BUGBUG: we should not support this. */
1042                 ast_copy_string(fullpath, word, sizeof(fullpath));
1043         } else {
1044                 snprintf(fullpath, sizeof(fullpath), "%s/%s", ast_config_AST_MODULE_DIR, word);
1045         }
1046
1047         /*
1048          * This is ugly that we keep calling filename_completion_function.
1049          * The only way to avoid this would be to make a copy of the function
1050          * that skips matches found in the running_modules vector.
1051          */
1052         while (!ret && (name = editline_ret = filename_completion_function(fullpath, idx++))) {
1053                 if (word[0] != '/') {
1054                         name += (strlen(ast_config_AST_MODULE_DIR) + 1);
1055                 }
1056
1057                 /* Don't list files that are already loaded! */
1058                 if (!AST_VECTOR_GET_CMP(&running_modules, name, !strcasecmp) && ++which > state) {
1059                         ret = ast_strdup(name);
1060                 }
1061
1062                 ast_std_free(editline_ret);
1063         }
1064
1065         /* Do not clean-up the elements, they belong to module_list. */
1066         AST_VECTOR_FREE(&running_modules);
1067         AST_DLLIST_UNLOCK(&module_list);
1068
1069         return ret;
1070 }
1071
1072 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
1073 {
1074         struct ast_module *mod;
1075         int which = 0;
1076         int wordlen = strlen(word);
1077         char *ret = NULL;
1078
1079         if (pos != rpos) {
1080                 return NULL;
1081         }
1082
1083         if (type == AST_MODULE_HELPER_LOAD) {
1084                 return module_load_helper(word, state);
1085         }
1086
1087         if (type == AST_MODULE_HELPER_RELOAD) {
1088                 int idx;
1089
1090                 for (idx = 0; reload_classes[idx].name; idx++) {
1091                         if (!strncasecmp(word, reload_classes[idx].name, wordlen) && ++which > state) {
1092                                 return ast_strdup(reload_classes[idx].name);
1093                         }
1094                 }
1095         }
1096
1097         AST_DLLIST_LOCK(&module_list);
1098         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1099                 if (!module_matches_helper_type(mod, type)) {
1100                         continue;
1101                 }
1102
1103                 if (!strncasecmp(word, mod->resource, wordlen) && ++which > state) {
1104                         ret = ast_strdup(mod->resource);
1105                         break;
1106                 }
1107         }
1108         AST_DLLIST_UNLOCK(&module_list);
1109
1110         return ret;
1111 }
1112
1113 void ast_process_pending_reloads(void)
1114 {
1115         struct reload_queue_item *item;
1116
1117         modules_loaded = 1;
1118
1119         AST_LIST_LOCK(&reload_queue);
1120
1121         if (do_full_reload) {
1122                 do_full_reload = 0;
1123                 AST_LIST_UNLOCK(&reload_queue);
1124                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
1125                 ast_module_reload(NULL);
1126                 return;
1127         }
1128
1129         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1130                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
1131                 ast_module_reload(item->module);
1132                 ast_free(item);
1133         }
1134
1135         AST_LIST_UNLOCK(&reload_queue);
1136 }
1137
1138 static void queue_reload_request(const char *module)
1139 {
1140         struct reload_queue_item *item;
1141
1142         AST_LIST_LOCK(&reload_queue);
1143
1144         if (do_full_reload) {
1145                 AST_LIST_UNLOCK(&reload_queue);
1146                 return;
1147         }
1148
1149         if (ast_strlen_zero(module)) {
1150                 /* A full reload request (when module is NULL) wipes out any previous
1151                    reload requests and causes the queue to ignore future ones */
1152                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
1153                         ast_free(item);
1154                 }
1155                 do_full_reload = 1;
1156         } else {
1157                 /* No reason to add the same module twice */
1158                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
1159                         if (!strcasecmp(item->module, module)) {
1160                                 AST_LIST_UNLOCK(&reload_queue);
1161                                 return;
1162                         }
1163                 }
1164                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
1165                 if (!item) {
1166                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
1167                         AST_LIST_UNLOCK(&reload_queue);
1168                         return;
1169                 }
1170                 strcpy(item->module, module);
1171                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
1172         }
1173         AST_LIST_UNLOCK(&reload_queue);
1174 }
1175
1176 /*!
1177  * \since 12
1178  * \internal
1179  * \brief Publish a \ref stasis message regarding the reload result
1180  */
1181 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
1182 {
1183         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1184         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
1185         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
1186         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
1187         char res_buffer[8];
1188
1189         if (!ast_manager_get_generic_type()) {
1190                 return;
1191         }
1192
1193         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
1194         event_object = ast_json_pack("{s: s, s: s}",
1195                         "Module", S_OR(name, "All"),
1196                         "Status", res_buffer);
1197         json_object = ast_json_pack("{s: s, s: i, s: o}",
1198                         "type", "Reload",
1199                         "class_type", EVENT_FLAG_SYSTEM,
1200                         "event", ast_json_ref(event_object));
1201
1202         if (!json_object) {
1203                 return;
1204         }
1205
1206         payload = ast_json_payload_create(json_object);
1207         if (!payload) {
1208                 return;
1209         }
1210
1211         message = stasis_message_create(ast_manager_get_generic_type(), payload);
1212         if (!message) {
1213                 return;
1214         }
1215
1216         stasis_publish(ast_manager_get_topic(), message);
1217 }
1218
1219 enum ast_module_reload_result ast_module_reload(const char *name)
1220 {
1221         struct ast_module *cur;
1222         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
1223         int i;
1224         size_t name_baselen = name ? resource_name_baselen(name) : 0;
1225
1226         /* If we aren't fully booted, we just pretend we reloaded but we queue this
1227            up to run once we are booted up. */
1228         if (!modules_loaded) {
1229                 queue_reload_request(name);
1230                 res = AST_MODULE_RELOAD_QUEUED;
1231                 goto module_reload_exit;
1232         }
1233
1234         if (ast_mutex_trylock(&reloadlock)) {
1235                 ast_verb(3, "The previous reload command didn't finish yet\n");
1236                 res = AST_MODULE_RELOAD_IN_PROGRESS;
1237                 goto module_reload_exit;
1238         }
1239         ast_sd_notify("RELOAD=1");
1240         ast_lastreloadtime = ast_tvnow();
1241
1242         if (ast_opt_lock_confdir) {
1243                 int try;
1244                 int res;
1245                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
1246                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
1247                         if (res == AST_LOCK_TIMEOUT) {
1248                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
1249                         }
1250                 }
1251                 if (res != AST_LOCK_SUCCESS) {
1252                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
1253                         res = AST_MODULE_RELOAD_ERROR;
1254                         goto module_reload_done;
1255                 }
1256         }
1257
1258         /* Call "predefined" reload here first */
1259         for (i = 0; reload_classes[i].name; i++) {
1260                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
1261                         if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
1262                                 res = AST_MODULE_RELOAD_SUCCESS;
1263                         }
1264                 }
1265         }
1266
1267         if (name && res == AST_MODULE_RELOAD_SUCCESS) {
1268                 if (ast_opt_lock_confdir) {
1269                         ast_unlock_path(ast_config_AST_CONFIG_DIR);
1270                 }
1271                 goto module_reload_done;
1272         }
1273
1274         AST_DLLIST_LOCK(&module_list);
1275         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1276                 const struct ast_module_info *info = cur->info;
1277
1278                 if (name && resource_name_match(name, name_baselen, cur->resource)) {
1279                         continue;
1280                 }
1281
1282                 if (!cur->flags.running || cur->flags.declined) {
1283                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1284                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
1285                         }
1286                         if (!name) {
1287                                 continue;
1288                         }
1289                         break;
1290                 }
1291
1292                 if (!info->reload) {    /* cannot be reloaded */
1293                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
1294                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
1295                         }
1296                         if (!name) {
1297                                 continue;
1298                         }
1299                         break;
1300                 }
1301                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
1302                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
1303                         res = AST_MODULE_RELOAD_SUCCESS;
1304                 }
1305                 if (name) {
1306                         break;
1307                 }
1308         }
1309         AST_DLLIST_UNLOCK(&module_list);
1310
1311         if (ast_opt_lock_confdir) {
1312                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
1313         }
1314 module_reload_done:
1315         ast_mutex_unlock(&reloadlock);
1316         ast_sd_notify("READY=1");
1317
1318 module_reload_exit:
1319         publish_reload_message(name, res);
1320         return res;
1321 }
1322
1323 static unsigned int inspect_module(const struct ast_module *mod)
1324 {
1325         if (!mod->info->description) {
1326                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
1327                 return 1;
1328         }
1329
1330         if (!mod->info->key) {
1331                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
1332                 return 1;
1333         }
1334
1335         if (verify_key((unsigned char *) mod->info->key)) {
1336                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
1337                 return 1;
1338         }
1339
1340         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
1341             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
1342                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
1343                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
1344                 return 1;
1345         }
1346
1347         return 0;
1348 }
1349
1350 static enum ast_module_load_result start_resource(struct ast_module *mod)
1351 {
1352         char tmp[256];
1353         enum ast_module_load_result res;
1354
1355         if (mod->flags.running) {
1356                 return AST_MODULE_LOAD_SUCCESS;
1357         }
1358
1359         if (!mod->info->load) {
1360                 return AST_MODULE_LOAD_FAILURE;
1361         }
1362
1363         if (module_deps_reference(mod, NULL)) {
1364                 struct module_vector missing;
1365                 int i;
1366
1367                 AST_VECTOR_INIT(&missing, 0);
1368                 if (module_deps_missing_recursive(mod, &missing)) {
1369                         ast_log(LOG_ERROR, "%s has one or more unknown dependencies.\n", mod->info->name);
1370                 }
1371                 for (i = 0; i < AST_VECTOR_SIZE(&missing); i++) {
1372                         ast_log(LOG_ERROR, "%s loaded before dependency %s!\n", mod->info->name,
1373                                 AST_VECTOR_GET(&missing, i)->info->name);
1374                 }
1375                 AST_VECTOR_FREE(&missing);
1376
1377                 return AST_MODULE_LOAD_FAILURE;
1378         }
1379
1380         if (!ast_fully_booted) {
1381                 ast_verb(1, "Loading %s.\n", mod->resource);
1382         }
1383         res = mod->info->load();
1384
1385         switch (res) {
1386         case AST_MODULE_LOAD_SUCCESS:
1387                 if (!ast_fully_booted) {
1388                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1389                 } else {
1390                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1391                 }
1392
1393                 mod->flags.running = 1;
1394
1395                 ast_update_use_count();
1396                 break;
1397         case AST_MODULE_LOAD_DECLINE:
1398                 mod->flags.declined = 1;
1399                 break;
1400         case AST_MODULE_LOAD_FAILURE:
1401         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1402         case AST_MODULE_LOAD_PRIORITY:
1403                 break;
1404         }
1405
1406         /* Make sure the newly started module is at the end of the list */
1407         AST_DLLIST_LOCK(&module_list);
1408         AST_DLLIST_REMOVE(&module_list, mod, entry);
1409         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1410         AST_DLLIST_UNLOCK(&module_list);
1411
1412         return res;
1413 }
1414
1415 /*! loads a resource based upon resource_name. If global_symbols_only is set
1416  *  only modules with global symbols will be loaded.
1417  *
1418  *  If the module_vector is provided (not NULL) the module is found and added to the
1419  *  vector without running the module's load() function.  By doing this, modules
1420  *  can be initialized later in order by priority and dependencies.
1421  *
1422  *  If the module_vector is not provided, the module's load function will be executed
1423  *  immediately */
1424 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging, struct module_vector *resource_heap, int required)
1425 {
1426         struct ast_module *mod;
1427         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1428
1429         if ((mod = find_resource(resource_name, 0))) {
1430                 if (mod->flags.running) {
1431                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
1432                         return AST_MODULE_LOAD_DECLINE;
1433                 }
1434         } else {
1435                 mod = load_dynamic_module(resource_name, suppress_logging);
1436                 if (!mod) {
1437                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1438                 }
1439
1440                 /* Split lists from mod->info. */
1441                 res  = ast_vector_string_split(&mod->requires, mod->info->requires, ",", 0, strcasecmp);
1442                 res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp);
1443                 res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp);
1444                 if (res) {
1445                         ast_log(LOG_WARNING, "Failed to initialize dependency structures for module '%s'.\n", resource_name);
1446                         unload_dynamic_module(mod);
1447
1448                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1449                 }
1450         }
1451
1452         if (inspect_module(mod)) {
1453                 goto prestart_error;
1454         }
1455
1456         mod->flags.declined = 0;
1457
1458         if (resource_heap) {
1459                 if (AST_VECTOR_ADD_SORTED(resource_heap, mod, module_vector_cmp)) {
1460                         goto prestart_error;
1461                 }
1462                 res = AST_MODULE_LOAD_PRIORITY;
1463         } else {
1464                 res = start_resource(mod);
1465         }
1466
1467         return res;
1468
1469 prestart_error:
1470         ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1471         unload_dynamic_module(mod);
1472         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1473 }
1474
1475 int ast_load_resource(const char *resource_name)
1476 {
1477         int res;
1478         AST_DLLIST_LOCK(&module_list);
1479         res = load_resource(resource_name, 0, NULL, 0);
1480         if (!res) {
1481                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1482         }
1483         AST_DLLIST_UNLOCK(&module_list);
1484
1485         return res;
1486 }
1487
1488 struct load_order_entry {
1489         char *resource;
1490         int required;
1491         AST_LIST_ENTRY(load_order_entry) entry;
1492 };
1493
1494 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1495
1496 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
1497 {
1498         struct load_order_entry *order;
1499         size_t resource_baselen = resource_name_baselen(resource);
1500
1501         AST_LIST_TRAVERSE(load_order, order, entry) {
1502                 if (!resource_name_match(resource, resource_baselen, order->resource)) {
1503                         /* Make sure we have the proper setting for the required field
1504                            (we might have both load= and required= lines in modules.conf) */
1505                         order->required |= required;
1506                         return NULL;
1507                 }
1508         }
1509
1510         if (!(order = ast_calloc(1, sizeof(*order))))
1511                 return NULL;
1512
1513         order->resource = ast_strdup(resource);
1514         order->required = required;
1515         AST_LIST_INSERT_TAIL(load_order, order, entry);
1516
1517         return order;
1518 }
1519
1520 AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
1521
1522 static enum ast_module_load_result start_resource_attempt(struct ast_module *mod, int *count)
1523 {
1524         enum ast_module_load_result lres;
1525
1526         /* Try to grab required references. */
1527         if (module_deps_reference(mod, NULL)) {
1528                 /* We're likely to retry so not an error. */
1529                 ast_debug(1, "Module %s is missing dependencies\n", mod->resource);
1530                 return AST_MODULE_LOAD_SKIP;
1531         }
1532
1533         lres = start_resource(mod);
1534         ast_debug(3, "START: %-46s[%d] %d\n",
1535                 mod->resource,
1536                 ast_test_flag(mod->info, AST_MODFLAG_LOAD_ORDER) ? mod->info->load_pri : AST_MODPRI_DEFAULT,
1537                 lres);
1538
1539         if (lres == AST_MODULE_LOAD_SUCCESS) {
1540                 (*count)++;
1541         } else if (lres == AST_MODULE_LOAD_FAILURE) {
1542                 ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
1543         }
1544
1545         return lres;
1546 }
1547
1548 static int start_resource_list(struct module_vector *resources, int *mod_count)
1549 {
1550         struct module_vector missingdeps;
1551         int res = 0;
1552
1553         AST_VECTOR_INIT(&missingdeps, 0);
1554         while (AST_VECTOR_SIZE(resources)) {
1555                 struct ast_module *mod = AST_VECTOR_REMOVE(resources, 0, 1);
1556                 enum ast_module_load_result lres;
1557
1558                 lres = start_resource_attempt(mod, mod_count);
1559                 if (lres == AST_MODULE_LOAD_SUCCESS) {
1560                         /* No missing dependencies, successful. */
1561                         continue;
1562                 }
1563
1564                 if (lres == AST_MODULE_LOAD_FAILURE) {
1565                         ast_log(LOG_ERROR, "Failed to load %s.\n", ast_module_name(mod));
1566                         res = -1;
1567                         break;
1568                 }
1569
1570                 if (lres == AST_MODULE_LOAD_DECLINE) {
1571                         continue;
1572                 }
1573
1574                 res = module_deps_missing_recursive(mod, &missingdeps);
1575                 if (res) {
1576                         break;
1577                 }
1578
1579                 if (!AST_VECTOR_SIZE(&missingdeps)) {
1580                         ast_log(LOG_WARNING, "%s isn't missing any dependencies but still didn't start\n",
1581                                 ast_module_name(mod));
1582                         /* Dependencies were met but the module failed to start. */
1583                         res = -1;
1584                         break;
1585                 }
1586
1587                 ast_debug(1, "%s has %d dependencies\n",
1588                         ast_module_name(mod), (int)AST_VECTOR_SIZE(&missingdeps));
1589                 while (AST_VECTOR_SIZE(&missingdeps)) {
1590                         int didwork = 0;
1591                         int i = 0;
1592
1593                         while (i < AST_VECTOR_SIZE(&missingdeps)) {
1594                                 struct ast_module *dep = AST_VECTOR_GET(&missingdeps, i);
1595
1596                                 ast_debug(1, "%s trying to start %s\n", ast_module_name(mod), ast_module_name(dep));
1597                                 if (!start_resource_attempt(dep, mod_count)) {
1598                                         ast_debug(1, "%s started %s\n", ast_module_name(mod), ast_module_name(dep));
1599                                         AST_VECTOR_REMOVE(&missingdeps, i, 1);
1600                                         AST_VECTOR_REMOVE_CMP_ORDERED(resources, dep,
1601                                                 AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_ELEM_CLEANUP_NOOP);
1602                                         didwork++;
1603                                         continue;
1604                                 }
1605                                 ast_debug(1, "%s failed to start %s\n", ast_module_name(mod), ast_module_name(dep));
1606                                 i++;
1607                         }
1608
1609                         if (!didwork) {
1610                                 break;
1611                         }
1612                 }
1613
1614                 if (AST_VECTOR_SIZE(&missingdeps)) {
1615                         ast_log(LOG_ERROR, "Failed to load %s due to unfilled dependencies.\n",
1616                                 ast_module_name(mod));
1617                         res = -1;
1618                         break;
1619                 }
1620
1621                 res = start_resource_attempt(mod, mod_count);
1622                 if (res) {
1623                         ast_log(LOG_ERROR, "Failed to load %s: %d\n", ast_module_name(mod), res);
1624                         break;
1625                 }
1626         }
1627
1628         AST_VECTOR_FREE(&missingdeps);
1629
1630         return res;
1631 }
1632
1633 /*! loads modules in order by load_pri, updates mod_count
1634         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1635 */
1636 static int load_resource_list(struct load_order *load_order, int *mod_count)
1637 {
1638         struct module_vector resource_heap;
1639         struct load_order_entry *order;
1640         struct load_retries load_retries;
1641         int count = 0;
1642         int res = 0;
1643         int i = 0;
1644 #define LOAD_RETRIES 4
1645
1646         AST_LIST_HEAD_INIT_NOLOCK(&load_retries);
1647
1648         if (AST_VECTOR_INIT(&resource_heap, 500)) {
1649                 ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
1650
1651                 return -1;
1652         }
1653
1654         /* first, add find and add modules to heap */
1655         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1656                 enum ast_module_load_result lres;
1657
1658                 /* Suppress log messages unless this is the last pass */
1659                 lres = load_resource(order->resource, 1, &resource_heap, order->required);
1660                 ast_debug(3, "PASS 0: %-46s %d\n", order->resource, lres);
1661                 switch (lres) {
1662                 case AST_MODULE_LOAD_SUCCESS:
1663                         /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */
1664                         break;
1665                 case AST_MODULE_LOAD_FAILURE:
1666                 case AST_MODULE_LOAD_DECLINE:
1667                         /*
1668                          * DECLINE or FAILURE means there was an issue with dlopen or module_register
1669                          * which might be retryable.  LOAD_FAILURE only happens for required modules
1670                          * but we're still going to retry.  We need to remove the entry from the
1671                          * load_order list and add it to the load_retries list.
1672                          */
1673                         AST_LIST_REMOVE_CURRENT(entry);
1674                         AST_LIST_INSERT_TAIL(&load_retries, order, entry);
1675                         break;
1676                 case AST_MODULE_LOAD_SKIP:
1677                         /*
1678                          * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.
1679                          * Leave it in load_order for the next call of load_resource_list.
1680                          */
1681                         break;
1682                 case AST_MODULE_LOAD_PRIORITY:
1683                         /* load_resource worked and the module was added to the priority vector */
1684                         AST_LIST_REMOVE_CURRENT(entry);
1685                         ast_free(order->resource);
1686                         ast_free(order);
1687                         break;
1688                 }
1689         }
1690         AST_LIST_TRAVERSE_SAFE_END;
1691
1692         /* Retry the failures until the list is empty or we reach LOAD_RETRIES */
1693         for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {
1694                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {
1695                         enum ast_module_load_result lres;
1696
1697                         /* Suppress log messages unless this is the last pass */
1698                         lres = load_resource(order->resource, (i < LOAD_RETRIES - 1), &resource_heap, order->required);
1699                         ast_debug(3, "PASS %d %-46s %d\n", i + 1, order->resource, lres);
1700                         switch (lres) {
1701                         /* These are all retryable. */
1702                         case AST_MODULE_LOAD_SUCCESS:
1703                         case AST_MODULE_LOAD_DECLINE:
1704                                 break;
1705                         case AST_MODULE_LOAD_FAILURE:
1706                                 /* LOAD_FAILURE only happens for required modules */
1707                                 if (i == LOAD_RETRIES - 1) {
1708                                         /* This was the last chance to load a required module*/
1709                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1710                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1711                                         res =  -2;
1712                                         goto done;
1713                                 }
1714                                 break;;
1715                         case AST_MODULE_LOAD_SKIP:
1716                                 /*
1717                                  * SKIP means that dlopen worked but global_symbols was set and this module
1718                                  * doesn't qualify.  Put it back in load_order for the next call of
1719                                  * load_resource_list.
1720                                  */
1721                                 AST_LIST_REMOVE_CURRENT(entry);
1722                                 AST_LIST_INSERT_TAIL(load_order, order, entry);
1723                                 break;
1724                         case AST_MODULE_LOAD_PRIORITY:
1725                                 /* load_resource worked and the module was added to the priority heap */
1726                                 AST_LIST_REMOVE_CURRENT(entry);
1727                                 ast_free(order->resource);
1728                                 ast_free(order);
1729                                 break;
1730                         }
1731                 }
1732                 AST_LIST_TRAVERSE_SAFE_END;
1733         }
1734
1735         res = start_resource_list(&resource_heap, &count);
1736
1737 done:
1738         while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {
1739                 ast_free(order->resource);
1740                 ast_free(order);
1741         }
1742
1743         if (mod_count) {
1744                 *mod_count += count;
1745         }
1746         AST_VECTOR_FREE(&resource_heap);
1747
1748         return res;
1749 }
1750
1751 int load_modules(unsigned int preload_only)
1752 {
1753         struct ast_config *cfg;
1754         struct load_order_entry *order;
1755         struct ast_variable *v;
1756         unsigned int load_count;
1757         struct load_order load_order;
1758         int res = 0;
1759         struct ast_flags config_flags = { 0 };
1760         int modulecount = 0;
1761         struct dirent *dirent;
1762         DIR *dir;
1763
1764         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1765
1766         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1767
1768         AST_DLLIST_LOCK(&module_list);
1769
1770         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1771         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1772                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1773                 goto done;
1774         }
1775
1776         /* first, find all the modules we have been explicitly requested to load */
1777         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1778                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1779                         add_to_load_order(v->value, &load_order, 0);
1780                 }
1781                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1782                         /* Add the module to the list and make sure it's required */
1783                         add_to_load_order(v->value, &load_order, 1);
1784                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1785                 }
1786
1787         }
1788
1789         /* check if 'autoload' is on */
1790         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1791                 /* if we are allowed to load dynamic modules, scan the directory for
1792                    for all available modules and add them as well */
1793                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1794                         while ((dirent = readdir(dir))) {
1795                                 int ld = strlen(dirent->d_name);
1796
1797                                 /* Must end in .so to load it.  */
1798
1799                                 if (ld < 4)
1800                                         continue;
1801
1802                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1803                                         continue;
1804
1805                                 /* if there is already a module by this name in the module_list,
1806                                    skip this file */
1807                                 if (find_resource(dirent->d_name, 0))
1808                                         continue;
1809
1810                                 add_to_load_order(dirent->d_name, &load_order, 0);
1811                         }
1812
1813                         closedir(dir);
1814                 } else {
1815                         if (!ast_opt_quiet)
1816                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1817                                         ast_config_AST_MODULE_DIR);
1818                 }
1819         }
1820
1821         /* now scan the config for any modules we are prohibited from loading and
1822            remove them from the load order */
1823         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1824                 size_t baselen;
1825
1826                 if (strcasecmp(v->name, "noload")) {
1827                         continue;
1828                 }
1829
1830                 baselen = resource_name_baselen(v->value);
1831                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1832                         if (!resource_name_match(v->value, baselen, order->resource)) {
1833                                 AST_LIST_REMOVE_CURRENT(entry);
1834                                 ast_free(order->resource);
1835                                 ast_free(order);
1836                         }
1837                 }
1838                 AST_LIST_TRAVERSE_SAFE_END;
1839         }
1840
1841         /* we are done with the config now, all the information we need is in the
1842            load_order list */
1843         ast_config_destroy(cfg);
1844
1845         load_count = 0;
1846         AST_LIST_TRAVERSE(&load_order, order, entry)
1847                 load_count++;
1848
1849         if (load_count)
1850                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1851
1852         res = load_resource_list(&load_order, &modulecount);
1853
1854 done:
1855         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1856                 ast_free(order->resource);
1857                 ast_free(order);
1858         }
1859
1860         AST_DLLIST_UNLOCK(&module_list);
1861         return res;
1862 }
1863
1864 void ast_update_use_count(void)
1865 {
1866         /* Notify any module monitors that the use count for a
1867            resource has changed */
1868         struct loadupdate *m;
1869
1870         AST_LIST_LOCK(&updaters);
1871         AST_LIST_TRAVERSE(&updaters, m, entry)
1872                 m->updater();
1873         AST_LIST_UNLOCK(&updaters);
1874 }
1875
1876 /*!
1877  * \internal
1878  * \brief Build an alpha sorted list of modules.
1879  *
1880  * \param alpha_module_list Pointer to uninitialized module_vector.
1881  *
1882  * This function always initializes alpha_module_list.
1883  *
1884  * \pre module_list must be locked.
1885  */
1886 static int alpha_module_list_create(struct module_vector *alpha_module_list)
1887 {
1888         struct ast_module *cur;
1889
1890         if (AST_VECTOR_INIT(alpha_module_list, 32)) {
1891                 return -1;
1892         }
1893
1894         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1895                 if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
1896                         return -1;
1897                 }
1898         }
1899
1900         return 0;
1901 }
1902
1903 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1904                                            int usecnt, const char *status, const char *like,
1905                                                                                    enum ast_module_support_level support_level),
1906                            const char *like)
1907 {
1908         int total_mod_loaded = 0;
1909         struct module_vector alpha_module_list;
1910
1911         AST_DLLIST_LOCK(&module_list);
1912
1913         if (!alpha_module_list_create(&alpha_module_list)) {
1914                 int idx;
1915
1916                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1917                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1918
1919                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1920                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1921                 }
1922         }
1923
1924         AST_DLLIST_UNLOCK(&module_list);
1925         AST_VECTOR_FREE(&alpha_module_list);
1926
1927         return total_mod_loaded;
1928 }
1929
1930 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
1931                                                 int usecnt, const char *status, const char *like,
1932                                                 enum ast_module_support_level support_level,
1933                                                 void *data),
1934                                 const char *like, void *data)
1935 {
1936         int total_mod_loaded = 0;
1937         struct module_vector alpha_module_list;
1938
1939         AST_DLLIST_LOCK(&module_list);
1940
1941         if (!alpha_module_list_create(&alpha_module_list)) {
1942                 int idx;
1943
1944                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1945                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1946
1947                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1948                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
1949                 }
1950         }
1951
1952         AST_DLLIST_UNLOCK(&module_list);
1953         AST_VECTOR_FREE(&alpha_module_list);
1954
1955         return total_mod_loaded;
1956 }
1957
1958 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
1959                                                      int usecnt, const char *status,
1960                                                      const char *like,
1961                                                      enum ast_module_support_level support_level,
1962                                                      void *data, const char *condition),
1963                                      const char *like, void *data, const char *condition)
1964 {
1965         int conditions_met = 0;
1966         struct module_vector alpha_module_list;
1967
1968         AST_DLLIST_LOCK(&module_list);
1969
1970         if (!alpha_module_list_create(&alpha_module_list)) {
1971                 int idx;
1972
1973                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1974                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1975
1976                         conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
1977                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
1978                                 condition);
1979                 }
1980         }
1981
1982         AST_DLLIST_UNLOCK(&module_list);
1983         AST_VECTOR_FREE(&alpha_module_list);
1984
1985         return conditions_met;
1986 }
1987
1988 /*! \brief Check if module exists */
1989 int ast_module_check(const char *name)
1990 {
1991         struct ast_module *cur;
1992
1993         if (ast_strlen_zero(name))
1994                 return 0;       /* FALSE */
1995
1996         cur = find_resource(name, 1);
1997
1998         return (cur != NULL);
1999 }
2000
2001
2002 int ast_loader_register(int (*v)(void))
2003 {
2004         struct loadupdate *tmp;
2005
2006         if (!(tmp = ast_malloc(sizeof(*tmp))))
2007                 return -1;
2008
2009         tmp->updater = v;
2010         AST_LIST_LOCK(&updaters);
2011         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
2012         AST_LIST_UNLOCK(&updaters);
2013
2014         return 0;
2015 }
2016
2017 int ast_loader_unregister(int (*v)(void))
2018 {
2019         struct loadupdate *cur;
2020
2021         AST_LIST_LOCK(&updaters);
2022         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
2023                 if (cur->updater == v)  {
2024                         AST_LIST_REMOVE_CURRENT(entry);
2025                         break;
2026                 }
2027         }
2028         AST_LIST_TRAVERSE_SAFE_END;
2029         AST_LIST_UNLOCK(&updaters);
2030
2031         return cur ? 0 : -1;
2032 }
2033
2034 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
2035 {
2036         if (!mod) {
2037                 return NULL;
2038         }
2039
2040         if (mod->ref_debug) {
2041                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
2042         }
2043
2044         ast_atomic_fetchadd_int(&mod->usecount, +1);
2045         ast_update_use_count();
2046
2047         return mod;
2048 }
2049
2050 struct ast_module *__ast_module_running_ref(struct ast_module *mod,
2051         const char *file, int line, const char *func)
2052 {
2053         if (!mod || !mod->flags.running) {
2054                 return NULL;
2055         }
2056
2057         return __ast_module_ref(mod, file, line, func);
2058 }
2059
2060 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
2061 {
2062         if (!mod || mod->flags.keepuntilshutdown) {
2063                 return;
2064         }
2065
2066         __ast_module_ref(mod, file, line, func);
2067         mod->flags.keepuntilshutdown = 1;
2068 }
2069
2070 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
2071 {
2072         if (!mod) {
2073                 return;
2074         }
2075
2076         if (mod->ref_debug) {
2077                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
2078         }
2079
2080         ast_atomic_fetchadd_int(&mod->usecount, -1);
2081         ast_update_use_count();
2082 }
2083
2084 const char *support_level_map [] = {
2085         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
2086         [AST_MODULE_SUPPORT_CORE] = "core",
2087         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
2088         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
2089 };
2090
2091 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
2092 {
2093         return support_level_map[support_level];
2094 }