BuildSystem: Remove unused variables.
[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 /* 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 static char *module_load_helper(const char *word, int state)
1040 {
1041         struct ast_module *mod;
1042         int which = 0;
1043         char *name;
1044         char *ret = NULL;
1045         char *editline_ret;
1046         char fullpath[PATH_MAX];
1047         int idx = 0;
1048         /* This is needed to avoid listing modules that are already running. */
1049         AST_VECTOR(, char *) running_modules;
1050
1051         AST_VECTOR_INIT(&running_modules, 200);
1052
1053         AST_DLLIST_LOCK(&module_list);
1054         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1055                 if (mod->flags.running) {
1056                         AST_VECTOR_APPEND(&running_modules, mod->resource);
1057                 }
1058         }
1059
1060         if (word[0] == '/') {
1061                 /* BUGBUG: we should not support this. */
1062                 ast_copy_string(fullpath, word, sizeof(fullpath));
1063         } else {
1064                 snprintf(fullpath, sizeof(fullpath), "%s/%s", ast_config_AST_MODULE_DIR, word);
1065         }
1066
1067         /*
1068          * This is ugly that we keep calling filename_completion_function.
1069          * The only way to avoid this would be to make a copy of the function
1070          * that skips matches found in the running_modules vector.
1071          */
1072         while (!ret && (name = editline_ret = filename_completion_function(fullpath, idx++))) {
1073                 if (word[0] != '/') {
1074                         name += (strlen(ast_config_AST_MODULE_DIR) + 1);
1075                 }
1076
1077                 /* Don't list files that are already loaded! */
1078                 if (!AST_VECTOR_GET_CMP(&running_modules, name, !strcasecmp) && ++which > state) {
1079                         ret = ast_strdup(name);
1080                 }
1081
1082                 ast_std_free(editline_ret);
1083         }
1084
1085         /* Do not clean-up the elements, they belong to module_list. */
1086         AST_VECTOR_FREE(&running_modules);
1087         AST_DLLIST_UNLOCK(&module_list);
1088
1089         return ret;
1090 }
1091
1092 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type)
1093 {
1094         struct ast_module *mod;
1095         int which = 0;
1096         int wordlen = strlen(word);
1097         char *ret = NULL;
1098
1099         if (pos != rpos) {
1100                 return NULL;
1101         }
1102
1103         if (type == AST_MODULE_HELPER_LOAD) {
1104                 return module_load_helper(word, state);
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_FAILURE;
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                 lres = start_resource_attempt(mod, mod_count);
1584                 if (lres == AST_MODULE_LOAD_SUCCESS) {
1585                         /* No missing dependencies, successful. */
1586                         continue;
1587                 }
1588
1589                 if (lres == AST_MODULE_LOAD_FAILURE) {
1590                         ast_log(LOG_ERROR, "Failed to load %s.\n", ast_module_name(mod));
1591                         res = -1;
1592                         break;
1593                 }
1594
1595                 if (lres == AST_MODULE_LOAD_DECLINE) {
1596                         continue;
1597                 }
1598
1599                 res = module_deps_missing_recursive(mod, &missingdeps);
1600                 if (res) {
1601                         break;
1602                 }
1603
1604                 if (!AST_VECTOR_SIZE(&missingdeps)) {
1605                         ast_log(LOG_WARNING, "%s isn't missing any dependencies but still didn't start\n",
1606                                 ast_module_name(mod));
1607                         /* Dependencies were met but the module failed to start. */
1608                         res = -1;
1609                         break;
1610                 }
1611
1612                 ast_debug(1, "%s has %d dependencies\n",
1613                         ast_module_name(mod), (int)AST_VECTOR_SIZE(&missingdeps));
1614                 while (AST_VECTOR_SIZE(&missingdeps)) {
1615                         int didwork = 0;
1616                         int i = 0;
1617
1618                         while (i < AST_VECTOR_SIZE(&missingdeps)) {
1619                                 struct ast_module *dep = AST_VECTOR_GET(&missingdeps, i);
1620
1621                                 ast_debug(1, "%s trying to start %s\n", ast_module_name(mod), ast_module_name(dep));
1622                                 if (!start_resource_attempt(dep, mod_count)) {
1623                                         ast_debug(1, "%s started %s\n", ast_module_name(mod), ast_module_name(dep));
1624                                         AST_VECTOR_REMOVE(&missingdeps, i, 1);
1625                                         AST_VECTOR_REMOVE_CMP_ORDERED(resources, dep,
1626                                                 AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_ELEM_CLEANUP_NOOP);
1627                                         didwork++;
1628                                         continue;
1629                                 }
1630                                 ast_debug(1, "%s failed to start %s\n", ast_module_name(mod), ast_module_name(dep));
1631                                 i++;
1632                         }
1633
1634                         if (!didwork) {
1635                                 break;
1636                         }
1637                 }
1638
1639                 if (AST_VECTOR_SIZE(&missingdeps)) {
1640                         ast_log(LOG_ERROR, "Failed to load %s due to unfilled dependencies.\n",
1641                                 ast_module_name(mod));
1642                         res = -1;
1643                         break;
1644                 }
1645
1646                 res = start_resource_attempt(mod, mod_count);
1647                 if (res) {
1648                         ast_log(LOG_ERROR, "Failed to load %s: %d\n", ast_module_name(mod), res);
1649                         break;
1650                 }
1651         }
1652
1653         AST_VECTOR_FREE(&missingdeps);
1654
1655         return res;
1656 }
1657
1658 /*! loads modules in order by load_pri, updates mod_count
1659         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1660 */
1661 static int load_resource_list(struct load_order *load_order, int *mod_count)
1662 {
1663         struct module_vector module_priorities;
1664         struct load_order_entry *order;
1665         int attempt = 0;
1666         int count = 0;
1667         int res = 0;
1668         int didwork;
1669         int lasttry = 0;
1670
1671         if (AST_VECTOR_INIT(&module_priorities, 500)) {
1672                 ast_log(LOG_ERROR, "Failed to initialize module loader.\n");
1673
1674                 return -1;
1675         }
1676
1677         while (!res) {
1678                 didwork = 0;
1679
1680                 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1681                         enum ast_module_load_result lres;
1682
1683                         /* Suppress log messages unless this is the last pass */
1684                         lres = load_resource(order->resource, !lasttry, &module_priorities, order->required);
1685                         ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);
1686                         switch (lres) {
1687                         case AST_MODULE_LOAD_SUCCESS:
1688                         case AST_MODULE_LOAD_SKIP:
1689                                 /* We're supplying module_priorities so SUCCESS isn't possible but we
1690                                  * still have to test for it.  SKIP is only used when we try to start a
1691                                  * module that is missing dependencies. */
1692                                 break;
1693                         case AST_MODULE_LOAD_DECLINE:
1694                                 break;
1695                         case AST_MODULE_LOAD_FAILURE:
1696                                 /* LOAD_FAILURE only happens for required modules */
1697                                 if (lasttry) {
1698                                         /* This run is just to print errors. */
1699                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1700                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1701                                         res =  -2;
1702                                 }
1703                                 break;
1704                         case AST_MODULE_LOAD_PRIORITY:
1705                                 /* load_resource worked and the module was added to module_priorities */
1706                                 AST_LIST_REMOVE_CURRENT(entry);
1707                                 ast_free(order->resource);
1708                                 ast_free(order);
1709                                 didwork = 1;
1710                                 break;
1711                         }
1712                 }
1713                 AST_LIST_TRAVERSE_SAFE_END;
1714
1715                 if (!didwork) {
1716                         if (lasttry) {
1717                                 break;
1718                         }
1719                         /* We know the next try is going to fail, it's only being performed
1720                          * so we can print errors. */
1721                         lasttry = 1;
1722                 }
1723                 attempt++;
1724         }
1725
1726         if (!res) {
1727                 res = start_resource_list(&module_priorities, &count);
1728         }
1729
1730         if (mod_count) {
1731                 *mod_count += count;
1732         }
1733         AST_VECTOR_FREE(&module_priorities);
1734
1735         return res;
1736 }
1737
1738 int load_modules(unsigned int preload_only)
1739 {
1740         struct ast_config *cfg;
1741         struct load_order_entry *order;
1742         struct ast_variable *v;
1743         unsigned int load_count;
1744         struct load_order load_order;
1745         int res = 0;
1746         struct ast_flags config_flags = { 0 };
1747         int modulecount = 0;
1748         struct dirent *dirent;
1749         DIR *dir;
1750
1751         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1752
1753         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1754
1755         AST_DLLIST_LOCK(&module_list);
1756
1757         /*
1758          * All built-in modules have registered the first time, now it's time to complete
1759          * the registration and add them to the priority list.
1760          */
1761         loader_ready = 1;
1762
1763         while ((resource_being_loaded = AST_DLLIST_REMOVE_HEAD(&builtin_module_list, entry))) {
1764                 /* ast_module_register doesn't finish when first run by built-in modules. */
1765                 ast_module_register(resource_being_loaded->info);
1766         }
1767
1768         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1769         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1770                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1771                 goto done;
1772         }
1773
1774         /* first, find all the modules we have been explicitly requested to load */
1775         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1776                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1777                         add_to_load_order(v->value, &load_order, 0);
1778                 }
1779                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1780                         /* Add the module to the list and make sure it's required */
1781                         add_to_load_order(v->value, &load_order, 1);
1782                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1783                 }
1784         }
1785
1786         /* check if 'autoload' is on */
1787         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1788                 /* if we are allowed to load dynamic modules, scan the directory for
1789                    for all available modules and add them as well */
1790                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1791                         while ((dirent = readdir(dir))) {
1792                                 int ld = strlen(dirent->d_name);
1793
1794                                 /* Must end in .so to load it.  */
1795
1796                                 if (ld < 4)
1797                                         continue;
1798
1799                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1800                                         continue;
1801
1802                                 /* if there is already a module by this name in the module_list,
1803                                    skip this file */
1804                                 if (find_resource(dirent->d_name, 0))
1805                                         continue;
1806
1807                                 add_to_load_order(dirent->d_name, &load_order, 0);
1808                         }
1809
1810                         closedir(dir);
1811                 } else {
1812                         if (!ast_opt_quiet)
1813                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1814                                         ast_config_AST_MODULE_DIR);
1815                 }
1816         }
1817
1818         /* now scan the config for any modules we are prohibited from loading and
1819            remove them from the load order */
1820         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1821                 size_t baselen;
1822
1823                 if (strcasecmp(v->name, "noload")) {
1824                         continue;
1825                 }
1826
1827                 baselen = resource_name_baselen(v->value);
1828                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1829                         if (!resource_name_match(v->value, baselen, order->resource)) {
1830                                 AST_LIST_REMOVE_CURRENT(entry);
1831                                 ast_free(order->resource);
1832                                 ast_free(order);
1833                         }
1834                 }
1835                 AST_LIST_TRAVERSE_SAFE_END;
1836         }
1837
1838         /* we are done with the config now, all the information we need is in the
1839            load_order list */
1840         ast_config_destroy(cfg);
1841
1842         load_count = 0;
1843         AST_LIST_TRAVERSE(&load_order, order, entry)
1844                 load_count++;
1845
1846         if (load_count)
1847                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1848
1849         res = load_resource_list(&load_order, &modulecount);
1850
1851 done:
1852         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1853                 ast_free(order->resource);
1854                 ast_free(order);
1855         }
1856
1857         AST_DLLIST_UNLOCK(&module_list);
1858         return res;
1859 }
1860
1861 void ast_update_use_count(void)
1862 {
1863         /* Notify any module monitors that the use count for a
1864            resource has changed */
1865         struct loadupdate *m;
1866
1867         AST_LIST_LOCK(&updaters);
1868         AST_LIST_TRAVERSE(&updaters, m, entry)
1869                 m->updater();
1870         AST_LIST_UNLOCK(&updaters);
1871 }
1872
1873 /*!
1874  * \internal
1875  * \brief Build an alpha sorted list of modules.
1876  *
1877  * \param alpha_module_list Pointer to uninitialized module_vector.
1878  *
1879  * This function always initializes alpha_module_list.
1880  *
1881  * \pre module_list must be locked.
1882  */
1883 static int alpha_module_list_create(struct module_vector *alpha_module_list)
1884 {
1885         struct ast_module *cur;
1886
1887         if (AST_VECTOR_INIT(alpha_module_list, 32)) {
1888                 return -1;
1889         }
1890
1891         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1892                 if (AST_VECTOR_ADD_SORTED(alpha_module_list, cur, module_vector_strcasecmp)) {
1893                         return -1;
1894                 }
1895         }
1896
1897         return 0;
1898 }
1899
1900 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1901                                            int usecnt, const char *status, const char *like,
1902                                                                                    enum ast_module_support_level support_level),
1903                            const char *like)
1904 {
1905         int total_mod_loaded = 0;
1906         struct module_vector alpha_module_list;
1907
1908         AST_DLLIST_LOCK(&module_list);
1909
1910         if (!alpha_module_list_create(&alpha_module_list)) {
1911                 int idx;
1912
1913                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1914                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1915
1916                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1917                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1918                 }
1919         }
1920
1921         AST_DLLIST_UNLOCK(&module_list);
1922         AST_VECTOR_FREE(&alpha_module_list);
1923
1924         return total_mod_loaded;
1925 }
1926
1927 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
1928                                                 int usecnt, const char *status, const char *like,
1929                                                 enum ast_module_support_level support_level,
1930                                                 void *data),
1931                                 const char *like, void *data)
1932 {
1933         int total_mod_loaded = 0;
1934         struct module_vector alpha_module_list;
1935
1936         AST_DLLIST_LOCK(&module_list);
1937
1938         if (!alpha_module_list_create(&alpha_module_list)) {
1939                 int idx;
1940
1941                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1942                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1943
1944                         total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1945                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
1946                 }
1947         }
1948
1949         AST_DLLIST_UNLOCK(&module_list);
1950         AST_VECTOR_FREE(&alpha_module_list);
1951
1952         return total_mod_loaded;
1953 }
1954
1955 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
1956                                                      int usecnt, const char *status,
1957                                                      const char *like,
1958                                                      enum ast_module_support_level support_level,
1959                                                      void *data, const char *condition),
1960                                      const char *like, void *data, const char *condition)
1961 {
1962         int conditions_met = 0;
1963         struct module_vector alpha_module_list;
1964
1965         AST_DLLIST_LOCK(&module_list);
1966
1967         if (!alpha_module_list_create(&alpha_module_list)) {
1968                 int idx;
1969
1970                 for (idx = 0; idx < AST_VECTOR_SIZE(&alpha_module_list); idx++) {
1971                         struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
1972
1973                         conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
1974                                 cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
1975                                 condition);
1976                 }
1977         }
1978
1979         AST_DLLIST_UNLOCK(&module_list);
1980         AST_VECTOR_FREE(&alpha_module_list);
1981
1982         return conditions_met;
1983 }
1984
1985 /*! \brief Check if module exists */
1986 int ast_module_check(const char *name)
1987 {
1988         struct ast_module *cur;
1989
1990         if (ast_strlen_zero(name))
1991                 return 0;       /* FALSE */
1992
1993         cur = find_resource(name, 1);
1994
1995         return (cur != NULL);
1996 }
1997
1998
1999 int ast_loader_register(int (*v)(void))
2000 {
2001         struct loadupdate *tmp;
2002
2003         if (!(tmp = ast_malloc(sizeof(*tmp))))
2004                 return -1;
2005
2006         tmp->updater = v;
2007         AST_LIST_LOCK(&updaters);
2008         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
2009         AST_LIST_UNLOCK(&updaters);
2010
2011         return 0;
2012 }
2013
2014 int ast_loader_unregister(int (*v)(void))
2015 {
2016         struct loadupdate *cur;
2017
2018         AST_LIST_LOCK(&updaters);
2019         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
2020                 if (cur->updater == v)  {
2021                         AST_LIST_REMOVE_CURRENT(entry);
2022                         break;
2023                 }
2024         }
2025         AST_LIST_TRAVERSE_SAFE_END;
2026         AST_LIST_UNLOCK(&updaters);
2027
2028         return cur ? 0 : -1;
2029 }
2030
2031 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
2032 {
2033         if (!mod) {
2034                 return NULL;
2035         }
2036
2037         if (mod->ref_debug) {
2038                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
2039         }
2040
2041         ast_atomic_fetchadd_int(&mod->usecount, +1);
2042         ast_update_use_count();
2043
2044         return mod;
2045 }
2046
2047 struct ast_module *__ast_module_running_ref(struct ast_module *mod,
2048         const char *file, int line, const char *func)
2049 {
2050         if (!mod || !mod->flags.running) {
2051                 return NULL;
2052         }
2053
2054         return __ast_module_ref(mod, file, line, func);
2055 }
2056
2057 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
2058 {
2059         if (!mod || mod->flags.keepuntilshutdown) {
2060                 return;
2061         }
2062
2063         __ast_module_ref(mod, file, line, func);
2064         mod->flags.keepuntilshutdown = 1;
2065 }
2066
2067 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
2068 {
2069         if (!mod) {
2070                 return;
2071         }
2072
2073         if (mod->ref_debug) {
2074                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
2075         }
2076
2077         ast_atomic_fetchadd_int(&mod->usecount, -1);
2078         ast_update_use_count();
2079 }
2080
2081 const char *support_level_map [] = {
2082         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
2083         [AST_MODULE_SUPPORT_CORE] = "core",
2084         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
2085         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
2086 };
2087
2088 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
2089 {
2090         return support_level_map[support_level];
2091 }