6617783cf28c6acfd1563d0ddc732ebf4f4faa88
[asterisk/asterisk.git] / main / loader.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  * Kevin P. Fleming <kpfleming@digium.com>
8  * Luigi Rizzo <rizzo@icir.org>
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief Module Loader
24  * \author Mark Spencer <markster@digium.com>
25  * \author Kevin P. Fleming <kpfleming@digium.com>
26  * \author Luigi Rizzo <rizzo@icir.org>
27  * - See ModMngMnt
28  */
29
30 /*** MODULEINFO
31         <support_level>core</support_level>
32  ***/
33
34 #include "asterisk.h"
35
36 #include "asterisk/_private.h"
37 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
38 #include <dirent.h>
39
40 #include "asterisk/dlinkedlists.h"
41 #include "asterisk/module.h"
42 #include "asterisk/config.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/term.h"
45 #include "asterisk/acl.h"
46 #include "asterisk/manager.h"
47 #include "asterisk/cdr.h"
48 #include "asterisk/enum.h"
49 #include "asterisk/http.h"
50 #include "asterisk/lock.h"
51 #include "asterisk/features_config.h"
52 #include "asterisk/dsp.h"
53 #include "asterisk/udptl.h"
54 #include "asterisk/heap.h"
55 #include "asterisk/app.h"
56 #include "asterisk/test.h"
57 #include "asterisk/sounds_index.h"
58
59 #include <dlfcn.h>
60
61 #include "asterisk/md5.h"
62 #include "asterisk/utils.h"
63
64 /*** DOCUMENTATION
65         <managerEvent language="en_US" name="Reload">
66                 <managerEventInstance class="EVENT_FLAG_SYSTEM">
67                         <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis>
68                         <syntax>
69                                 <parameter name="Module">
70                                         <para>The name of the module that was reloaded, or
71                                         <literal>All</literal> if all modules were reloaded</para>
72                                 </parameter>
73                                 <parameter name="Status">
74                                         <para>The numeric status code denoting the success or failure
75                                         of the reload request.</para>
76                                         <enumlist>
77                                                 <enum name="0"><para>Success</para></enum>
78                                                 <enum name="1"><para>Request queued</para></enum>
79                                                 <enum name="2"><para>Module not found</para></enum>
80                                                 <enum name="3"><para>Error</para></enum>
81                                                 <enum name="4"><para>Reload already in progress</para></enum>
82                                                 <enum name="5"><para>Module uninitialized</para></enum>
83                                                 <enum name="6"><para>Reload not supported</para></enum>
84                                         </enumlist>
85                                 </parameter>
86                         </syntax>
87                 </managerEventInstance>
88         </managerEvent>
89  ***/
90
91 #ifndef RTLD_NOW
92 #define RTLD_NOW 0
93 #endif
94
95 #ifndef RTLD_LOCAL
96 #define RTLD_LOCAL 0
97 #endif
98
99 struct ast_module_user {
100         struct ast_channel *chan;
101         AST_LIST_ENTRY(ast_module_user) entry;
102 };
103
104 AST_DLLIST_HEAD(module_user_list, ast_module_user);
105
106 static const unsigned char expected_key[] =
107 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
108   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
109
110 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
111
112 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
113                                       since they are here before we dlopen() any
114                                    */
115
116 /*!
117  * \brief Internal flag to indicate all modules have been initially loaded.
118  */
119 static int modules_loaded;
120
121 struct ast_module {
122         const struct ast_module_info *info;
123         /* Used to get module references into refs log */
124         void *ref_debug;
125         void *lib;                                      /* the shared lib, or NULL if embedded */
126         int usecount;                                   /* the number of 'users' currently in this module */
127         struct module_user_list users;                  /* the list of users in the module */
128         struct {
129                 unsigned int running:1;
130                 unsigned int declined:1;
131                 unsigned int keepuntilshutdown:1;
132         } flags;
133         AST_LIST_ENTRY(ast_module) list_entry;
134         AST_DLLIST_ENTRY(ast_module) entry;
135         char resource[0];
136 };
137
138 static AST_DLLIST_HEAD_STATIC(module_list, ast_module);
139
140 const char *ast_module_name(const struct ast_module *mod)
141 {
142         if (!mod || !mod->info) {
143                 return NULL;
144         }
145
146         return mod->info->name;
147 }
148
149 /*
150  * module_list is cleared by its constructor possibly after
151  * we start accumulating embedded modules, so we need to
152  * use another list (without the lock) to accumulate them.
153  * Then we update the main list when embedding is done.
154  */
155 static struct module_list embedded_module_list;
156
157 struct loadupdate {
158         int (*updater)(void);
159         AST_LIST_ENTRY(loadupdate) entry;
160 };
161
162 static AST_DLLIST_HEAD_STATIC(updaters, loadupdate);
163
164 AST_MUTEX_DEFINE_STATIC(reloadlock);
165
166 struct reload_queue_item {
167         AST_LIST_ENTRY(reload_queue_item) entry;
168         char module[0];
169 };
170
171 static int do_full_reload = 0;
172
173 static AST_DLLIST_HEAD_STATIC(reload_queue, reload_queue_item);
174
175 /* when dynamic modules are being loaded, ast_module_register() will
176    need to know what filename the module was loaded from while it
177    is being registered
178 */
179 static struct ast_module *resource_being_loaded;
180
181 /* XXX: should we check for duplicate resource names here? */
182
183 void ast_module_register(const struct ast_module_info *info)
184 {
185         struct ast_module *mod;
186
187         if (embedding) {
188                 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
189                         return;
190                 strcpy(mod->resource, info->name);
191         } else {
192                 mod = resource_being_loaded;
193         }
194
195         ast_debug(5, "Registering module %s\n", info->name);
196
197         mod->info = info;
198         if (ast_opt_ref_debug) {
199                 mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
200         }
201         AST_LIST_HEAD_INIT(&mod->users);
202
203         /* during startup, before the loader has been initialized,
204            there are no threads, so there is no need to take the lock
205            on this list to manipulate it. it is also possible that it
206            might be unsafe to use the list lock at that point... so
207            let's avoid it altogether
208         */
209         if (embedding) {
210                 AST_DLLIST_INSERT_TAIL(&embedded_module_list, mod, entry);
211         } else {
212                 AST_DLLIST_LOCK(&module_list);
213                 /* it is paramount that the new entry be placed at the tail of
214                    the list, otherwise the code that uses dlopen() to load
215                    dynamic modules won't be able to find out if the module it
216                    just opened was registered or failed to load
217                 */
218                 AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
219                 AST_DLLIST_UNLOCK(&module_list);
220         }
221
222         /* give the module a copy of its own handle, for later use in registrations and the like */
223         *((struct ast_module **) &(info->self)) = mod;
224 }
225
226 void ast_module_unregister(const struct ast_module_info *info)
227 {
228         struct ast_module *mod = NULL;
229
230         /* it is assumed that the users list in the module structure
231            will already be empty, or we cannot have gotten to this
232            point
233         */
234         AST_DLLIST_LOCK(&module_list);
235         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
236                 if (mod->info == info) {
237                         AST_DLLIST_REMOVE_CURRENT(entry);
238                         break;
239                 }
240         }
241         AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
242         AST_DLLIST_UNLOCK(&module_list);
243
244         if (mod) {
245                 ast_debug(5, "Unregistering module %s\n", info->name);
246                 AST_LIST_HEAD_DESTROY(&mod->users);
247                 ao2_cleanup(mod->ref_debug);
248                 ast_free(mod);
249         }
250 }
251
252 struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast_channel *chan)
253 {
254         struct ast_module_user *u;
255
256         u = ast_calloc(1, sizeof(*u));
257         if (!u) {
258                 return NULL;
259         }
260
261         u->chan = chan;
262
263         AST_LIST_LOCK(&mod->users);
264         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
265         AST_LIST_UNLOCK(&mod->users);
266
267         if (mod->ref_debug) {
268                 ao2_ref(mod->ref_debug, +1);
269         }
270
271         ast_atomic_fetchadd_int(&mod->usecount, +1);
272
273         ast_update_use_count();
274
275         return u;
276 }
277
278 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
279 {
280         if (!u) {
281                 return;
282         }
283
284         AST_LIST_LOCK(&mod->users);
285         u = AST_LIST_REMOVE(&mod->users, u, entry);
286         AST_LIST_UNLOCK(&mod->users);
287         if (!u) {
288                 /*
289                  * Was not in the list.  Either a bad pointer or
290                  * __ast_module_user_hangup_all() has been called.
291                  */
292                 return;
293         }
294
295         if (mod->ref_debug) {
296                 ao2_ref(mod->ref_debug, -1);
297         }
298
299         ast_atomic_fetchadd_int(&mod->usecount, -1);
300         ast_free(u);
301
302         ast_update_use_count();
303 }
304
305 void __ast_module_user_hangup_all(struct ast_module *mod)
306 {
307         struct ast_module_user *u;
308
309         AST_LIST_LOCK(&mod->users);
310         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
311                 if (u->chan) {
312                         ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
313                 }
314
315                 if (mod->ref_debug) {
316                         ao2_ref(mod->ref_debug, -1);
317                 }
318
319                 ast_atomic_fetchadd_int(&mod->usecount, -1);
320                 ast_free(u);
321         }
322         AST_LIST_UNLOCK(&mod->users);
323
324         ast_update_use_count();
325 }
326
327 /*! \note
328  * In addition to modules, the reload command handles some extra keywords
329  * which are listed here together with the corresponding handlers.
330  * This table is also used by the command completion code.
331  */
332 static struct reload_classes {
333         const char *name;
334         int (*reload_fn)(void);
335 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
336         { "acl",         ast_named_acl_reload },
337         { "cdr",         ast_cdr_engine_reload },
338         { "cel",         ast_cel_engine_reload },
339         { "dnsmgr",      dnsmgr_reload },
340         { "dsp",         ast_dsp_reload},
341         { "extconfig",   read_config_maps },
342         { "enum",        ast_enum_reload },
343         { "features",    ast_features_config_reload },
344         { "http",        ast_http_reload },
345         { "indications", ast_indications_reload },
346         { "logger",      logger_reload },
347         { "manager",     reload_manager },
348         { "plc",         ast_plc_reload },
349         { "sounds",      ast_sounds_reindex },
350         { "udptl",       ast_udptl_reload },
351         { NULL,          NULL }
352 };
353
354 static int printdigest(const unsigned char *d)
355 {
356         int x, pos;
357         char buf[256]; /* large enough so we don't have to worry */
358
359         for (pos = 0, x = 0; x < 16; x++)
360                 pos += sprintf(buf + pos, " %02hhx", *d++);
361
362         ast_debug(1, "Unexpected signature:%s\n", buf);
363
364         return 0;
365 }
366
367 static int key_matches(const unsigned char *key1, const unsigned char *key2)
368 {
369         int x;
370
371         for (x = 0; x < 16; x++) {
372                 if (key1[x] != key2[x])
373                         return 0;
374         }
375
376         return 1;
377 }
378
379 static int verify_key(const unsigned char *key)
380 {
381         struct MD5Context c;
382         unsigned char digest[16];
383
384         MD5Init(&c);
385         MD5Update(&c, key, strlen((char *)key));
386         MD5Final(digest, &c);
387
388         if (key_matches(expected_key, digest))
389                 return 0;
390
391         printdigest(digest);
392
393         return -1;
394 }
395
396 static int resource_name_match(const char *name1_in, const char *name2_in)
397 {
398         char *name1 = (char *) name1_in;
399         char *name2 = (char *) name2_in;
400
401         /* trim off any .so extensions */
402         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
403                 name1 = ast_strdupa(name1);
404                 name1[strlen(name1) - 3] = '\0';
405         }
406         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
407                 name2 = ast_strdupa(name2);
408                 name2[strlen(name2) - 3] = '\0';
409         }
410
411         return strcasecmp(name1, name2);
412 }
413
414 static struct ast_module *find_resource(const char *resource, int do_lock)
415 {
416         struct ast_module *cur;
417
418         if (do_lock) {
419                 AST_DLLIST_LOCK(&module_list);
420         }
421
422         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
423                 if (!resource_name_match(resource, cur->resource))
424                         break;
425         }
426
427         if (do_lock) {
428                 AST_DLLIST_UNLOCK(&module_list);
429         }
430
431         return cur;
432 }
433
434 #ifdef LOADABLE_MODULES
435
436 /*!
437  * \brief dlclose(), with failure logging.
438  */
439 static void logged_dlclose(const char *name, void *lib)
440 {
441         char *error;
442
443         if (!lib) {
444                 return;
445         }
446
447         /* Clear any existing error */
448         dlerror();
449         if (dlclose(lib)) {
450                 error = dlerror();
451                 ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
452                         S_OR(name, "unknown"), S_OR(error, "Unknown error"));
453         }
454 }
455
456 #if defined(HAVE_RTLD_NOLOAD)
457 /*!
458  * \brief Check to see if the given resource is loaded.
459  *
460  * \param resource_name Name of the resource, including .so suffix.
461  * \return False (0) if module is not loaded.
462  * \return True (non-zero) if module is loaded.
463  */
464 static int is_module_loaded(const char *resource_name)
465 {
466         char fn[PATH_MAX] = "";
467         void *lib;
468
469         snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_MODULE_DIR,
470                 resource_name);
471
472         lib = dlopen(fn, RTLD_LAZY | RTLD_NOLOAD);
473
474         if (lib) {
475                 logged_dlclose(resource_name, lib);
476                 return 1;
477         }
478
479         return 0;
480 }
481 #endif
482
483 static void unload_dynamic_module(struct ast_module *mod)
484 {
485 #if defined(HAVE_RTLD_NOLOAD)
486         char *name = ast_strdupa(ast_module_name(mod));
487 #endif
488         void *lib = mod->lib;
489
490         /* WARNING: the structure pointed to by mod is going to
491            disappear when this operation succeeds, so we can't
492            dereference it */
493         logged_dlclose(ast_module_name(mod), lib);
494
495         /* There are several situations where the module might still be resident
496          * in memory.
497          *
498          * If somehow there was another dlopen() on the same module (unlikely,
499          * since that all is supposed to happen in loader.c).
500          *
501          * Or the lazy resolution of a global symbol (very likely, since that is
502          * how we load all of our modules that export global symbols).
503          *
504          * Avoid the temptation of repeating the dlclose(). The other code that
505          * dlopened the module still has its module reference, and should close
506          * it itself. In other situations, dlclose() will happily return success
507          * for as many times as you wish to call it.
508          */
509 #if defined(HAVE_RTLD_NOLOAD)
510         if (is_module_loaded(name)) {
511                 ast_log(LOG_WARNING, "Module '%s' could not be completely unloaded\n", name);
512         }
513 #endif
514 }
515
516 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required);
517
518 #define MODULE_LOCAL_ONLY (void *)-1
519
520 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap)
521 {
522         char fn[PATH_MAX] = "";
523         void *lib = NULL;
524         struct ast_module *mod;
525         unsigned int wants_global;
526         int space;      /* room needed for the descriptor */
527         int missing_so = 0;
528
529         space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
530         if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
531                 missing_so = 1;
532                 space += 3;     /* room for the extra ".so" */
533         }
534
535         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
536
537         /* make a first load of the module in 'quiet' mode... don't try to resolve
538            any symbols, and don't export any symbols. this will allow us to peek into
539            the module's info block (if available) to see what flags it has set */
540
541         resource_being_loaded = ast_calloc(1, space);
542         if (!resource_being_loaded)
543                 return NULL;
544         strcpy(resource_being_loaded->resource, resource_in);
545         if (missing_so)
546                 strcat(resource_being_loaded->resource, ".so");
547
548         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_GLOBAL))) {
549                 if (!suppress_logging) {
550                         ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
551                 }
552                 ast_free(resource_being_loaded);
553                 return NULL;
554         }
555
556         /* the dlopen() succeeded, let's find out if the module
557            registered itself */
558         /* note that this will only work properly as long as
559            ast_module_register() (which is called by the module's
560            constructor) places the new module at the tail of the
561            module_list
562         */
563         if (resource_being_loaded != (mod = AST_DLLIST_LAST(&module_list))) {
564                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
565                 /* no, it did not, so close it and return */
566                 logged_dlclose(resource_in, lib);
567                 /* note that the module's destructor will call ast_module_unregister(),
568                    which will free the structure we allocated in resource_being_loaded */
569                 return NULL;
570         }
571
572         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
573
574         /* if we are being asked only to load modules that provide global symbols,
575            and this one does not, then close it and return */
576         if (global_symbols_only && !wants_global) {
577                 logged_dlclose(resource_in, lib);
578                 return MODULE_LOCAL_ONLY;
579         }
580
581         logged_dlclose(resource_in, lib);
582         resource_being_loaded = NULL;
583
584         /* start the load process again */
585         resource_being_loaded = ast_calloc(1, space);
586         if (!resource_being_loaded)
587                 return NULL;
588         strcpy(resource_being_loaded->resource, resource_in);
589         if (missing_so)
590                 strcat(resource_being_loaded->resource, ".so");
591
592         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
593                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
594                 ast_free(resource_being_loaded);
595                 return NULL;
596         }
597
598         /* since the module was successfully opened, and it registered itself
599            the previous time we did that, we're going to assume it worked this
600            time too :) */
601
602         AST_DLLIST_LAST(&module_list)->lib = lib;
603         resource_being_loaded = NULL;
604
605         return AST_DLLIST_LAST(&module_list);
606 }
607
608 #endif
609
610 void ast_module_shutdown(void)
611 {
612         struct ast_module *mod;
613         int somethingchanged = 1, final = 0;
614
615         AST_DLLIST_LOCK(&module_list);
616
617         /*!\note Some resources, like timers, are started up dynamically, and thus
618          * may be still in use, even if all channels are dead.  We must therefore
619          * check the usecount before asking modules to unload. */
620         do {
621                 if (!somethingchanged) {
622                         /*!\note If we go through the entire list without changing
623                          * anything, ignore the usecounts and unload, then exit. */
624                         final = 1;
625                 }
626
627                 /* Reset flag before traversing the list */
628                 somethingchanged = 0;
629
630                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(&module_list, mod, entry) {
631                         if (!final && mod->usecount) {
632                                 ast_debug(1, "Passing on %s: its use count is %d\n",
633                                         mod->resource, mod->usecount);
634                                 continue;
635                         }
636                         AST_DLLIST_REMOVE_CURRENT(entry);
637                         if (mod->flags.running && !mod->flags.declined && mod->info->unload) {
638                                 ast_verb(1, "Unloading %s\n", mod->resource);
639                                 mod->info->unload();
640                         }
641                         AST_LIST_HEAD_DESTROY(&mod->users);
642                         ao2_cleanup(mod->ref_debug);
643                         ast_free(mod);
644                         somethingchanged = 1;
645                 }
646                 AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END;
647                 if (!somethingchanged) {
648                         AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
649                                 if (mod->flags.keepuntilshutdown) {
650                                         ast_module_unref(mod);
651                                         mod->flags.keepuntilshutdown = 0;
652                                         somethingchanged = 1;
653                                 }
654                         }
655                 }
656         } while (somethingchanged && !final);
657
658         AST_DLLIST_UNLOCK(&module_list);
659 }
660
661 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
662 {
663         struct ast_module *mod;
664         int res = -1;
665         int error = 0;
666
667         AST_DLLIST_LOCK(&module_list);
668
669         if (!(mod = find_resource(resource_name, 0))) {
670                 AST_DLLIST_UNLOCK(&module_list);
671                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
672                 return -1;
673         }
674
675         if (!mod->flags.running || mod->flags.declined) {
676                 ast_log(LOG_WARNING, "Unload failed, '%s' is not loaded.\n", resource_name);
677                 error = 1;
678         }
679
680         if (!error && (mod->usecount > 0)) {
681                 if (force)
682                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
683                                 resource_name, mod->usecount);
684                 else {
685                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
686                                 mod->usecount);
687                         error = 1;
688                 }
689         }
690
691         if (!error) {
692                 /* Request any channels attached to the module to hangup. */
693                 __ast_module_user_hangup_all(mod);
694
695                 ast_verb(1, "Unloading %s\n", mod->resource);
696                 res = mod->info->unload();
697                 if (res) {
698                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
699                         if (force <= AST_FORCE_FIRM) {
700                                 error = 1;
701                         } else {
702                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
703                         }
704                 }
705
706                 if (!error) {
707                         /*
708                          * Request hangup on any channels that managed to get attached
709                          * while we called the module unload function.
710                          */
711                         __ast_module_user_hangup_all(mod);
712                         sched_yield();
713                 }
714         }
715
716         if (!error)
717                 mod->flags.running = mod->flags.declined = 0;
718
719         AST_DLLIST_UNLOCK(&module_list);
720
721         if (!error && !mod->lib && mod->info && mod->info->restore_globals)
722                 mod->info->restore_globals();
723
724 #ifdef LOADABLE_MODULES
725         if (!error) {
726                 unload_dynamic_module(mod);
727                 ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name);
728         }
729 #endif
730
731         if (!error)
732                 ast_update_use_count();
733
734         return res;
735 }
736
737 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
738 {
739         struct ast_module *cur;
740         int i, which=0, l = strlen(word);
741         char *ret = NULL;
742
743         if (pos != rpos)
744                 return NULL;
745
746         AST_DLLIST_LOCK(&module_list);
747         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
748                 if (!strncasecmp(word, cur->resource, l) &&
749                     (cur->info->reload || !needsreload) &&
750                     ++which > state) {
751                         ret = ast_strdup(cur->resource);
752                         break;
753                 }
754         }
755         AST_DLLIST_UNLOCK(&module_list);
756
757         if (!ret) {
758                 for (i=0; !ret && reload_classes[i].name; i++) {
759                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
760                                 ret = ast_strdup(reload_classes[i].name);
761                 }
762         }
763
764         return ret;
765 }
766
767 void ast_process_pending_reloads(void)
768 {
769         struct reload_queue_item *item;
770
771         modules_loaded = 1;
772
773         AST_LIST_LOCK(&reload_queue);
774
775         if (do_full_reload) {
776                 do_full_reload = 0;
777                 AST_LIST_UNLOCK(&reload_queue);
778                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
779                 ast_module_reload(NULL);
780                 return;
781         }
782
783         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
784                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
785                 ast_module_reload(item->module);
786                 ast_free(item);
787         }
788
789         AST_LIST_UNLOCK(&reload_queue);
790 }
791
792 static void queue_reload_request(const char *module)
793 {
794         struct reload_queue_item *item;
795
796         AST_LIST_LOCK(&reload_queue);
797
798         if (do_full_reload) {
799                 AST_LIST_UNLOCK(&reload_queue);
800                 return;
801         }
802
803         if (ast_strlen_zero(module)) {
804                 /* A full reload request (when module is NULL) wipes out any previous
805                    reload requests and causes the queue to ignore future ones */
806                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
807                         ast_free(item);
808                 }
809                 do_full_reload = 1;
810         } else {
811                 /* No reason to add the same module twice */
812                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
813                         if (!strcasecmp(item->module, module)) {
814                                 AST_LIST_UNLOCK(&reload_queue);
815                                 return;
816                         }
817                 }
818                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
819                 if (!item) {
820                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
821                         AST_LIST_UNLOCK(&reload_queue);
822                         return;
823                 }
824                 strcpy(item->module, module);
825                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
826         }
827         AST_LIST_UNLOCK(&reload_queue);
828 }
829
830 /*!
831  * \since 12
832  * \internal
833  * \brief Publish a \ref stasis message regarding the reload result
834  */
835 static void publish_reload_message(const char *name, enum ast_module_reload_result result)
836 {
837         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
838         RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup);
839         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
840         RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref);
841         char res_buffer[8];
842
843         if (!ast_manager_get_generic_type()) {
844                 return;
845         }
846
847         snprintf(res_buffer, sizeof(res_buffer), "%u", result);
848         event_object = ast_json_pack("{s: s, s: s}",
849                         "Module", S_OR(name, "All"),
850                         "Status", res_buffer);
851         json_object = ast_json_pack("{s: s, s: i, s: o}",
852                         "type", "Reload",
853                         "class_type", EVENT_FLAG_SYSTEM,
854                         "event", ast_json_ref(event_object));
855
856         if (!json_object) {
857                 return;
858         }
859
860         payload = ast_json_payload_create(json_object);
861         if (!payload) {
862                 return;
863         }
864
865         message = stasis_message_create(ast_manager_get_generic_type(), payload);
866         if (!message) {
867                 return;
868         }
869
870         stasis_publish(ast_manager_get_topic(), message);
871 }
872
873 enum ast_module_reload_result ast_module_reload(const char *name)
874 {
875         struct ast_module *cur;
876         enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
877         int i;
878
879         /* If we aren't fully booted, we just pretend we reloaded but we queue this
880            up to run once we are booted up. */
881         if (!modules_loaded) {
882                 queue_reload_request(name);
883                 res = AST_MODULE_RELOAD_QUEUED;
884                 goto module_reload_exit;
885         }
886
887         if (ast_mutex_trylock(&reloadlock)) {
888                 ast_verb(3, "The previous reload command didn't finish yet\n");
889                 res = AST_MODULE_RELOAD_IN_PROGRESS;
890                 goto module_reload_exit;
891         }
892         ast_sd_notify("RELOAD=1");
893         ast_lastreloadtime = ast_tvnow();
894
895         if (ast_opt_lock_confdir) {
896                 int try;
897                 int res;
898                 for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
899                         res = ast_lock_path(ast_config_AST_CONFIG_DIR);
900                         if (res == AST_LOCK_TIMEOUT) {
901                                 ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
902                         }
903                 }
904                 if (res != AST_LOCK_SUCCESS) {
905                         ast_log(AST_LOG_WARNING, "Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
906                         res = AST_MODULE_RELOAD_ERROR;
907                         goto module_reload_done;
908                 }
909         }
910
911         /* Call "predefined" reload here first */
912         for (i = 0; reload_classes[i].name; i++) {
913                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
914                         if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) {
915                                 res = AST_MODULE_RELOAD_SUCCESS;
916                         }
917                 }
918         }
919
920         if (name && res == AST_MODULE_RELOAD_SUCCESS) {
921                 if (ast_opt_lock_confdir) {
922                         ast_unlock_path(ast_config_AST_CONFIG_DIR);
923                 }
924                 goto module_reload_done;
925         }
926
927         AST_DLLIST_LOCK(&module_list);
928         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
929                 const struct ast_module_info *info = cur->info;
930
931                 if (name && resource_name_match(name, cur->resource))
932                         continue;
933
934                 if (!cur->flags.running || cur->flags.declined) {
935                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
936                                 res = AST_MODULE_RELOAD_UNINITIALIZED;
937                         }
938                         if (!name) {
939                                 continue;
940                         }
941                         break;
942                 }
943
944                 if (!info->reload) {    /* cannot be reloaded */
945                         if (res == AST_MODULE_RELOAD_NOT_FOUND) {
946                                 res = AST_MODULE_RELOAD_NOT_IMPLEMENTED;
947                         }
948                         if (!name) {
949                                 continue;
950                         }
951                         break;
952                 }
953                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
954                 if (info->reload() == AST_MODULE_LOAD_SUCCESS) {
955                         res = AST_MODULE_RELOAD_SUCCESS;
956                 }
957                 if (name) {
958                         break;
959                 }
960         }
961         AST_DLLIST_UNLOCK(&module_list);
962
963         if (ast_opt_lock_confdir) {
964                 ast_unlock_path(ast_config_AST_CONFIG_DIR);
965         }
966 module_reload_done:
967         ast_mutex_unlock(&reloadlock);
968         ast_sd_notify("READY=1");
969
970 module_reload_exit:
971         publish_reload_message(name, res);
972         return res;
973 }
974
975 static unsigned int inspect_module(const struct ast_module *mod)
976 {
977         if (!mod->info->description) {
978                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
979                 return 1;
980         }
981
982         if (!mod->info->key) {
983                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
984                 return 1;
985         }
986
987         if (verify_key((unsigned char *) mod->info->key)) {
988                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
989                 return 1;
990         }
991
992         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
993             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
994                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
995                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
996                 return 1;
997         }
998
999         return 0;
1000 }
1001
1002 static enum ast_module_load_result start_resource(struct ast_module *mod)
1003 {
1004         char tmp[256];
1005         enum ast_module_load_result res;
1006
1007         if (mod->flags.running) {
1008                 return AST_MODULE_LOAD_SUCCESS;
1009         }
1010
1011         if (!mod->info->load) {
1012                 return AST_MODULE_LOAD_FAILURE;
1013         }
1014
1015         if (!ast_fully_booted) {
1016                 ast_verb(1, "Loading %s.\n", mod->resource);
1017         }
1018         res = mod->info->load();
1019
1020         switch (res) {
1021         case AST_MODULE_LOAD_SUCCESS:
1022                 if (!ast_fully_booted) {
1023                         ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
1024                 } else {
1025                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
1026                 }
1027
1028                 mod->flags.running = 1;
1029
1030                 ast_update_use_count();
1031                 break;
1032         case AST_MODULE_LOAD_DECLINE:
1033                 mod->flags.declined = 1;
1034                 break;
1035         case AST_MODULE_LOAD_FAILURE:
1036         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
1037         case AST_MODULE_LOAD_PRIORITY:
1038                 break;
1039         }
1040
1041         /* Make sure the newly started module is at the end of the list */
1042         AST_DLLIST_LOCK(&module_list);
1043         AST_DLLIST_REMOVE(&module_list, mod, entry);
1044         AST_DLLIST_INSERT_TAIL(&module_list, mod, entry);
1045         AST_DLLIST_UNLOCK(&module_list);
1046
1047         return res;
1048 }
1049
1050 /*! loads a resource based upon resource_name. If global_symbols_only is set
1051  *  only modules with global symbols will be loaded.
1052  *
1053  *  If the ast_heap is provided (not NULL) the module is found and added to the
1054  *  heap without running the module's load() function.  By doing this, modules
1055  *  added to the resource_heap can be initialized later in order by priority.
1056  *
1057  *  If the ast_heap is not provided, the module's load function will be executed
1058  *  immediately */
1059 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required)
1060 {
1061         struct ast_module *mod;
1062         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
1063
1064         if ((mod = find_resource(resource_name, 0))) {
1065                 if (mod->flags.running) {
1066                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
1067                         return AST_MODULE_LOAD_DECLINE;
1068                 }
1069                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
1070                         return AST_MODULE_LOAD_SKIP;
1071         } else {
1072 #ifdef LOADABLE_MODULES
1073                 mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging, resource_heap);
1074                 if (mod == MODULE_LOCAL_ONLY) {
1075                                 return AST_MODULE_LOAD_SKIP;
1076                 }
1077                 if (!mod) {
1078                         if (!global_symbols_only) {
1079                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1080                         }
1081                         return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1082                 }
1083 #else
1084                 ast_log(LOG_WARNING, "Module support is not available. Module '%s' could not be loaded.\n", resource_name);
1085                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1086 #endif
1087         }
1088
1089         if (inspect_module(mod)) {
1090                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
1091 #ifdef LOADABLE_MODULES
1092                 unload_dynamic_module(mod);
1093 #endif
1094                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1095         }
1096
1097         if (!mod->lib && mod->info->backup_globals && mod->info->backup_globals()) {
1098                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
1099                 return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
1100         }
1101
1102         mod->flags.declined = 0;
1103
1104         if (resource_heap) {
1105                 ast_heap_push(resource_heap, mod);
1106                 res = AST_MODULE_LOAD_PRIORITY;
1107         } else {
1108                 res = start_resource(mod);
1109         }
1110
1111         return res;
1112 }
1113
1114 int ast_load_resource(const char *resource_name)
1115 {
1116         int res;
1117         AST_DLLIST_LOCK(&module_list);
1118         res = load_resource(resource_name, 0, 0, NULL, 0);
1119         if (!res) {
1120                 ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);
1121         }
1122         AST_DLLIST_UNLOCK(&module_list);
1123
1124         return res;
1125 }
1126
1127 struct load_order_entry {
1128         char *resource;
1129         int required;
1130         AST_LIST_ENTRY(load_order_entry) entry;
1131 };
1132
1133 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
1134
1135 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
1136 {
1137         struct load_order_entry *order;
1138
1139         AST_LIST_TRAVERSE(load_order, order, entry) {
1140                 if (!resource_name_match(order->resource, resource)) {
1141                         /* Make sure we have the proper setting for the required field
1142                            (we might have both load= and required= lines in modules.conf) */
1143                         order->required |= required;
1144                         return NULL;
1145                 }
1146         }
1147
1148         if (!(order = ast_calloc(1, sizeof(*order))))
1149                 return NULL;
1150
1151         order->resource = ast_strdup(resource);
1152         order->required = required;
1153         AST_LIST_INSERT_TAIL(load_order, order, entry);
1154
1155         return order;
1156 }
1157
1158 static int mod_load_cmp(void *a, void *b)
1159 {
1160         struct ast_module *a_mod = (struct ast_module *) a;
1161         struct ast_module *b_mod = (struct ast_module *) b;
1162         /* if load_pri is not set, default is 128.  Lower is better */
1163         int a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;
1164         int b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;
1165
1166         /*
1167          * Returns comparison values for a min-heap
1168          * <0 a_pri > b_pri
1169          * =0 a_pri == b_pri
1170          * >0 a_pri < b_pri
1171          */
1172         return b_pri - a_pri;
1173 }
1174
1175 AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);
1176
1177 /*! loads modules in order by load_pri, updates mod_count
1178         \return -1 on failure to load module, -2 on failure to load required module, otherwise 0
1179 */
1180 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
1181 {
1182         struct ast_heap *resource_heap;
1183         struct load_order_entry *order;
1184         struct ast_module *mod;
1185         struct load_retries load_retries;
1186         int count = 0;
1187         int res = 0;
1188         int i = 0;
1189 #define LOAD_RETRIES 4
1190
1191         AST_LIST_HEAD_INIT_NOLOCK(&load_retries);
1192
1193         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
1194                 return -1;
1195         }
1196
1197         /* first, add find and add modules to heap */
1198         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
1199                 enum ast_module_load_result lres;
1200
1201                 /* Suppress log messages unless this is the last pass */
1202                 lres = load_resource(order->resource, global_symbols, 1, resource_heap, order->required);
1203                 ast_debug(3, "PASS 0: %-46s %d %d\n", order->resource, lres, global_symbols);
1204                 switch (lres) {
1205                 case AST_MODULE_LOAD_SUCCESS:
1206                         /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */
1207                         break;
1208                 case AST_MODULE_LOAD_FAILURE:
1209                 case AST_MODULE_LOAD_DECLINE:
1210                         /*
1211                          * DECLINE or FAILURE means there was an issue with dlopen or module_register
1212                          * which might be retryable.  LOAD_FAILURE only happens for required modules
1213                          * but we're still going to retry.  We need to remove the entry from the
1214                          * load_order list and add it to the load_retries list.
1215                          */
1216                         AST_LIST_REMOVE_CURRENT(entry);
1217                         AST_LIST_INSERT_TAIL(&load_retries, order, entry);
1218                         break;
1219                 case AST_MODULE_LOAD_SKIP:
1220                         /*
1221                          * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.
1222                          * Leave it in load_order for the next call of load_resource_list.
1223                          */
1224                         break;
1225                 case AST_MODULE_LOAD_PRIORITY:
1226                         /* load_resource worked and the module was added to the priority heap */
1227                         AST_LIST_REMOVE_CURRENT(entry);
1228                         ast_free(order->resource);
1229                         ast_free(order);
1230                         break;
1231                 }
1232         }
1233         AST_LIST_TRAVERSE_SAFE_END;
1234
1235         /* Retry the failures until the list is empty or we reach LOAD_RETRIES */
1236         for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {
1237                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {
1238                         enum ast_module_load_result lres;
1239
1240                         /* Suppress log messages unless this is the last pass */
1241                         lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), resource_heap, order->required);
1242                         ast_debug(3, "PASS %d %-46s %d %d\n", i + 1, order->resource, lres, global_symbols);
1243                         switch (lres) {
1244                         /* These are all retryable. */
1245                         case AST_MODULE_LOAD_SUCCESS:
1246                         case AST_MODULE_LOAD_DECLINE:
1247                                 break;
1248                         case AST_MODULE_LOAD_FAILURE:
1249                                 /* LOAD_FAILURE only happens for required modules */
1250                                 if (i == LOAD_RETRIES - 1) {
1251                                         /* This was the last chance to load a required module*/
1252                                         ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);
1253                                         fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);
1254                                         res =  -2;
1255                                         goto done;
1256                                 }
1257                                 break;;
1258                         case AST_MODULE_LOAD_SKIP:
1259                                 /*
1260                                  * SKIP means that dlopen worked but global_symbols was set and this module
1261                                  * doesn't qualify.  Put it back in load_order for the next call of
1262                                  * load_resource_list.
1263                                  */
1264                                 AST_LIST_REMOVE_CURRENT(entry);
1265                                 AST_LIST_INSERT_TAIL(load_order, order, entry);
1266                                 break;
1267                         case AST_MODULE_LOAD_PRIORITY:
1268                                 /* load_resource worked and the module was added to the priority heap */
1269                                 AST_LIST_REMOVE_CURRENT(entry);
1270                                 ast_free(order->resource);
1271                                 ast_free(order);
1272                                 break;
1273                         }
1274                 }
1275                 AST_LIST_TRAVERSE_SAFE_END;
1276         }
1277
1278         /* second remove modules from heap sorted by priority */
1279         while ((mod = ast_heap_pop(resource_heap))) {
1280                 enum ast_module_load_result lres;
1281
1282                 lres = start_resource(mod);
1283                 ast_debug(3, "START: %-46s %d %d\n", mod->resource, lres, global_symbols);
1284                 switch (lres) {
1285                 case AST_MODULE_LOAD_SUCCESS:
1286                         count++;
1287                 case AST_MODULE_LOAD_DECLINE:
1288                         break;
1289                 case AST_MODULE_LOAD_FAILURE:
1290                         res = -1;
1291                         goto done;
1292                 case AST_MODULE_LOAD_SKIP:
1293                 case AST_MODULE_LOAD_PRIORITY:
1294                         break;
1295                 }
1296         }
1297
1298 done:
1299
1300         while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {
1301                 ast_free(order->resource);
1302                 ast_free(order);
1303         }
1304
1305         if (mod_count) {
1306                 *mod_count += count;
1307         }
1308         ast_heap_destroy(resource_heap);
1309
1310         return res;
1311 }
1312
1313 int load_modules(unsigned int preload_only)
1314 {
1315         struct ast_config *cfg;
1316         struct ast_module *mod;
1317         struct load_order_entry *order;
1318         struct ast_variable *v;
1319         unsigned int load_count;
1320         struct load_order load_order;
1321         int res = 0;
1322         struct ast_flags config_flags = { 0 };
1323         int modulecount = 0;
1324
1325 #ifdef LOADABLE_MODULES
1326         struct dirent *dirent;
1327         DIR *dir;
1328 #endif
1329
1330         /* all embedded modules have registered themselves by now */
1331         embedding = 0;
1332
1333         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
1334
1335         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
1336
1337         AST_DLLIST_LOCK(&module_list);
1338
1339         if (embedded_module_list.first) {
1340                 module_list.first = embedded_module_list.first;
1341                 module_list.last = embedded_module_list.last;
1342                 embedded_module_list.first = NULL;
1343         }
1344
1345         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
1346         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
1347                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
1348                 goto done;
1349         }
1350
1351         /* first, find all the modules we have been explicitly requested to load */
1352         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1353                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
1354                         add_to_load_order(v->value, &load_order, 0);
1355                 }
1356                 if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
1357                         /* Add the module to the list and make sure it's required */
1358                         add_to_load_order(v->value, &load_order, 1);
1359                         ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
1360                 }
1361
1362         }
1363
1364         /* check if 'autoload' is on */
1365         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
1366                 /* if so, first add all the embedded modules that are not already running to the load order */
1367                 AST_DLLIST_TRAVERSE(&module_list, mod, entry) {
1368                         /* if it's not embedded, skip it */
1369                         if (mod->lib)
1370                                 continue;
1371
1372                         if (mod->flags.running)
1373                                 continue;
1374
1375                         add_to_load_order(mod->resource, &load_order, 0);
1376                 }
1377
1378 #ifdef LOADABLE_MODULES
1379                 /* if we are allowed to load dynamic modules, scan the directory for
1380                    for all available modules and add them as well */
1381                 if ((dir = opendir(ast_config_AST_MODULE_DIR))) {
1382                         while ((dirent = readdir(dir))) {
1383                                 int ld = strlen(dirent->d_name);
1384
1385                                 /* Must end in .so to load it.  */
1386
1387                                 if (ld < 4)
1388                                         continue;
1389
1390                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
1391                                         continue;
1392
1393                                 /* if there is already a module by this name in the module_list,
1394                                    skip this file */
1395                                 if (find_resource(dirent->d_name, 0))
1396                                         continue;
1397
1398                                 add_to_load_order(dirent->d_name, &load_order, 0);
1399                         }
1400
1401                         closedir(dir);
1402                 } else {
1403                         if (!ast_opt_quiet)
1404                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1405                                         ast_config_AST_MODULE_DIR);
1406                 }
1407 #endif
1408         }
1409
1410         /* now scan the config for any modules we are prohibited from loading and
1411            remove them from the load order */
1412         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1413                 if (strcasecmp(v->name, "noload"))
1414                         continue;
1415
1416                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1417                         if (!resource_name_match(order->resource, v->value)) {
1418                                 AST_LIST_REMOVE_CURRENT(entry);
1419                                 ast_free(order->resource);
1420                                 ast_free(order);
1421                         }
1422                 }
1423                 AST_LIST_TRAVERSE_SAFE_END;
1424         }
1425
1426         /* we are done with the config now, all the information we need is in the
1427            load_order list */
1428         ast_config_destroy(cfg);
1429
1430         load_count = 0;
1431         AST_LIST_TRAVERSE(&load_order, order, entry)
1432                 load_count++;
1433
1434         if (load_count)
1435                 ast_log(LOG_NOTICE, "%u modules will be loaded.\n", load_count);
1436
1437         /* first, load only modules that provide global symbols */
1438         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1439                 goto done;
1440         }
1441
1442         /* now load everything else */
1443         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1444                 goto done;
1445         }
1446
1447 done:
1448         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1449                 ast_free(order->resource);
1450                 ast_free(order);
1451         }
1452
1453         AST_DLLIST_UNLOCK(&module_list);
1454         return res;
1455 }
1456
1457 void ast_update_use_count(void)
1458 {
1459         /* Notify any module monitors that the use count for a
1460            resource has changed */
1461         struct loadupdate *m;
1462
1463         AST_LIST_LOCK(&updaters);
1464         AST_LIST_TRAVERSE(&updaters, m, entry)
1465                 m->updater();
1466         AST_LIST_UNLOCK(&updaters);
1467 }
1468
1469 int ast_update_module_list(int (*modentry)(const char *module, const char *description,
1470                                            int usecnt, const char *status, const char *like,
1471                                                                                    enum ast_module_support_level support_level),
1472                            const char *like)
1473 {
1474         struct ast_module *cur;
1475         int unlock = -1;
1476         int total_mod_loaded = 0;
1477         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1478
1479         if (AST_DLLIST_TRYLOCK(&module_list)) {
1480                 unlock = 0;
1481         }
1482
1483         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1484                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1485         }
1486
1487         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1488                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1489                                                 cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
1490         }
1491
1492         if (unlock) {
1493                 AST_DLLIST_UNLOCK(&module_list);
1494         }
1495
1496         return total_mod_loaded;
1497 }
1498
1499 int ast_update_module_list_data(int (*modentry)(const char *module, const char *description,
1500                                                 int usecnt, const char *status, const char *like,
1501                                                 enum ast_module_support_level support_level,
1502                                                 void *data),
1503                                 const char *like, void *data)
1504 {
1505         struct ast_module *cur;
1506         int total_mod_loaded = 0;
1507         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1508
1509         AST_DLLIST_LOCK(&module_list);
1510
1511         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1512                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1513         }
1514
1515         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1516                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
1517                         cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
1518         }
1519
1520         AST_DLLIST_UNLOCK(&module_list);
1521
1522         return total_mod_loaded;
1523 }
1524
1525 int ast_update_module_list_condition(int (*modentry)(const char *module, const char *description,
1526                                                      int usecnt, const char *status,
1527                                                      const char *like,
1528                                                      enum ast_module_support_level support_level,
1529                                                      void *data, const char *condition),
1530                                      const char *like, void *data, const char *condition)
1531 {
1532         struct ast_module *cur;
1533         int conditions_met = 0;
1534         AST_LIST_HEAD_NOLOCK(, ast_module) alpha_module_list = AST_LIST_HEAD_NOLOCK_INIT_VALUE;
1535
1536         AST_DLLIST_LOCK(&module_list);
1537
1538         AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
1539                 AST_LIST_INSERT_SORTALPHA(&alpha_module_list, cur, list_entry, resource);
1540         }
1541
1542         while ((cur = AST_LIST_REMOVE_HEAD(&alpha_module_list, list_entry))) {
1543                 conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
1544                         cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
1545                         condition);
1546         }
1547
1548         AST_DLLIST_UNLOCK(&module_list);
1549
1550         return conditions_met;
1551 }
1552
1553 /*! \brief Check if module exists */
1554 int ast_module_check(const char *name)
1555 {
1556         struct ast_module *cur;
1557
1558         if (ast_strlen_zero(name))
1559                 return 0;       /* FALSE */
1560
1561         cur = find_resource(name, 1);
1562
1563         return (cur != NULL);
1564 }
1565
1566
1567 int ast_loader_register(int (*v)(void))
1568 {
1569         struct loadupdate *tmp;
1570
1571         if (!(tmp = ast_malloc(sizeof(*tmp))))
1572                 return -1;
1573
1574         tmp->updater = v;
1575         AST_LIST_LOCK(&updaters);
1576         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1577         AST_LIST_UNLOCK(&updaters);
1578
1579         return 0;
1580 }
1581
1582 int ast_loader_unregister(int (*v)(void))
1583 {
1584         struct loadupdate *cur;
1585
1586         AST_LIST_LOCK(&updaters);
1587         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1588                 if (cur->updater == v)  {
1589                         AST_LIST_REMOVE_CURRENT(entry);
1590                         break;
1591                 }
1592         }
1593         AST_LIST_TRAVERSE_SAFE_END;
1594         AST_LIST_UNLOCK(&updaters);
1595
1596         return cur ? 0 : -1;
1597 }
1598
1599 struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, int line, const char *func)
1600 {
1601         if (!mod) {
1602                 return NULL;
1603         }
1604
1605         if (mod->ref_debug) {
1606                 __ao2_ref(mod->ref_debug, +1, "", file, line, func);
1607         }
1608
1609         ast_atomic_fetchadd_int(&mod->usecount, +1);
1610         ast_update_use_count();
1611
1612         return mod;
1613 }
1614
1615 void __ast_module_shutdown_ref(struct ast_module *mod, const char *file, int line, const char *func)
1616 {
1617         if (!mod || mod->flags.keepuntilshutdown) {
1618                 return;
1619         }
1620
1621         __ast_module_ref(mod, file, line, func);
1622         mod->flags.keepuntilshutdown = 1;
1623 }
1624
1625 void __ast_module_unref(struct ast_module *mod, const char *file, int line, const char *func)
1626 {
1627         if (!mod) {
1628                 return;
1629         }
1630
1631         if (mod->ref_debug) {
1632                 __ao2_ref(mod->ref_debug, -1, "", file, line, func);
1633         }
1634
1635         ast_atomic_fetchadd_int(&mod->usecount, -1);
1636         ast_update_use_count();
1637 }
1638
1639 const char *support_level_map [] = {
1640         [AST_MODULE_SUPPORT_UNKNOWN] = "unknown",
1641         [AST_MODULE_SUPPORT_CORE] = "core",
1642         [AST_MODULE_SUPPORT_EXTENDED] = "extended",
1643         [AST_MODULE_SUPPORT_DEPRECATED] = "deprecated",
1644 };
1645
1646 const char *ast_module_support_level_to_string(enum ast_module_support_level support_level)
1647 {
1648         return support_level_map[support_level];
1649 }