module load priority
[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 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                 break;
746         case AST_MODULE_LOAD_SKIP:
747                 /* modules should never return this value */
748                 break;
749         }
750
751         return res;
752 }
753
754 /*! loads a resource based upon resource_name. If global_symbols_only is set
755  *  only modules with global symbols will be loaded.
756  *
757  *  If the ast_heap is provided (not NULL) the module is found and added to the
758  *  heap without running the module's load() function.  By doing this, modules
759  *  added to the resource_heap can be initilized later in order by priority. 
760  *
761  *  If the ast_heap is not provided, the module's load function will be executed
762  *  immediately */
763 static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap)
764 {
765         struct ast_module *mod;
766         enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
767
768         if ((mod = find_resource(resource_name, 0))) {
769                 if (mod->flags.running) {
770                         ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name);
771                         return AST_MODULE_LOAD_DECLINE;
772                 }
773                 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))
774                         return AST_MODULE_LOAD_SKIP;
775         } else {
776 #ifdef LOADABLE_MODULES
777                 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) {
778                         /* don't generate a warning message during load_modules() */
779                         if (!global_symbols_only) {
780                                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
781                                 return AST_MODULE_LOAD_DECLINE;
782                         } else {
783                                 return AST_MODULE_LOAD_SKIP;
784                         }
785                 }
786 #else
787                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
788                 return AST_MODULE_LOAD_DECLINE;
789 #endif
790         }
791
792         if (inspect_module(mod)) {
793                 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
794 #ifdef LOADABLE_MODULES
795                 unload_dynamic_module(mod);
796 #endif
797                 return AST_MODULE_LOAD_DECLINE;
798         }
799
800         if (!mod->lib && mod->info->backup_globals()) {
801                 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
802                 return AST_MODULE_LOAD_DECLINE;
803         }
804
805         mod->flags.declined = 0;
806
807         if (resource_heap) {
808                 ast_heap_push(resource_heap, mod);
809                 res = AST_MODULE_LOAD_SKIP;
810         } else {
811                 res = start_resource(mod);
812         }
813
814         return res;
815 }
816
817 int ast_load_resource(const char *resource_name)
818 {
819         int res;
820         AST_LIST_LOCK(&module_list);
821         res = load_resource(resource_name, 0, NULL);
822         AST_LIST_UNLOCK(&module_list);
823
824         return res;
825 }
826
827 struct load_order_entry {
828         char *resource;
829         AST_LIST_ENTRY(load_order_entry) entry;
830 };
831
832 AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
833
834 static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order)
835 {
836         struct load_order_entry *order;
837
838         AST_LIST_TRAVERSE(load_order, order, entry) {
839                 if (!resource_name_match(order->resource, resource))
840                         return NULL;
841         }
842
843         if (!(order = ast_calloc(1, sizeof(*order))))
844                 return NULL;
845
846         order->resource = ast_strdup(resource);
847         AST_LIST_INSERT_TAIL(load_order, order, entry);
848
849         return order;
850 }
851
852 static int mod_load_cmp(void *a, void *b)
853 {
854         struct ast_module *a_mod = (struct ast_module *) a;
855         struct ast_module *b_mod = (struct ast_module *) b;
856         int res = -1;
857         /* if load_pri is not set, default is 255.  Lower is better*/
858         unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255;
859         unsigned char b_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255;
860         if (a_pri == b_pri) {
861                 res = 0;
862         } else if (a_pri < b_pri) {
863                 res = 1;
864         }
865         return res;
866 }
867
868 /*! loads modules in order by load_pri, updates mod_count */
869 static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
870 {
871         struct ast_heap *resource_heap;
872         struct load_order_entry *order;
873         struct ast_module *mod;
874         int count = 0;
875         int res = 0;
876
877         if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
878                 return -1;
879         }
880
881         /* first, add find and add modules to heap */
882         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
883                 switch (load_resource(order->resource, global_symbols, resource_heap)) {
884                 case AST_MODULE_LOAD_SUCCESS:
885                 case AST_MODULE_LOAD_DECLINE:
886                         AST_LIST_REMOVE_CURRENT(entry);
887                         ast_free(order->resource);
888                         ast_free(order);
889                         break;
890                 case AST_MODULE_LOAD_FAILURE:
891                         res = -1;
892                         goto done;
893                 case AST_MODULE_LOAD_SKIP:
894                         break;
895                 }
896         }
897         AST_LIST_TRAVERSE_SAFE_END;
898
899         /* second remove modules from heap sorted by priority */
900         while ((mod = ast_heap_pop(resource_heap))) {
901                 switch (start_resource(mod)) {
902                 case AST_MODULE_LOAD_SUCCESS:
903                         count++;
904                 case AST_MODULE_LOAD_DECLINE:
905                         break;
906                 case AST_MODULE_LOAD_FAILURE:
907                         res = -1;
908                         goto done;
909                 case AST_MODULE_LOAD_SKIP:
910                         break;
911                 }
912         }
913
914 done:
915         if (mod_count) {
916                 *mod_count += count;
917         }
918         ast_heap_destroy(resource_heap);
919
920         return res;
921 }
922
923 int load_modules(unsigned int preload_only)
924 {
925         struct ast_config *cfg;
926         struct ast_module *mod;
927         struct load_order_entry *order;
928         struct ast_variable *v;
929         unsigned int load_count;
930         struct load_order load_order;
931         int res = 0;
932         struct ast_flags config_flags = { 0 };
933         int modulecount = 0;
934
935 #ifdef LOADABLE_MODULES
936         struct dirent *dirent;
937         DIR *dir;
938 #endif
939
940         /* all embedded modules have registered themselves by now */
941         embedding = 0;
942
943         ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
944
945         AST_LIST_HEAD_INIT_NOLOCK(&load_order);
946
947         AST_LIST_LOCK(&module_list);
948
949         if (embedded_module_list.first) {
950                 module_list.first = embedded_module_list.first;
951                 module_list.last = embedded_module_list.last;
952                 embedded_module_list.first = NULL;
953         }
954
955         cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);
956         if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
957                 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);
958                 goto done;
959         }
960
961         /* first, find all the modules we have been explicitly requested to load */
962         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
963                 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
964                         add_to_load_order(v->value, &load_order);
965                 }
966         }
967
968         /* check if 'autoload' is on */
969         if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {
970                 /* if so, first add all the embedded modules that are not already running to the load order */
971                 AST_LIST_TRAVERSE(&module_list, mod, entry) {
972                         /* if it's not embedded, skip it */
973                         if (mod->lib)
974                                 continue;
975
976                         if (mod->flags.running)
977                                 continue;
978
979                         order = add_to_load_order(mod->resource, &load_order);
980                 }
981
982 #ifdef LOADABLE_MODULES
983                 /* if we are allowed to load dynamic modules, scan the directory for
984                    for all available modules and add them as well */
985                 if ((dir  = opendir(ast_config_AST_MODULE_DIR))) {
986                         while ((dirent = readdir(dir))) {
987                                 int ld = strlen(dirent->d_name);
988
989                                 /* Must end in .so to load it.  */
990
991                                 if (ld < 4)
992                                         continue;
993
994                                 if (strcasecmp(dirent->d_name + ld - 3, ".so"))
995                                         continue;
996
997                                 /* if there is already a module by this name in the module_list,
998                                    skip this file */
999                                 if (find_resource(dirent->d_name, 0))
1000                                         continue;
1001
1002                                 add_to_load_order(dirent->d_name, &load_order);
1003                         }
1004
1005                         closedir(dir);
1006                 } else {
1007                         if (!ast_opt_quiet)
1008                                 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",
1009                                         ast_config_AST_MODULE_DIR);
1010                 }
1011 #endif
1012         }
1013
1014         /* now scan the config for any modules we are prohibited from loading and
1015            remove them from the load order */
1016         for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
1017                 if (strcasecmp(v->name, "noload"))
1018                         continue;
1019
1020                 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
1021                         if (!resource_name_match(order->resource, v->value)) {
1022                                 AST_LIST_REMOVE_CURRENT(entry);
1023                                 ast_free(order->resource);
1024                                 ast_free(order);
1025                         }
1026                 }
1027                 AST_LIST_TRAVERSE_SAFE_END;
1028         }
1029
1030         /* we are done with the config now, all the information we need is in the
1031            load_order list */
1032         ast_config_destroy(cfg);
1033
1034         load_count = 0;
1035         AST_LIST_TRAVERSE(&load_order, order, entry)
1036                 load_count++;
1037
1038         if (load_count)
1039                 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
1040
1041         /* first, load only modules that provide global symbols */
1042         if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
1043                 goto done;
1044         }
1045
1046         /* now load everything else */
1047         if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) {
1048                 goto done;
1049         }
1050
1051 done:
1052         while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) {
1053                 ast_free(order->resource);
1054                 ast_free(order);
1055         }
1056
1057         AST_LIST_UNLOCK(&module_list);
1058         
1059         /* Tell manager clients that are aggressive at logging in that we're done
1060            loading modules. If there's a DNS problem in chan_sip, we might not
1061            even reach this */
1062         manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount);
1063         
1064         return res;
1065 }
1066
1067 void ast_update_use_count(void)
1068 {
1069         /* Notify any module monitors that the use count for a
1070            resource has changed */
1071         struct loadupdate *m;
1072
1073         AST_LIST_LOCK(&updaters);
1074         AST_LIST_TRAVERSE(&updaters, m, entry)
1075                 m->updater();
1076         AST_LIST_UNLOCK(&updaters);
1077 }
1078
1079 int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
1080                            const char *like)
1081 {
1082         struct ast_module *cur;
1083         int unlock = -1;
1084         int total_mod_loaded = 0;
1085
1086         if (AST_LIST_TRYLOCK(&module_list))
1087                 unlock = 0;
1088  
1089         AST_LIST_TRAVERSE(&module_list, cur, entry) {
1090                 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like);
1091         }
1092
1093         if (unlock)
1094                 AST_LIST_UNLOCK(&module_list);
1095
1096         return total_mod_loaded;
1097 }
1098
1099 /*! \brief Check if module exists */
1100 int ast_module_check(const char *name)
1101 {
1102         struct ast_module *cur;
1103
1104         if (ast_strlen_zero(name))
1105                 return 0;       /* FALSE */
1106
1107         cur = find_resource(name, 1);
1108
1109         return (cur != NULL);
1110 }
1111
1112
1113 int ast_loader_register(int (*v)(void))
1114 {
1115         struct loadupdate *tmp;
1116
1117         if (!(tmp = ast_malloc(sizeof(*tmp))))
1118                 return -1;
1119
1120         tmp->updater = v;
1121         AST_LIST_LOCK(&updaters);
1122         AST_LIST_INSERT_HEAD(&updaters, tmp, entry);
1123         AST_LIST_UNLOCK(&updaters);
1124
1125         return 0;
1126 }
1127
1128 int ast_loader_unregister(int (*v)(void))
1129 {
1130         struct loadupdate *cur;
1131
1132         AST_LIST_LOCK(&updaters);
1133         AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) {
1134                 if (cur->updater == v)  {
1135                         AST_LIST_REMOVE_CURRENT(entry);
1136                         break;
1137                 }
1138         }
1139         AST_LIST_TRAVERSE_SAFE_END;
1140         AST_LIST_UNLOCK(&updaters);
1141
1142         return cur ? 0 : -1;
1143 }
1144
1145 struct ast_module *ast_module_ref(struct ast_module *mod)
1146 {
1147         ast_atomic_fetchadd_int(&mod->usecount, +1);
1148         ast_update_use_count();
1149
1150         return mod;
1151 }
1152
1153 void ast_module_unref(struct ast_module *mod)
1154 {
1155         ast_atomic_fetchadd_int(&mod->usecount, -1);
1156         ast_update_use_count();
1157 }