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