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