attempting to load running modules
[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 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/_private.h"
35 #include "asterisk/paths.h"     /* use ast_config_AST_MODULE_DIR */
36 #include <dirent.h>
37
38 #include "asterisk/linkedlists.h"
39 #include "asterisk/module.h"
40 #include "asterisk/config.h"
41 #include "asterisk/channel.h"
42 #include "asterisk/term.h"
43 #include "asterisk/manager.h"
44 #include "asterisk/cdr.h"
45 #include "asterisk/enum.h"
46 #include "asterisk/http.h"
47 #include "asterisk/lock.h"
48 #include "asterisk/features.h"
49 #include "asterisk/dsp.h"
50 #include "asterisk/udptl.h"
51 #include "asterisk/heap.h"
52
53 #include <dlfcn.h>
54
55 #include "asterisk/md5.h"
56 #include "asterisk/utils.h"
57
58 #ifndef RTLD_NOW
59 #define RTLD_NOW 0
60 #endif
61
62 #ifndef RTLD_LOCAL
63 #define RTLD_LOCAL 0
64 #endif
65
66 struct ast_module_user {
67         struct ast_channel *chan;
68         AST_LIST_ENTRY(ast_module_user) entry;
69 };
70
71 AST_LIST_HEAD(module_user_list, ast_module_user);
72
73 static const unsigned char expected_key[] =
74 { 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
75   0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 };
76
77 static char buildopt_sum[33] = AST_BUILDOPT_SUM;
78
79 static unsigned int embedding = 1; /* we always start out by registering embedded modules,
80                                       since they are here before we dlopen() any
81                                    */
82
83 struct ast_module {
84         const struct ast_module_info *info;
85         void *lib;                                      /* the shared lib, or NULL if embedded */
86         int usecount;                                   /* the number of 'users' currently in this module */
87         struct module_user_list users;                  /* the list of users in the module */
88         struct {
89                 unsigned int running:1;
90                 unsigned int declined:1;
91         } flags;
92         AST_LIST_ENTRY(ast_module) entry;
93         char resource[0];
94 };
95
96 static AST_LIST_HEAD_STATIC(module_list, ast_module);
97
98 /*
99  * module_list is cleared by its constructor possibly after
100  * we start accumulating embedded modules, so we need to
101  * use another list (without the lock) to accumulate them.
102  * Then we update the main list when embedding is done.
103  */
104 static struct module_list embedded_module_list;
105
106 struct loadupdate {
107         int (*updater)(void);
108         AST_LIST_ENTRY(loadupdate) entry;
109 };
110
111 static AST_LIST_HEAD_STATIC(updaters, loadupdate);
112
113 AST_MUTEX_DEFINE_STATIC(reloadlock);
114
115 struct reload_queue_item {
116         AST_LIST_ENTRY(reload_queue_item) entry;
117         char module[0];
118 };
119
120 static int do_full_reload = 0;
121
122 static AST_LIST_HEAD_STATIC(reload_queue, reload_queue_item);
123
124 /* when dynamic modules are being loaded, ast_module_register() will
125    need to know what filename the module was loaded from while it
126    is being registered
127 */
128 static struct ast_module *resource_being_loaded;
129
130 /* XXX: should we check for duplicate resource names here? */
131
132 void ast_module_register(const struct ast_module_info *info)
133 {
134         struct ast_module *mod;
135
136         if (embedding) {
137                 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1)))
138                         return;
139                 strcpy(mod->resource, info->name);
140         } else {
141                 mod = resource_being_loaded;
142         }
143
144         mod->info = info;
145         AST_LIST_HEAD_INIT(&mod->users);
146
147         /* during startup, before the loader has been initialized,
148            there are no threads, so there is no need to take the lock
149            on this list to manipulate it. it is also possible that it
150            might be unsafe to use the list lock at that point... so
151            let's avoid it altogether
152         */
153         if (embedding) {
154                 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry);
155         } else {
156                 AST_LIST_LOCK(&module_list);
157                 /* it is paramount that the new entry be placed at the tail of
158                    the list, otherwise the code that uses dlopen() to load
159                    dynamic modules won't be able to find out if the module it
160                    just opened was registered or failed to load
161                 */
162                 AST_LIST_INSERT_TAIL(&module_list, mod, entry);
163                 AST_LIST_UNLOCK(&module_list);
164         }
165
166         /* give the module a copy of its own handle, for later use in registrations and the like */
167         *((struct ast_module **) &(info->self)) = mod;
168 }
169
170 void ast_module_unregister(const struct ast_module_info *info)
171 {
172         struct ast_module *mod = NULL;
173
174         /* it is assumed that the users list in the module structure
175            will already be empty, or we cannot have gotten to this
176            point
177         */
178         AST_LIST_LOCK(&module_list);
179         AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) {
180                 if (mod->info == info) {
181                         AST_LIST_REMOVE_CURRENT(entry);
182                         break;
183                 }
184         }
185         AST_LIST_TRAVERSE_SAFE_END;
186         AST_LIST_UNLOCK(&module_list);
187
188         if (mod) {
189                 AST_LIST_HEAD_DESTROY(&mod->users);
190                 ast_free(mod);
191         }
192 }
193
194 struct ast_module_user *__ast_module_user_add(struct ast_module *mod,
195                                               struct ast_channel *chan)
196 {
197         struct ast_module_user *u = ast_calloc(1, sizeof(*u));
198
199         if (!u)
200                 return NULL;
201
202         u->chan = chan;
203
204         AST_LIST_LOCK(&mod->users);
205         AST_LIST_INSERT_HEAD(&mod->users, u, entry);
206         AST_LIST_UNLOCK(&mod->users);
207
208         ast_atomic_fetchadd_int(&mod->usecount, +1);
209
210         ast_update_use_count();
211
212         return u;
213 }
214
215 void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
216 {
217         AST_LIST_LOCK(&mod->users);
218         AST_LIST_REMOVE(&mod->users, u, entry);
219         AST_LIST_UNLOCK(&mod->users);
220         ast_atomic_fetchadd_int(&mod->usecount, -1);
221         ast_free(u);
222
223         ast_update_use_count();
224 }
225
226 void __ast_module_user_hangup_all(struct ast_module *mod)
227 {
228         struct ast_module_user *u;
229
230         AST_LIST_LOCK(&mod->users);
231         while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) {
232                 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
233                 ast_atomic_fetchadd_int(&mod->usecount, -1);
234                 ast_free(u);
235         }
236         AST_LIST_UNLOCK(&mod->users);
237
238         ast_update_use_count();
239 }
240
241 /*! \note
242  * In addition to modules, the reload command handles some extra keywords
243  * which are listed here together with the corresponding handlers.
244  * This table is also used by the command completion code.
245  */
246 static struct reload_classes {
247         const char *name;
248         int (*reload_fn)(void);
249 } reload_classes[] = {  /* list in alpha order, longest match first for cli completion */
250         { "cdr",        ast_cdr_engine_reload },
251         { "dnsmgr",     dnsmgr_reload },
252         { "extconfig",  read_config_maps },
253         { "enum",       ast_enum_reload },
254         { "manager",    reload_manager },
255         { "http",       ast_http_reload },
256         { "logger",     logger_reload },
257         { "features",   ast_features_reload },
258         { "dsp",        ast_dsp_reload},
259         { "udptl",      ast_udptl_reload },
260         { "indications", ast_indications_reload },
261         { NULL,         NULL }
262 };
263
264 static int printdigest(const unsigned char *d)
265 {
266         int x, pos;
267         char buf[256]; /* large enough so we don't have to worry */
268
269         for (pos = 0, x = 0; x < 16; x++)
270                 pos += sprintf(buf + pos, " %02x", *d++);
271
272         ast_debug(1, "Unexpected signature:%s\n", buf);
273
274         return 0;
275 }
276
277 static int key_matches(const unsigned char *key1, const unsigned char *key2)
278 {
279         int x;
280
281         for (x = 0; x < 16; x++) {
282                 if (key1[x] != key2[x])
283                         return 0;
284         }
285
286         return 1;
287 }
288
289 static int verify_key(const unsigned char *key)
290 {
291         struct MD5Context c;
292         unsigned char digest[16];
293
294         MD5Init(&c);
295         MD5Update(&c, key, strlen((char *)key));
296         MD5Final(digest, &c);
297
298         if (key_matches(expected_key, digest))
299                 return 0;
300
301         printdigest(digest);
302
303         return -1;
304 }
305
306 static int resource_name_match(const char *name1_in, const char *name2_in)
307 {
308         char *name1 = (char *) name1_in;
309         char *name2 = (char *) name2_in;
310
311         /* trim off any .so extensions */
312         if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
313                 name1 = ast_strdupa(name1);
314                 name1[strlen(name1) - 3] = '\0';
315         }
316         if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
317                 name2 = ast_strdupa(name2);
318                 name2[strlen(name2) - 3] = '\0';
319         }
320
321         return strcasecmp(name1, name2);
322 }
323
324 static struct ast_module *find_resource(const char *resource, int do_lock)
325 {
326         struct ast_module *cur;
327
328         if (do_lock)
329                 AST_LIST_LOCK(&module_list);
330
331         AST_LIST_TRAVERSE(&module_list, cur, entry) {
332                 if (!resource_name_match(resource, cur->resource))
333                         break;
334         }
335
336         if (do_lock)
337                 AST_LIST_UNLOCK(&module_list);
338
339         return cur;
340 }
341
342 #ifdef LOADABLE_MODULES
343 static void unload_dynamic_module(struct ast_module *mod)
344 {
345         void *lib = mod->lib;
346
347         /* WARNING: the structure pointed to by mod is going to
348            disappear when this operation succeeds, so we can't
349            dereference it */
350
351         if (lib)
352                 while (!dlclose(lib));
353 }
354
355 static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only)
356 {
357         char fn[PATH_MAX] = "";
358         void *lib = NULL;
359         struct ast_module *mod;
360         unsigned int wants_global;
361         int space;      /* room needed for the descriptor */
362         int missing_so = 0;
363
364         space = sizeof(*resource_being_loaded) + strlen(resource_in) + 1;
365         if (strcasecmp(resource_in + strlen(resource_in) - 3, ".so")) {
366                 missing_so = 1;
367                 space += 3;     /* room for the extra ".so" */
368         }
369
370         snprintf(fn, sizeof(fn), "%s/%s%s", ast_config_AST_MODULE_DIR, resource_in, missing_so ? ".so" : "");
371
372         /* make a first load of the module in 'quiet' mode... don't try to resolve
373            any symbols, and don't export any symbols. this will allow us to peek into
374            the module's info block (if available) to see what flags it has set */
375
376         resource_being_loaded = ast_calloc(1, space);
377         if (!resource_being_loaded)
378                 return NULL;
379         strcpy(resource_being_loaded->resource, resource_in);
380         if (missing_so)
381                 strcat(resource_being_loaded->resource, ".so");
382
383         if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
384                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
385                 ast_free(resource_being_loaded);
386                 return NULL;
387         }
388
389         /* the dlopen() succeeded, let's find out if the module
390            registered itself */
391         /* note that this will only work properly as long as
392            ast_module_register() (which is called by the module's
393            constructor) places the new module at the tail of the
394            module_list
395         */
396         if (resource_being_loaded != (mod = AST_LIST_LAST(&module_list))) {
397                 ast_log(LOG_WARNING, "Module '%s' did not register itself during load\n", resource_in);
398                 /* no, it did not, so close it and return */
399                 while (!dlclose(lib));
400                 /* note that the module's destructor will call ast_module_unregister(),
401                    which will free the structure we allocated in resource_being_loaded */
402                 return NULL;
403         }
404
405         wants_global = ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS);
406
407         /* if we are being asked only to load modules that provide global symbols,
408            and this one does not, then close it and return */
409         if (global_symbols_only && !wants_global) {
410                 while (!dlclose(lib));
411                 return NULL;
412         }
413
414         while (!dlclose(lib));
415         resource_being_loaded = NULL;
416
417         /* start the load process again */
418         resource_being_loaded = ast_calloc(1, space);
419         if (!resource_being_loaded)
420                 return NULL;
421         strcpy(resource_being_loaded->resource, resource_in);
422         if (missing_so)
423                 strcat(resource_being_loaded->resource, ".so");
424
425         if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
426                 ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
427                 ast_free(resource_being_loaded);
428                 return NULL;
429         }
430
431         /* since the module was successfully opened, and it registered itself
432            the previous time we did that, we're going to assume it worked this
433            time too :) */
434
435         AST_LIST_LAST(&module_list)->lib = lib;
436         resource_being_loaded = NULL;
437
438         return AST_LIST_LAST(&module_list);
439 }
440 #endif
441
442 void ast_module_shutdown(void)
443 {
444         struct ast_module *mod;
445         AST_LIST_HEAD_NOLOCK_STATIC(local_module_list, ast_module);
446
447         /* We have to call the unload() callbacks in reverse order that the modules
448          * exist in the module list so it is the reverse order of how they were
449          * loaded. */
450
451         AST_LIST_LOCK(&module_list);
452         while ((mod = AST_LIST_REMOVE_HEAD(&module_list, entry)))
453                 AST_LIST_INSERT_HEAD(&local_module_list, mod, entry);
454         AST_LIST_UNLOCK(&module_list);
455
456         while ((mod = AST_LIST_REMOVE_HEAD(&local_module_list, entry))) {
457                 if (mod->info->unload)
458                         mod->info->unload();
459                 /* Since this should only be called when shutting down "gracefully",
460                  * all channels should be down before we get to this point, meaning
461                  * there will be no module users left. */
462                 AST_LIST_HEAD_DESTROY(&mod->users);
463                 free(mod);
464         }
465 }
466
467 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)
468 {
469         struct ast_module *mod;
470         int res = -1;
471         int error = 0;
472
473         AST_LIST_LOCK(&module_list);
474
475         if (!(mod = find_resource(resource_name, 0))) {
476                 AST_LIST_UNLOCK(&module_list);
477                 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name);
478                 return 0;
479         }
480
481         if (!(mod->flags.running || mod->flags.declined))
482                 error = 1;
483
484         if (!error && (mod->usecount > 0)) {
485                 if (force)
486                         ast_log(LOG_WARNING, "Warning:  Forcing removal of module '%s' with use count %d\n",
487                                 resource_name, mod->usecount);
488                 else {
489                         ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name,
490                                 mod->usecount);
491                         error = 1;
492                 }
493         }
494
495         if (!error) {
496                 __ast_module_user_hangup_all(mod);
497                 res = mod->info->unload();
498
499                 if (res) {
500                         ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name);
501                         if (force <= AST_FORCE_FIRM)
502                                 error = 1;
503                         else
504                                 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n");
505                 }
506         }
507
508         if (!error)
509                 mod->flags.running = mod->flags.declined = 0;
510
511         AST_LIST_UNLOCK(&module_list);
512
513         if (!error && !mod->lib && mod->info && mod->info->restore_globals)
514                 mod->info->restore_globals();
515
516 #ifdef LOADABLE_MODULES
517         if (!error)
518                 unload_dynamic_module(mod);
519 #endif
520
521         if (!error)
522                 ast_update_use_count();
523
524         return res;
525 }
526
527 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload)
528 {
529         struct ast_module *cur;
530         int i, which=0, l = strlen(word);
531         char *ret = NULL;
532
533         if (pos != rpos)
534                 return NULL;
535
536         AST_LIST_LOCK(&module_list);
537         AST_LIST_TRAVERSE(&module_list, cur, entry) {
538                 if (!strncasecmp(word, cur->resource, l) &&
539                     (cur->info->reload || !needsreload) &&
540                     ++which > state) {
541                         ret = ast_strdup(cur->resource);
542                         break;
543                 }
544         }
545         AST_LIST_UNLOCK(&module_list);
546
547         if (!ret) {
548                 for (i=0; !ret && reload_classes[i].name; i++) {
549                         if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state)
550                                 ret = ast_strdup(reload_classes[i].name);
551                 }
552         }
553
554         return ret;
555 }
556
557 void ast_process_pending_reloads(void)
558 {
559         struct reload_queue_item *item;
560
561         if (!ast_fully_booted) {
562                 return;
563         }
564
565         AST_LIST_LOCK(&reload_queue);
566
567         if (do_full_reload) {
568                 do_full_reload = 0;
569                 AST_LIST_UNLOCK(&reload_queue);
570                 ast_log(LOG_NOTICE, "Executing deferred reload request.\n");
571                 ast_module_reload(NULL);
572                 return;
573         }
574
575         while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
576                 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module);
577                 ast_module_reload(item->module);
578                 ast_free(item);
579         }
580
581         AST_LIST_UNLOCK(&reload_queue);
582 }
583
584 static void queue_reload_request(const char *module)
585 {
586         struct reload_queue_item *item;
587
588         AST_LIST_LOCK(&reload_queue);
589
590         if (do_full_reload) {
591                 AST_LIST_UNLOCK(&reload_queue);
592                 return;
593         }
594
595         if (ast_strlen_zero(module)) {
596                 /* A full reload request (when module is NULL) wipes out any previous
597                    reload requests and causes the queue to ignore future ones */
598                 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) {
599                         ast_free(item);
600                 }
601                 do_full_reload = 1;
602         } else {
603                 /* No reason to add the same module twice */
604                 AST_LIST_TRAVERSE(&reload_queue, item, entry) {
605                         if (!strcasecmp(item->module, module)) {
606                                 AST_LIST_UNLOCK(&reload_queue);
607                                 return;
608                         }
609                 }
610                 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1);
611                 if (!item) {
612                         ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n");
613                         AST_LIST_UNLOCK(&reload_queue);
614                         return;
615                 }
616                 strcpy(item->module, module);
617                 AST_LIST_INSERT_TAIL(&reload_queue, item, entry);
618         }
619         AST_LIST_UNLOCK(&reload_queue);
620 }
621
622 int ast_module_reload(const char *name)
623 {
624         struct ast_module *cur;
625         int res = 0; /* return value. 0 = not found, others, see below */
626         int i;
627
628         /* If we aren't fully booted, we just pretend we reloaded but we queue this
629            up to run once we are booted up. */
630         if (!ast_fully_booted) {
631                 queue_reload_request(name);
632                 return 0;
633         }
634
635         if (ast_mutex_trylock(&reloadlock)) {
636                 ast_verbose("The previous reload command didn't finish yet\n");
637                 return -1;      /* reload already in progress */
638         }
639         ast_lastreloadtime = ast_tvnow();
640
641         /* Call "predefined" reload here first */
642         for (i = 0; reload_classes[i].name; i++) {
643                 if (!name || !strcasecmp(name, reload_classes[i].name)) {
644                         reload_classes[i].reload_fn();  /* XXX should check error ? */
645                         res = 2;        /* found and reloaded */
646                 }
647         }
648
649         if (name && res) {
650                 ast_mutex_unlock(&reloadlock);
651                 return res;
652         }
653
654         AST_LIST_LOCK(&module_list);
655         AST_LIST_TRAVERSE(&module_list, cur, entry) {
656                 const struct ast_module_info *info = cur->info;
657
658                 if (name && resource_name_match(name, cur->resource))
659                         continue;
660
661                 if (!cur->flags.running || cur->flags.declined) {
662                         if (!name)
663                                 continue;
664                         ast_log(LOG_NOTICE, "The module '%s' was not properly initialized.  "
665                                 "Before reloading the module, you must run \"module load %s\" "
666                                 "and fix whatever is preventing the module from being initialized.\n",
667                                 name, name);
668                         res = 2; /* Don't report that the module was not found */
669                         break;
670                 }
671
672                 if (!info->reload) {    /* cannot be reloaded */
673                         if (res < 1)    /* store result if possible */
674                                 res = 1;        /* 1 = no reload() method */
675                         continue;
676                 }
677
678                 res = 2;
679                 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description);
680                 info->reload();
681         }
682         AST_LIST_UNLOCK(&module_list);
683
684         ast_mutex_unlock(&reloadlock);
685
686         return res;
687 }
688
689 static unsigned int inspect_module(const struct ast_module *mod)
690 {
691         if (!mod->info->description) {
692                 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource);
693                 return 1;
694         }
695
696         if (!mod->info->key) {
697                 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource);
698                 return 1;
699         }
700
701         if (verify_key((unsigned char *) mod->info->key)) {
702                 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource);
703                 return 1;
704         }
705
706         if (!ast_strlen_zero(mod->info->buildopt_sum) &&
707             strcmp(buildopt_sum, mod->info->buildopt_sum)) {
708                 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource);
709                 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource);
710                 return 1;
711         }
712
713         return 0;
714 }
715
716 static enum ast_module_load_result start_resource(struct ast_module *mod)
717 {
718         char tmp[256];
719         enum ast_module_load_result res;
720
721         if (!mod->info->load) {
722                 return AST_MODULE_LOAD_FAILURE;
723         }
724
725         res = mod->info->load();
726
727         switch (res) {
728         case AST_MODULE_LOAD_SUCCESS:
729                 if (!ast_fully_booted) {
730                         ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
731                         if (ast_opt_console && !option_verbose)
732                                 ast_verbose( ".");
733                 } else {
734                         ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description);
735                 }
736
737                 mod->flags.running = 1;
738
739                 ast_update_use_count();
740                 break;
741         case AST_MODULE_LOAD_DECLINE:
742                 mod->flags.declined = 1;
743                 break;
744         case AST_MODULE_LOAD_FAILURE:
745         case AST_MODULE_LOAD_SKIP: /* modules should never return this value */
746         case AST_MODULE_LOAD_PRIORITY:
747                 break;
748         }
749
750         return res;
751 }
752
753 /*! loads a resource based upon resource_name. If global_symbols_only is set
754  *  only modules with global symbols will be loaded.
755  *
756  *  If the ast_heap is provided (not NULL) the module is found and added to the
757  *  heap without running the module's load() function.  By doing this, modules
758  *  added to the resource_heap can be initilized later in order by priority. 
759  *
760  *  If the ast_heap is not provided, the module's load function will be executed
761  *  immediately */
762 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap)
763 {
764         struct ast_module *mod;
765         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
766
767         if ((mod = find_resource(resource_name, 0))) {
768                 if (mod->flags.running) {
769                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
770                         return AST_MODULE_LOAD_DECLINE;
771                 }
772                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
773                         return AST_MODULE_LOAD_SKIP;
774         } else {
775 #ifdef LOADABLE_MODULES
776                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
777                         /* don't generate a warning message during load_modules() */
778                         if (!global_symbols_only) {
779                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
780                                 return AST_MODULE_LOAD_DECLINE;
781                         } else {
782                                 return AST_MODULE_LOAD_SKIP;
783                         }
784                 }
785 #else
786                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
787                 return AST_MODULE_LOAD_DECLINE;
788 #endif
789         }
790
791         if (inspect_module(mod)) {
792                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
793 #ifdef LOADABLE_MODULES
794                 unload_dynamic_module(mod);
795 #endif
796                 return AST_MODULE_LOAD_DECLINE;
797         }
798
799         if (!mod->lib && mod->info->backup_globals()) {
800                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
801                 return AST_MODULE_LOAD_DECLINE;
802         }
803
804         mod->flags.declined = 0;
805
806         if (resource_heap) {
807                 ast_heap_push(resource_heap, mod);
808                 res = AST_MODULE_LOAD_PRIORITY;
809         } else {
810                 res = start_resource(mod);
811         }
812
813         return res;
814 }
815
816 int ast_load_resource(const char *resource_name)
817 {
818         int res;
819         AST_LIST_LOCK(&module_list);
820         res = load_resource(resource_name, 0, NULL);
821         AST_LIST_UNLOCK(&module_list);
822
823         return res;
824 }
825
826 struct load_order_entry {
827         char *resource;
828         AST_LIST_ENTRY(load_order_entry) entry;
829 };
830
831 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
832
833 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
834 {
835         struct load_order_entry *order;
836
837         AST_LIST_TRAVERSE(load_order, order, entry) {
838                 if (!resource_name_match(order->resource, resource))
839                         return NULL;
840         }
841
842         if (!(order = ast_calloc(1, sizeof(*order))))
843                 return NULL;
844
845         order->resource = ast_strdup(resource);
846         AST_LIST_INSERT_TAIL(load_order, order, entry);
847
848         return order;
849 }
850
851 static int mod_load_cmp(void *a, void *b)
852 {
853         struct ast_module *a_mod = (struct ast_module *) a;
854         struct ast_module *b_mod = (struct ast_module *) b;
855         int res = -1;
856         /* if load_pri is not set, default is 255.  Lower is better*/
857         unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255;
858         unsigned char b_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255;
859         if (a_pri == b_pri) {
860                 res = 0;
861         } else if (a_pri < b_pri) {
862                 res = 1;
863         }
864         return res;
865 }
866
867 /*! loads modules in order by load_pri, updates mod_count */
868 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
869 {
870         struct ast_heap *resource_heap;
871         struct load_order_entry *order;
872         struct ast_module *mod;
873         int count = 0;
874         int res = 0;
875
876         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
877                 return -1;
878         }
879
880         /* first, add find and add modules to heap */
881         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
882                 switch (load_resource(order->resource, global_symbols, resource_heap)) {
883                 case AST_MODULE_LOAD_SUCCESS:
884                 case AST_MODULE_LOAD_DECLINE:
885                         AST_LIST_REMOVE_CURRENT(entry);
886                         ast_free(order->resource);
887                         ast_free(order);
888                         break;
889                 case AST_MODULE_LOAD_FAILURE:
890                         res = -1;
891                         goto done;
892                 case AST_MODULE_LOAD_SKIP:
893                         break;
894                 case AST_MODULE_LOAD_PRIORITY:
895                         AST_LIST_REMOVE_CURRENT(entry);
896                         break;
897                 }
898         }
899         AST_LIST_TRAVERSE_SAFE_END;
900
901         /* second remove modules from heap sorted by priority */
902         while ((mod = ast_heap_pop(resource_heap))) {
903                 switch (start_resource(mod)) {
904                 case AST_MODULE_LOAD_SUCCESS:
905                         count++;
906                 case AST_MODULE_LOAD_DECLINE:
907                         break;
908                 case AST_MODULE_LOAD_FAILURE:
909                         res = -1;
910                         goto done;
911                 case AST_MODULE_LOAD_SKIP:
912                 case AST_MODULE_LOAD_PRIORITY:
913                         break;
914                 }
915         }
916
917 done:
918         if (mod_count) {
919                 *mod_count += count;
920         }
921         ast_heap_destroy(resource_heap);
922
923         return res;
924 }
925
926 int load_modules(unsigned int preload_only)
927 {
928         struct ast_config *cfg;
929         struct ast_module *mod;
930         struct load_order_entry *order;
931         struct ast_variable *v;
932         unsigned int load_count;
933         struct load_order load_order;
934         int res = 0;
935         struct ast_flags config_flags = { 0 };
936         int modulecount = 0;
937
938 #ifdef LOADABLE_MODULES
939         struct dirent *dirent;
940         DIR *dir;
941 #endif
942
943         /* all embedded modules have registered themselves by now */
944         embedding = 0;
945
946         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
947
948         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
949
950         AST_LIST_LOCK(&module_list);
951
952         if (embedded_module_list.first) {
953                 module_list.first = embedded_module_list.first;
954                 module_list.last = embedded_module_list.last;
955                 embedded_module_list.first = NULL;
956         }
957
958         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
959         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
960                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
961                 goto done;
962         }
963
964         /* first, find all the modules we have been explicitly requested to load */
965         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
966                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
967                         add_to_load_order(v->value, &load_order);
968                 }
969         }
970
971         /* check if 'autoload' is on */
972         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
973                 /* if so, first add all the embedded modules that are not already running to the load order */
974                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
975                         /* if it's not embedded, skip it */
976                         if (mod->lib)
977                                 continue;
978
979                         if (mod->flags.running)
980                                 continue;
981
982                         order = add_to_load_order(mod->resource, &load_order);
983                 }
984
985 #ifdef LOADABLE_MODULES
986                 /* if we are allowed to load dynamic modules, scan the directory for
987                    for all available modules and add them as well */
988                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
989                         while ((dirent = readdir(dir))) {
990                                 int ld = strlen(dirent->d_name);
991
992                                 /* Must end in .so to load it.  */
993
994                                 if (ld < 4)
995                                         continue;
996
997                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
998                                         continue;
999
1000                                 /* if there is already a module by this name in the module_list,
1001                                    skip this file */
1002                                 if (find_resource(dirent->d_name, 0))
1003                                         continue;
1004
1005                                 add_to_load_order(dirent->d_name, &load_order);
1006                         }
1007
1008                         closedir(dir);
1009                 } else {
1010                         if (!ast_opt_quiet)
1011                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1012                                         ast_config_AST_MODULE_DIR);
1013                 }
1014 #endif
1015         }
1016
1017         /* now scan the config for any modules we are prohibited from loading and
1018            remove them from the load order */
1019         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1020                 if (strcasecmp(v->name, "noload"))
1021                         continue;
1022
1023                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1024                         if (!resource_name_match(order->resource, v->value)) {
1025                                 AST_LIST_REMOVE_CURRENT(entry);
1026                                 ast_free(order->resource);
1027                                 ast_free(order);
1028                         }
1029                 }
1030                 AST_LIST_TRAVERSE_SAFE_END;
1031         }
1032
1033         /* we are done with the config now, all the information we need is in the
1034            load_order list */
1035         ast_config_destroy(cfg);
1036
1037         load_count = 0;
1038         AST_LIST_TRAVERSE(&load_order, order, entry)
1039                 load_count++;
1040
1041         if (load_count)
1042                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1043
1044         /* first, load only modules that provide global symbols */
1045         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1046                 goto done;
1047         }
1048
1049         /* now load everything else */
1050         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1051                 goto done;
1052         }
1053
1054 done:
1055         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1056                 ast_free(order->resource);
1057                 ast_free(order);
1058         }
1059
1060         AST_LIST_UNLOCK(&module_list);
1061         
1062         /* Tell manager clients that are aggressive at logging in that we're done
1063            loading modules. If there's a DNS problem in chan_sip, we might not
1064            even reach this */
1065         manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1066         
1067         return res;
1068 }
1069
1070 void ast_update_use_count(void)
1071 {
1072         /* Notify any module monitors that the use count for a
1073            resource has changed */
1074         struct loadupdate *m;
1075
1076         AST_LIST_LOCK(&updaters);
1077         AST_LIST_TRAVERSE(&updaters, m, entry)
1078                 m->updater();
1079         AST_LIST_UNLOCK(&updaters);
1080 }
1081
1082 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
1083                            const char *like)
1084 {
1085         struct ast_module *cur;
1086         int unlock = -1;
1087         int total_mod_loaded = 0;
1088
1089         if (AST_LIST_TRYLOCK(&module_list))
1090                 unlock = 0;
1091  
1092         AST_LIST_TRAVERSE(&module_list, cur, entry) {
1093                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1094         }
1095
1096         if (unlock)
1097                 AST_LIST_UNLOCK(&module_list);
1098
1099         return total_mod_loaded;
1100 }
1101
1102 /*! \brief Check if module exists */
1103 int ast_module_check(const char *name)
1104 {
1105         struct ast_module *cur;
1106
1107         if (ast_strlen_zero(name))
1108                 return 0;       /* FALSE */
1109
1110         cur = find_resource(name, 1);
1111
1112         return (cur != NULL);
1113 }
1114
1115
1116 int ast_loader_register(int (*v)(void))
1117 {
1118         struct loadupdate *tmp;
1119
1120         if (!(tmp = ast_malloc(sizeof(*tmp))))
1121                 return -1;
1122
1123         tmp->updater = v;
1124         AST_LIST_LOCK(&updaters);
1125         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1126         AST_LIST_UNLOCK(&updaters);
1127
1128         return 0;
1129 }
1130
1131 int ast_loader_unregister(int (*v)(void))
1132 {
1133         struct loadupdate *cur;
1134
1135         AST_LIST_LOCK(&updaters);
1136         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1137                 if (cur->updater == v)  {
1138                         AST_LIST_REMOVE_CURRENT(entry);
1139                         break;
1140                 }
1141         }
1142         AST_LIST_TRAVERSE_SAFE_END;
1143         AST_LIST_UNLOCK(&updaters);
1144
1145         return cur ? 0 : -1;
1146 }
1147
1148 struct ast_module *ast_module_ref(struct ast_module *mod)
1149 {
1150         ast_atomic_fetchadd_int(&mod->usecount, +1);
1151         ast_update_use_count();
1152
1153         return mod;
1154 }
1155
1156 void ast_module_unref(struct ast_module *mod)
1157 {
1158         ast_atomic_fetchadd_int(&mod->usecount, -1);
1159         ast_update_use_count();
1160 }