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