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