Module Loader. More...
#include "asterisk.h"#include "asterisk/_private.h"#include "asterisk/paths.h"#include <dirent.h>#include "asterisk/linkedlists.h"#include "asterisk/module.h"#include "asterisk/config.h"#include "asterisk/channel.h"#include "asterisk/term.h"#include "asterisk/manager.h"#include "asterisk/cdr.h"#include "asterisk/enum.h"#include "asterisk/rtp.h"#include "asterisk/http.h"#include "asterisk/lock.h"#include "asterisk/features.h"#include "asterisk/dsp.h"#include "asterisk/udptl.h"#include "asterisk/heap.h"#include <dlfcn.h>#include "asterisk/md5.h"#include "asterisk/utils.h"
Go to the source code of this file.
Data Structures | |
| struct | ast_module |
| struct | ast_module_user |
| struct | load_order_entry |
| struct | loadupdate |
| struct | reload_classes |
| struct | reload_queue_item |
Defines | |
| #define | RTLD_LOCAL 0 |
| #define | RTLD_NOW 0 |
Functions | |
| struct ast_module_user * | __ast_module_user_add (struct ast_module *mod, struct ast_channel *chan) |
| void | __ast_module_user_hangup_all (struct ast_module *mod) |
| void | __ast_module_user_remove (struct ast_module *mod, struct ast_module_user *u) |
| static struct load_order_entry * | add_to_load_order (const char *resource, struct load_order *load_order) |
| AST_LIST_HEAD (module_user_list, ast_module_user) | |
| AST_LIST_HEAD_NOLOCK (load_order, load_order_entry) | |
| static | AST_LIST_HEAD_STATIC (reload_queue, reload_queue_item) |
| static | AST_LIST_HEAD_STATIC (updaters, loadupdate) |
| static | AST_LIST_HEAD_STATIC (module_list, ast_module) |
| int | ast_load_resource (const char *resource_name) |
| Load a module. | |
| int | ast_loader_register (int(*v)(void)) |
| Add a procedure to be run when modules have been updated. | |
| int | ast_loader_unregister (int(*v)(void)) |
| Remove a procedure to be run when modules are updated. | |
| int | ast_module_check (const char *name) |
| Check if module exists. | |
| char * | ast_module_helper (const char *line, const char *word, int pos, int state, int rpos, int needsreload) |
| Match modules names for the Asterisk cli. | |
| struct ast_module * | ast_module_ref (struct ast_module *mod) |
| void | ast_module_register (const struct ast_module_info *info) |
| int | ast_module_reload (const char *name) |
| Reload asterisk modules. | |
| void | ast_module_shutdown (void) |
| Run the unload() callback for all loaded modules. | |
| void | ast_module_unref (struct ast_module *mod) |
| void | ast_module_unregister (const struct ast_module_info *info) |
| AST_MUTEX_DEFINE_STATIC (reloadlock) | |
| void | ast_process_pending_reloads (void) |
| Process reload requests received during startup. | |
| int | ast_unload_resource (const char *resource_name, enum ast_module_unload_mode force) |
| Unload a module. | |
| int | ast_update_module_list (int(*modentry)(const char *module, const char *description, int usecnt, const char *like), const char *like) |
| Ask for a list of modules, descriptions, and use counts. | |
| void | ast_update_use_count (void) |
| Notify when usecount has been changed. | |
| static struct ast_module * | find_resource (const char *resource, int do_lock) |
| static unsigned int | inspect_module (const struct ast_module *mod) |
| static int | key_matches (const unsigned char *key1, const unsigned char *key2) |
| int | load_modules (unsigned int preload_only) |
| static enum ast_module_load_result | load_resource (const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap) |
| static int | load_resource_list (struct load_order *load_order, unsigned int global_symbols, int *mod_count) |
| static int | mod_load_cmp (void *a, void *b) |
| static int | printdigest (const unsigned char *d) |
| static void | queue_reload_request (const char *module) |
| static int | resource_name_match (const char *name1_in, const char *name2_in) |
| static enum ast_module_load_result | start_resource (struct ast_module *mod) |
| static int | verify_key (const unsigned char *key) |
Variables | |
| static char | buildopt_sum [33] = AST_BUILDOPT_SUM |
| static int | do_full_reload = 0 |
| static struct module_list | embedded_module_list |
| static unsigned int | embedding = 1 |
| static unsigned char | expected_key [] |
| struct ast_module * | resource_being_loaded |
Module Loader.
Definition in file loader.c.
| struct ast_module_user* __ast_module_user_add | ( | struct ast_module * | mod, | |
| struct ast_channel * | chan | |||
| ) | [read] |
Definition at line 195 of file loader.c.
References ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_update_use_count(), ast_module_user::chan, ast_module::usecount, and ast_module::users.
Referenced by ast_func_read(), ast_func_write(), and pbx_exec().
00197 { 00198 struct ast_module_user *u = ast_calloc(1, sizeof(*u)); 00199 00200 if (!u) 00201 return NULL; 00202 00203 u->chan = chan; 00204 00205 AST_LIST_LOCK(&mod->users); 00206 AST_LIST_INSERT_HEAD(&mod->users, u, entry); 00207 AST_LIST_UNLOCK(&mod->users); 00208 00209 ast_atomic_fetchadd_int(&mod->usecount, +1); 00210 00211 ast_update_use_count(); 00212 00213 return u; 00214 }
| void __ast_module_user_hangup_all | ( | struct ast_module * | mod | ) |
Definition at line 227 of file loader.c.
References ast_atomic_fetchadd_int(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_update_use_count(), ast_module_user::chan, ast_module::usecount, and ast_module::users.
Referenced by ast_unload_resource().
00228 { 00229 struct ast_module_user *u; 00230 00231 AST_LIST_LOCK(&mod->users); 00232 while ((u = AST_LIST_REMOVE_HEAD(&mod->users, entry))) { 00233 ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD); 00234 ast_atomic_fetchadd_int(&mod->usecount, -1); 00235 ast_free(u); 00236 } 00237 AST_LIST_UNLOCK(&mod->users); 00238 00239 ast_update_use_count(); 00240 }
| void __ast_module_user_remove | ( | struct ast_module * | mod, | |
| struct ast_module_user * | u | |||
| ) |
Definition at line 216 of file loader.c.
References ast_atomic_fetchadd_int(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_update_use_count(), ast_module::usecount, and ast_module::users.
Referenced by ast_func_read(), ast_func_write(), and pbx_exec().
00217 { 00218 AST_LIST_LOCK(&mod->users); 00219 AST_LIST_REMOVE(&mod->users, u, entry); 00220 AST_LIST_UNLOCK(&mod->users); 00221 ast_atomic_fetchadd_int(&mod->usecount, -1); 00222 ast_free(u); 00223 00224 ast_update_use_count(); 00225 }
| static struct load_order_entry* add_to_load_order | ( | const char * | resource, | |
| struct load_order * | load_order | |||
| ) | [static, read] |
Definition at line 847 of file loader.c.
References ast_calloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_strdup, load_order_entry::resource, and resource_name_match().
Referenced by load_modules().
00848 { 00849 struct load_order_entry *order; 00850 00851 AST_LIST_TRAVERSE(load_order, order, entry) { 00852 if (!resource_name_match(order->resource, resource)) 00853 return NULL; 00854 } 00855 00856 if (!(order = ast_calloc(1, sizeof(*order)))) 00857 return NULL; 00858 00859 order->resource = ast_strdup(resource); 00860 AST_LIST_INSERT_TAIL(load_order, order, entry); 00861 00862 return order; 00863 }
| AST_LIST_HEAD | ( | module_user_list | , | |
| ast_module_user | ||||
| ) |
| AST_LIST_HEAD_NOLOCK | ( | load_order | , | |
| load_order_entry | ||||
| ) |
| static AST_LIST_HEAD_STATIC | ( | reload_queue | , | |
| reload_queue_item | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | updaters | , | |
| loadupdate | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | module_list | , | |
| ast_module | ||||
| ) | [static] |
| int ast_load_resource | ( | const char * | resource_name | ) |
Load a module.
| resource_name | The name of the module to load. |
This function is run by the PBX to load the modules. It performs all loading and initialization tasks. Basically, to load a module, just give it the name of the module and it will do the rest.
Definition at line 830 of file loader.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, and load_resource().
Referenced by file_ok_sel(), handle_load(), load_module(), manager_moduleload(), and reload().
00831 { 00832 int res; 00833 AST_LIST_LOCK(&module_list); 00834 res = load_resource(resource_name, 0, NULL); 00835 AST_LIST_UNLOCK(&module_list); 00836 00837 return res; 00838 }
| int ast_loader_register | ( | int(*)(void) | updater | ) |
Add a procedure to be run when modules have been updated.
| updater | The function to run when modules have been updated. |
This function adds the given function to a linked list of functions to be run when the modules are updated.
| 0 | on success | |
| -1 | on failure. |
Definition at line 1129 of file loader.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_malloc, and loadupdate::updater.
Referenced by show_console().
01130 { 01131 struct loadupdate *tmp; 01132 01133 if (!(tmp = ast_malloc(sizeof(*tmp)))) 01134 return -1; 01135 01136 tmp->updater = v; 01137 AST_LIST_LOCK(&updaters); 01138 AST_LIST_INSERT_HEAD(&updaters, tmp, entry); 01139 AST_LIST_UNLOCK(&updaters); 01140 01141 return 0; 01142 }
| int ast_loader_unregister | ( | int(*)(void) | updater | ) |
Remove a procedure to be run when modules are updated.
| updater | The updater function to unregister. |
This removes the given function from the updater list.
| 0 | on success | |
| -1 | on failure. |
Definition at line 1144 of file loader.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, and loadupdate::updater.
Referenced by exit_now().
01145 { 01146 struct loadupdate *cur; 01147 01148 AST_LIST_LOCK(&updaters); 01149 AST_LIST_TRAVERSE_SAFE_BEGIN(&updaters, cur, entry) { 01150 if (cur->updater == v) { 01151 AST_LIST_REMOVE_CURRENT(entry); 01152 break; 01153 } 01154 } 01155 AST_LIST_TRAVERSE_SAFE_END; 01156 AST_LIST_UNLOCK(&updaters); 01157 01158 return cur ? 0 : -1; 01159 }
| int ast_module_check | ( | const char * | name | ) |
Check if module exists.
Check if module with the name given is loaded.
Definition at line 1116 of file loader.c.
References ast_strlen_zero(), and find_resource().
Referenced by ifmodule_read(), load_module(), manager_modulecheck(), and unload_module().
01117 { 01118 struct ast_module *cur; 01119 01120 if (ast_strlen_zero(name)) 01121 return 0; /* FALSE */ 01122 01123 cur = find_resource(name, 1); 01124 01125 return (cur != NULL); 01126 }
| char* ast_module_helper | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| int | rpos, | |||
| int | needsreload | |||
| ) |
Match modules names for the Asterisk cli.
| line | Unused by this function, but this should be the line we are matching. | |
| word | The partial name to match. | |
| pos | The position the word we are completing is in. | |
| state | The possible match to return. | |
| rpos | The position we should be matching. This should be the same as pos. | |
| needsreload | This should be 1 if we need to reload this module and 0 otherwise. This function will only return modules that are reloadble if this is 1. |
| A | possible completion of the partial match. | |
| NULL | if no matches were found. |
Definition at line 541 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strdup, ast_module::info, name, and ast_module_info::reload.
Referenced by handle_modlist(), handle_reload(), handle_unload(), and load_module().
00542 { 00543 struct ast_module *cur; 00544 int i, which=0, l = strlen(word); 00545 char *ret = NULL; 00546 00547 if (pos != rpos) 00548 return NULL; 00549 00550 AST_LIST_LOCK(&module_list); 00551 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00552 if (!strncasecmp(word, cur->resource, l) && 00553 (cur->info->reload || !needsreload) && 00554 ++which > state) { 00555 ret = ast_strdup(cur->resource); 00556 break; 00557 } 00558 } 00559 AST_LIST_UNLOCK(&module_list); 00560 00561 if (!ret) { 00562 for (i=0; !ret && reload_classes[i].name; i++) { 00563 if (!strncasecmp(word, reload_classes[i].name, l) && ++which > state) 00564 ret = ast_strdup(reload_classes[i].name); 00565 } 00566 } 00567 00568 return ret; 00569 }
| struct ast_module* ast_module_ref | ( | struct ast_module * | mod | ) | [read] |
Definition at line 1161 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by __oh323_new(), agi_handle_command(), alsa_new(), ast_agi_register(), ast_iax2_new(), ast_timer_open(), dahdi_new(), fn_wrapper(), gtalk_new(), handle_cli_file_convert(), handle_orig(), mgcp_new(), moh_alloc(), moh_files_alloc(), newpvt(), oss_new(), phone_check_exception(), phone_new(), sip_new(), skinny_new(), smdi_load(), and usbradio_new().
01162 { 01163 ast_atomic_fetchadd_int(&mod->usecount, +1); 01164 ast_update_use_count(); 01165 01166 return mod; 01167 }
| void ast_module_register | ( | const struct ast_module_info * | info | ) |
Definition at line 133 of file loader.c.
References ast_calloc, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, embedded_module_list, embedding, ast_module::info, ast_module_info::name, resource_being_loaded, ast_module_info::self, and ast_module::users.
00134 { 00135 struct ast_module *mod; 00136 00137 if (embedding) { 00138 if (!(mod = ast_calloc(1, sizeof(*mod) + strlen(info->name) + 1))) 00139 return; 00140 strcpy(mod->resource, info->name); 00141 } else { 00142 mod = resource_being_loaded; 00143 } 00144 00145 mod->info = info; 00146 AST_LIST_HEAD_INIT(&mod->users); 00147 00148 /* during startup, before the loader has been initialized, 00149 there are no threads, so there is no need to take the lock 00150 on this list to manipulate it. it is also possible that it 00151 might be unsafe to use the list lock at that point... so 00152 let's avoid it altogether 00153 */ 00154 if (embedding) { 00155 AST_LIST_INSERT_TAIL(&embedded_module_list, mod, entry); 00156 } else { 00157 AST_LIST_LOCK(&module_list); 00158 /* it is paramount that the new entry be placed at the tail of 00159 the list, otherwise the code that uses dlopen() to load 00160 dynamic modules won't be able to find out if the module it 00161 just opened was registered or failed to load 00162 */ 00163 AST_LIST_INSERT_TAIL(&module_list, mod, entry); 00164 AST_LIST_UNLOCK(&module_list); 00165 } 00166 00167 /* give the module a copy of its own handle, for later use in registrations and the like */ 00168 *((struct ast_module **) &(info->self)) = mod; 00169 }
| int ast_module_reload | ( | const char * | name | ) |
Reload asterisk modules.
| name | the name of the module to reload |
This function reloads the specified module, or if no modules are specified, it will reload all loaded modules.
| 1 | if the module was found but cannot be reloaded. | |
| -1 | if a reload operation is already in progress. | |
| 2 | if the specfied module was found and reloaded. |
Definition at line 636 of file loader.c.
References ast_fully_booted, ast_lastreloadtime, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_tvnow(), ast_verb, ast_verbose, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, LOG_NOTICE, queue_reload_request(), ast_module_info::reload, resource_name_match(), and ast_module::running.
Referenced by action_reload(), action_updateconfig(), ast_process_pending_reloads(), handle_reload(), manager_moduleload(), and monitor_sig_flags().
00637 { 00638 struct ast_module *cur; 00639 int res = 0; /* return value. 0 = not found, others, see below */ 00640 int i; 00641 00642 /* If we aren't fully booted, we just pretend we reloaded but we queue this 00643 up to run once we are booted up. */ 00644 if (!ast_fully_booted) { 00645 queue_reload_request(name); 00646 return 0; 00647 } 00648 00649 if (ast_mutex_trylock(&reloadlock)) { 00650 ast_verbose("The previous reload command didn't finish yet\n"); 00651 return -1; /* reload already in progress */ 00652 } 00653 ast_lastreloadtime = ast_tvnow(); 00654 00655 /* Call "predefined" reload here first */ 00656 for (i = 0; reload_classes[i].name; i++) { 00657 if (!name || !strcasecmp(name, reload_classes[i].name)) { 00658 reload_classes[i].reload_fn(); /* XXX should check error ? */ 00659 res = 2; /* found and reloaded */ 00660 } 00661 } 00662 00663 if (name && res) { 00664 ast_mutex_unlock(&reloadlock); 00665 return res; 00666 } 00667 00668 AST_LIST_LOCK(&module_list); 00669 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00670 const struct ast_module_info *info = cur->info; 00671 00672 if (name && resource_name_match(name, cur->resource)) 00673 continue; 00674 00675 if (!cur->flags.running || cur->flags.declined) { 00676 if (!name) 00677 continue; 00678 ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. " 00679 "Before reloading the module, you must run \"module load %s\" " 00680 "and fix whatever is preventing the module from being initialized.\n", 00681 name, name); 00682 res = 2; /* Don't report that the module was not found */ 00683 break; 00684 } 00685 00686 if (!info->reload) { /* cannot be reloaded */ 00687 if (res < 1) /* store result if possible */ 00688 res = 1; /* 1 = no reload() method */ 00689 continue; 00690 } 00691 00692 res = 2; 00693 ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description); 00694 info->reload(); 00695 } 00696 AST_LIST_UNLOCK(&module_list); 00697 00698 ast_mutex_unlock(&reloadlock); 00699 00700 return res; 00701 }
| void ast_module_shutdown | ( | void | ) |
Run the unload() callback for all loaded modules.
This function should be called when Asterisk is shutting down gracefully.
Definition at line 443 of file loader.c.
References AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, free, ast_module::info, ast_module_info::unload, ast_module::usecount, and ast_module::users.
Referenced by quit_handler().
00444 { 00445 struct ast_module *mod; 00446 int somethingchanged = 1, final = 0; 00447 00448 AST_LIST_LOCK(&module_list); 00449 00450 /*!\note Some resources, like timers, are started up dynamically, and thus 00451 * may be still in use, even if all channels are dead. We must therefore 00452 * check the usecount before asking modules to unload. */ 00453 do { 00454 if (!somethingchanged) { 00455 /*!\note If we go through the entire list without changing 00456 * anything, ignore the usecounts and unload, then exit. */ 00457 final = 1; 00458 } 00459 00460 /* Reset flag before traversing the list */ 00461 somethingchanged = 0; 00462 00463 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00464 if (!final && mod->usecount) { 00465 continue; 00466 } 00467 AST_LIST_REMOVE_CURRENT(entry); 00468 if (mod->info->unload) { 00469 mod->info->unload(); 00470 } 00471 AST_LIST_HEAD_DESTROY(&mod->users); 00472 free(mod); 00473 somethingchanged = 1; 00474 } 00475 AST_LIST_TRAVERSE_SAFE_END; 00476 } while (somethingchanged && !final); 00477 00478 AST_LIST_UNLOCK(&module_list); 00479 }
| void ast_module_unref | ( | struct ast_module * | mod | ) |
Definition at line 1169 of file loader.c.
References ast_atomic_fetchadd_int(), ast_update_use_count(), and ast_module::usecount.
Referenced by agi_handle_command(), alsa_hangup(), ast_agi_unregister(), ast_smdi_interface_destroy(), ast_timer_close(), dahdi_destroy_channel_bynum(), dahdi_hangup(), destroy(), filestream_destructor(), gtalk_hangup(), handle_cli_file_convert(), handle_orig(), iax2_predestroy(), local_ast_moh_cleanup(), mgcp_hangup(), oh323_hangup(), oss_hangup(), phone_check_exception(), phone_hangup(), sip_hangup(), and usbradio_hangup().
01170 { 01171 ast_atomic_fetchadd_int(&mod->usecount, -1); 01172 ast_update_use_count(); 01173 }
| void ast_module_unregister | ( | const struct ast_module_info * | info | ) |
Definition at line 171 of file loader.c.
References ast_free, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_module::info, and ast_module::users.
00172 { 00173 struct ast_module *mod = NULL; 00174 00175 /* it is assumed that the users list in the module structure 00176 will already be empty, or we cannot have gotten to this 00177 point 00178 */ 00179 AST_LIST_LOCK(&module_list); 00180 AST_LIST_TRAVERSE_SAFE_BEGIN(&module_list, mod, entry) { 00181 if (mod->info == info) { 00182 AST_LIST_REMOVE_CURRENT(entry); 00183 break; 00184 } 00185 } 00186 AST_LIST_TRAVERSE_SAFE_END; 00187 AST_LIST_UNLOCK(&module_list); 00188 00189 if (mod) { 00190 AST_LIST_HEAD_DESTROY(&mod->users); 00191 ast_free(mod); 00192 } 00193 }
| AST_MUTEX_DEFINE_STATIC | ( | reloadlock | ) |
| void ast_process_pending_reloads | ( | void | ) |
Process reload requests received during startup.
This function requests that the loader execute the pending reload requests that were queued during server startup.
Definition at line 571 of file loader.c.
References ast_free, ast_fully_booted, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_module_reload(), do_full_reload, and LOG_NOTICE.
Referenced by main().
00572 { 00573 struct reload_queue_item *item; 00574 00575 if (!ast_fully_booted) { 00576 return; 00577 } 00578 00579 AST_LIST_LOCK(&reload_queue); 00580 00581 if (do_full_reload) { 00582 do_full_reload = 0; 00583 AST_LIST_UNLOCK(&reload_queue); 00584 ast_log(LOG_NOTICE, "Executing deferred reload request.\n"); 00585 ast_module_reload(NULL); 00586 return; 00587 } 00588 00589 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00590 ast_log(LOG_NOTICE, "Executing deferred reload request for module '%s'.\n", item->module); 00591 ast_module_reload(item->module); 00592 ast_free(item); 00593 } 00594 00595 AST_LIST_UNLOCK(&reload_queue); 00596 }
| int ast_unload_resource | ( | const char * | resource_name, | |
| enum | ast_module_unload_mode | |||
| ) |
Unload a module.
| resource_name | The name of the module to unload. | |
| ast_module_unload_mode | The force flag. This should be set using one of the AST_FORCE flags. |
This function unloads a module. It will only unload modules that are not in use (usecount not zero), unless AST_FORCE_FIRM or AST_FORCE_HARD is specified. Setting AST_FORCE_FIRM or AST_FORCE_HARD will unload the module regardless of consequences (NOT RECOMMENDED).
| 0 | on success. | |
| -1 | on error. |
Definition at line 481 of file loader.c.
References __ast_module_user_hangup_all(), AST_FORCE_FIRM, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_update_use_count(), ast_module::declined, find_resource(), ast_module::flags, ast_module::info, ast_module::lib, LOG_WARNING, ast_module_info::restore_globals, ast_module::running, ast_module_info::unload, and ast_module::usecount.
Referenced by exit_now(), handle_unload(), manager_moduleload(), reload(), and remove_module().
00482 { 00483 struct ast_module *mod; 00484 int res = -1; 00485 int error = 0; 00486 00487 AST_LIST_LOCK(&module_list); 00488 00489 if (!(mod = find_resource(resource_name, 0))) { 00490 AST_LIST_UNLOCK(&module_list); 00491 ast_log(LOG_WARNING, "Unload failed, '%s' could not be found\n", resource_name); 00492 return 0; 00493 } 00494 00495 if (!(mod->flags.running || mod->flags.declined)) 00496 error = 1; 00497 00498 if (!error && (mod->usecount > 0)) { 00499 if (force) 00500 ast_log(LOG_WARNING, "Warning: Forcing removal of module '%s' with use count %d\n", 00501 resource_name, mod->usecount); 00502 else { 00503 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, 00504 mod->usecount); 00505 error = 1; 00506 } 00507 } 00508 00509 if (!error) { 00510 __ast_module_user_hangup_all(mod); 00511 res = mod->info->unload(); 00512 00513 if (res) { 00514 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00515 if (force <= AST_FORCE_FIRM) 00516 error = 1; 00517 else 00518 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00519 } 00520 } 00521 00522 if (!error) 00523 mod->flags.running = mod->flags.declined = 0; 00524 00525 AST_LIST_UNLOCK(&module_list); 00526 00527 if (!error && !mod->lib && mod->info && mod->info->restore_globals) 00528 mod->info->restore_globals(); 00529 00530 #ifdef LOADABLE_MODULES 00531 if (!error) 00532 unload_dynamic_module(mod); 00533 #endif 00534 00535 if (!error) 00536 ast_update_use_count(); 00537 00538 return res; 00539 }
| int ast_update_module_list | ( | int(*)(const char *module, const char *description, int usecnt, const char *like) | modentry, | |
| const char * | like | |||
| ) |
Ask for a list of modules, descriptions, and use counts.
| modentry | A callback to an updater function. | |
| like | For each of the modules loaded, modentry will be executed with the resource, description, and usecount values of each particular module. |
Definition at line 1095 of file loader.c.
References AST_LIST_TRAVERSE, AST_LIST_TRYLOCK, AST_LIST_UNLOCK, ast_module_info::description, ast_module::info, and ast_module::usecount.
Referenced by handle_modlist(), and mod_update().
01097 { 01098 struct ast_module *cur; 01099 int unlock = -1; 01100 int total_mod_loaded = 0; 01101 01102 if (AST_LIST_TRYLOCK(&module_list)) 01103 unlock = 0; 01104 01105 AST_LIST_TRAVERSE(&module_list, cur, entry) { 01106 total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount, like); 01107 } 01108 01109 if (unlock) 01110 AST_LIST_UNLOCK(&module_list); 01111 01112 return total_mod_loaded; 01113 }
| void ast_update_use_count | ( | void | ) |
Notify when usecount has been changed.
This function calulates use counts and notifies anyone trying to keep track of them. It should be called whenever your module's usecount changes.
Definition at line 1083 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and loadupdate::updater.
Referenced by __ast_module_user_add(), __ast_module_user_hangup_all(), __ast_module_user_remove(), ast_module_ref(), ast_module_unref(), ast_unload_resource(), exit_now(), handle_request_do(), load_module(), oh323_request(), scheduler_process_request_queue(), sip_request_call(), start_resource(), and unistim_new().
01084 { 01085 /* Notify any module monitors that the use count for a 01086 resource has changed */ 01087 struct loadupdate *m; 01088 01089 AST_LIST_LOCK(&updaters); 01090 AST_LIST_TRAVERSE(&updaters, m, entry) 01091 m->updater(); 01092 AST_LIST_UNLOCK(&updaters); 01093 }
| static struct ast_module* find_resource | ( | const char * | resource, | |
| int | do_lock | |||
| ) | [static, read] |
Definition at line 325 of file loader.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and resource_name_match().
Referenced by ast_module_check(), ast_unload_resource(), load_modules(), and load_resource().
00326 { 00327 struct ast_module *cur; 00328 00329 if (do_lock) 00330 AST_LIST_LOCK(&module_list); 00331 00332 AST_LIST_TRAVERSE(&module_list, cur, entry) { 00333 if (!resource_name_match(resource, cur->resource)) 00334 break; 00335 } 00336 00337 if (do_lock) 00338 AST_LIST_UNLOCK(&module_list); 00339 00340 return cur; 00341 }
| static unsigned int inspect_module | ( | const struct ast_module * | mod | ) | [static] |
Definition at line 703 of file loader.c.
References ast_log(), ast_strlen_zero(), buildopt_sum, ast_module_info::buildopt_sum, ast_module_info::description, ast_module::info, ast_module_info::key, LOG_WARNING, and verify_key().
Referenced by load_resource().
00704 { 00705 if (!mod->info->description) { 00706 ast_log(LOG_WARNING, "Module '%s' does not provide a description.\n", mod->resource); 00707 return 1; 00708 } 00709 00710 if (!mod->info->key) { 00711 ast_log(LOG_WARNING, "Module '%s' does not provide a license key.\n", mod->resource); 00712 return 1; 00713 } 00714 00715 if (verify_key((unsigned char *) mod->info->key)) { 00716 ast_log(LOG_WARNING, "Module '%s' did not provide a valid license key.\n", mod->resource); 00717 return 1; 00718 } 00719 00720 if (!ast_strlen_zero(mod->info->buildopt_sum) && 00721 strcmp(buildopt_sum, mod->info->buildopt_sum)) { 00722 ast_log(LOG_WARNING, "Module '%s' was not compiled with the same compile-time options as this version of Asterisk.\n", mod->resource); 00723 ast_log(LOG_WARNING, "Module '%s' will not be initialized as it may cause instability.\n", mod->resource); 00724 return 1; 00725 } 00726 00727 return 0; 00728 }
| static int key_matches | ( | const unsigned char * | key1, | |
| const unsigned char * | key2 | |||
| ) | [static] |
Definition at line 278 of file loader.c.
Referenced by verify_key().
| int load_modules | ( | unsigned | int | ) |
Provided by loader.c
Definition at line 940 of file loader.c.
References add_to_load_order(), ast_config_AST_MODULE_DIR, ast_config_destroy(), ast_config_load2(), ast_free, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), AST_MODULE_CONFIG, ast_opt_quiet, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, dir, embedded_module_list, embedding, EVENT_FLAG_SYSTEM, find_resource(), ast_module::flags, ast_module::lib, load_resource_list(), LOG_NOTICE, LOG_WARNING, manager_event, ast_variable::name, ast_variable::next, load_order_entry::resource, resource_name_match(), ast_module::running, and ast_variable::value.
Referenced by main().
00941 { 00942 struct ast_config *cfg; 00943 struct ast_module *mod; 00944 struct load_order_entry *order; 00945 struct ast_variable *v; 00946 unsigned int load_count; 00947 struct load_order load_order; 00948 int res = 0; 00949 struct ast_flags config_flags = { 0 }; 00950 int modulecount = 0; 00951 00952 #ifdef LOADABLE_MODULES 00953 struct dirent *dirent; 00954 DIR *dir; 00955 #endif 00956 00957 /* all embedded modules have registered themselves by now */ 00958 embedding = 0; 00959 00960 ast_verb(1, "Asterisk Dynamic Loader Starting:\n"); 00961 00962 AST_LIST_HEAD_INIT_NOLOCK(&load_order); 00963 00964 AST_LIST_LOCK(&module_list); 00965 00966 if (embedded_module_list.first) { 00967 module_list.first = embedded_module_list.first; 00968 module_list.last = embedded_module_list.last; 00969 embedded_module_list.first = NULL; 00970 } 00971 00972 if (!(cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags))) { 00973 ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG); 00974 goto done; 00975 } 00976 00977 /* first, find all the modules we have been explicitly requested to load */ 00978 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 00979 if (!strcasecmp(v->name, preload_only ? "preload" : "load")) { 00980 add_to_load_order(v->value, &load_order); 00981 } 00982 } 00983 00984 /* check if 'autoload' is on */ 00985 if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) { 00986 /* if so, first add all the embedded modules that are not already running to the load order */ 00987 AST_LIST_TRAVERSE(&module_list, mod, entry) { 00988 /* if it's not embedded, skip it */ 00989 if (mod->lib) 00990 continue; 00991 00992 if (mod->flags.running) 00993 continue; 00994 00995 order = add_to_load_order(mod->resource, &load_order); 00996 } 00997 00998 #ifdef LOADABLE_MODULES 00999 /* if we are allowed to load dynamic modules, scan the directory for 01000 for all available modules and add them as well */ 01001 if ((dir = opendir(ast_config_AST_MODULE_DIR))) { 01002 while ((dirent = readdir(dir))) { 01003 int ld = strlen(dirent->d_name); 01004 01005 /* Must end in .so to load it. */ 01006 01007 if (ld < 4) 01008 continue; 01009 01010 if (strcasecmp(dirent->d_name + ld - 3, ".so")) 01011 continue; 01012 01013 /* if there is already a module by this name in the module_list, 01014 skip this file */ 01015 if (find_resource(dirent->d_name, 0)) 01016 continue; 01017 01018 add_to_load_order(dirent->d_name, &load_order); 01019 } 01020 01021 closedir(dir); 01022 } else { 01023 if (!ast_opt_quiet) 01024 ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n", 01025 ast_config_AST_MODULE_DIR); 01026 } 01027 #endif 01028 } 01029 01030 /* now scan the config for any modules we are prohibited from loading and 01031 remove them from the load order */ 01032 for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { 01033 if (strcasecmp(v->name, "noload")) 01034 continue; 01035 01036 AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) { 01037 if (!resource_name_match(order->resource, v->value)) { 01038 AST_LIST_REMOVE_CURRENT(entry); 01039 ast_free(order->resource); 01040 ast_free(order); 01041 } 01042 } 01043 AST_LIST_TRAVERSE_SAFE_END; 01044 } 01045 01046 /* we are done with the config now, all the information we need is in the 01047 load_order list */ 01048 ast_config_destroy(cfg); 01049 01050 load_count = 0; 01051 AST_LIST_TRAVERSE(&load_order, order, entry) 01052 load_count++; 01053 01054 if (load_count) 01055 ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count); 01056 01057 /* first, load only modules that provide global symbols */ 01058 if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) { 01059 goto done; 01060 } 01061 01062 /* now load everything else */ 01063 if ((res = load_resource_list(&load_order, 0, &modulecount)) < 0) { 01064 goto done; 01065 } 01066 01067 done: 01068 while ((order = AST_LIST_REMOVE_HEAD(&load_order, entry))) { 01069 ast_free(order->resource); 01070 ast_free(order); 01071 } 01072 01073 AST_LIST_UNLOCK(&module_list); 01074 01075 /* Tell manager clients that are aggressive at logging in that we're done 01076 loading modules. If there's a DNS problem in chan_sip, we might not 01077 even reach this */ 01078 manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount); 01079 01080 return res; 01081 }
| static enum ast_module_load_result load_resource | ( | const char * | resource_name, | |
| unsigned int | global_symbols_only, | |||
| struct ast_heap * | resource_heap | |||
| ) | [static] |
loads a resource based upon resource_name. If global_symbols_only is set only modules with global symbols will be loaded.
If the ast_heap is provided (not NULL) the module is found and added to the heap without running the module's load() function. By doing this, modules added to the resource_heap can be initialized later in order by priority.
If the ast_heap is not provided, the module's load function will be executed immediately
Definition at line 776 of file loader.c.
References ast_heap_push(), ast_log(), AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_test_flag, ast_module_info::backup_globals, ast_module::declined, find_resource(), ast_module::flags, ast_module::info, inspect_module(), ast_module::lib, LOG_WARNING, ast_module::running, and start_resource().
Referenced by ast_load_resource(), and load_resource_list().
00777 { 00778 struct ast_module *mod; 00779 enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; 00780 00781 if ((mod = find_resource(resource_name, 0))) { 00782 if (mod->flags.running) { 00783 ast_log(LOG_WARNING, "Module '%s' already exists.\n", resource_name); 00784 return AST_MODULE_LOAD_DECLINE; 00785 } 00786 if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS)) 00787 return AST_MODULE_LOAD_SKIP; 00788 } else { 00789 #ifdef LOADABLE_MODULES 00790 if (!(mod = load_dynamic_module(resource_name, global_symbols_only))) { 00791 /* don't generate a warning message during load_modules() */ 00792 if (!global_symbols_only) { 00793 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00794 return AST_MODULE_LOAD_DECLINE; 00795 } else { 00796 return AST_MODULE_LOAD_SKIP; 00797 } 00798 } 00799 #else 00800 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00801 return AST_MODULE_LOAD_DECLINE; 00802 #endif 00803 } 00804 00805 if (inspect_module(mod)) { 00806 ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); 00807 #ifdef LOADABLE_MODULES 00808 unload_dynamic_module(mod); 00809 #endif 00810 return AST_MODULE_LOAD_DECLINE; 00811 } 00812 00813 if (!mod->lib && mod->info->backup_globals()) { 00814 ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name); 00815 return AST_MODULE_LOAD_DECLINE; 00816 } 00817 00818 mod->flags.declined = 0; 00819 00820 if (resource_heap) { 00821 ast_heap_push(resource_heap, mod); 00822 res = AST_MODULE_LOAD_PRIORITY; 00823 } else { 00824 res = start_resource(mod); 00825 } 00826 00827 return res; 00828 }
| static int load_resource_list | ( | struct load_order * | load_order, | |
| unsigned int | global_symbols, | |||
| int * | mod_count | |||
| ) | [static] |
loads modules in order by load_pri, updates mod_count
Definition at line 882 of file loader.c.
References ast_free, ast_heap_create(), ast_heap_destroy(), ast_heap_pop(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, load_resource(), mod_load_cmp(), load_order_entry::resource, and start_resource().
Referenced by load_modules().
00883 { 00884 struct ast_heap *resource_heap; 00885 struct load_order_entry *order; 00886 struct ast_module *mod; 00887 int count = 0; 00888 int res = 0; 00889 00890 if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) { 00891 return -1; 00892 } 00893 00894 /* first, add find and add modules to heap */ 00895 AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) { 00896 switch (load_resource(order->resource, global_symbols, resource_heap)) { 00897 case AST_MODULE_LOAD_SUCCESS: 00898 case AST_MODULE_LOAD_DECLINE: 00899 AST_LIST_REMOVE_CURRENT(entry); 00900 ast_free(order->resource); 00901 ast_free(order); 00902 break; 00903 case AST_MODULE_LOAD_FAILURE: 00904 res = -1; 00905 goto done; 00906 case AST_MODULE_LOAD_SKIP: 00907 break; 00908 case AST_MODULE_LOAD_PRIORITY: 00909 AST_LIST_REMOVE_CURRENT(entry); 00910 break; 00911 } 00912 } 00913 AST_LIST_TRAVERSE_SAFE_END; 00914 00915 /* second remove modules from heap sorted by priority */ 00916 while ((mod = ast_heap_pop(resource_heap))) { 00917 switch (start_resource(mod)) { 00918 case AST_MODULE_LOAD_SUCCESS: 00919 count++; 00920 case AST_MODULE_LOAD_DECLINE: 00921 break; 00922 case AST_MODULE_LOAD_FAILURE: 00923 res = -1; 00924 goto done; 00925 case AST_MODULE_LOAD_SKIP: 00926 case AST_MODULE_LOAD_PRIORITY: 00927 break; 00928 } 00929 } 00930 00931 done: 00932 if (mod_count) { 00933 *mod_count += count; 00934 } 00935 ast_heap_destroy(resource_heap); 00936 00937 return res; 00938 }
| static int mod_load_cmp | ( | void * | a, | |
| void * | b | |||
| ) | [static] |
Definition at line 865 of file loader.c.
References AST_MODFLAG_LOAD_ORDER, ast_test_flag, ast_module::info, and ast_module_info::load_pri.
Referenced by load_resource_list().
00866 { 00867 struct ast_module *a_mod = (struct ast_module *) a; 00868 struct ast_module *b_mod = (struct ast_module *) b; 00869 int res = -1; 00870 /* if load_pri is not set, default is 255. Lower is better*/ 00871 unsigned char a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 255; 00872 unsigned char b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 255; 00873 if (a_pri == b_pri) { 00874 res = 0; 00875 } else if (a_pri < b_pri) { 00876 res = 1; 00877 } 00878 return res; 00879 }
| static int printdigest | ( | const unsigned char * | d | ) | [static] |
| static void queue_reload_request | ( | const char * | module | ) | [static] |
Definition at line 598 of file loader.c.
References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), do_full_reload, and LOG_ERROR.
Referenced by ast_module_reload().
00599 { 00600 struct reload_queue_item *item; 00601 00602 AST_LIST_LOCK(&reload_queue); 00603 00604 if (do_full_reload) { 00605 AST_LIST_UNLOCK(&reload_queue); 00606 return; 00607 } 00608 00609 if (ast_strlen_zero(module)) { 00610 /* A full reload request (when module is NULL) wipes out any previous 00611 reload requests and causes the queue to ignore future ones */ 00612 while ((item = AST_LIST_REMOVE_HEAD(&reload_queue, entry))) { 00613 ast_free(item); 00614 } 00615 do_full_reload = 1; 00616 } else { 00617 /* No reason to add the same module twice */ 00618 AST_LIST_TRAVERSE(&reload_queue, item, entry) { 00619 if (!strcasecmp(item->module, module)) { 00620 AST_LIST_UNLOCK(&reload_queue); 00621 return; 00622 } 00623 } 00624 item = ast_calloc(1, sizeof(*item) + strlen(module) + 1); 00625 if (!item) { 00626 ast_log(LOG_ERROR, "Failed to allocate reload queue item.\n"); 00627 AST_LIST_UNLOCK(&reload_queue); 00628 return; 00629 } 00630 strcpy(item->module, module); 00631 AST_LIST_INSERT_TAIL(&reload_queue, item, entry); 00632 } 00633 AST_LIST_UNLOCK(&reload_queue); 00634 }
| static int resource_name_match | ( | const char * | name1_in, | |
| const char * | name2_in | |||
| ) | [static] |
Definition at line 307 of file loader.c.
References ast_strdupa.
Referenced by add_to_load_order(), ast_module_reload(), find_resource(), and load_modules().
00308 { 00309 char *name1 = (char *) name1_in; 00310 char *name2 = (char *) name2_in; 00311 00312 /* trim off any .so extensions */ 00313 if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) { 00314 name1 = ast_strdupa(name1); 00315 name1[strlen(name1) - 3] = '\0'; 00316 } 00317 if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) { 00318 name2 = ast_strdupa(name2); 00319 name2[strlen(name2) - 3] = '\0'; 00320 } 00321 00322 return strcasecmp(name1, name2); 00323 }
| static enum ast_module_load_result start_resource | ( | struct ast_module * | mod | ) | [static] |
Definition at line 730 of file loader.c.
References ast_fully_booted, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_PRIORITY, AST_MODULE_LOAD_SKIP, AST_MODULE_LOAD_SUCCESS, ast_opt_console, ast_update_use_count(), ast_verb, ast_verbose, COLOR_BLACK, COLOR_BROWN, ast_module::declined, ast_module_info::description, ast_module::flags, ast_module::info, ast_module_info::load, option_verbose, ast_module::running, and term_color().
Referenced by load_resource(), and load_resource_list().
00731 { 00732 char tmp[256]; 00733 enum ast_module_load_result res; 00734 00735 if (!mod->info->load) { 00736 return AST_MODULE_LOAD_FAILURE; 00737 } 00738 00739 res = mod->info->load(); 00740 00741 switch (res) { 00742 case AST_MODULE_LOAD_SUCCESS: 00743 if (!ast_fully_booted) { 00744 ast_verb(1, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00745 if (ast_opt_console && !option_verbose) 00746 ast_verbose( "."); 00747 } else { 00748 ast_verb(1, "Loaded %s => (%s)\n", mod->resource, mod->info->description); 00749 } 00750 00751 mod->flags.running = 1; 00752 00753 ast_update_use_count(); 00754 break; 00755 case AST_MODULE_LOAD_DECLINE: 00756 mod->flags.declined = 1; 00757 break; 00758 case AST_MODULE_LOAD_FAILURE: 00759 case AST_MODULE_LOAD_SKIP: /* modules should never return this value */ 00760 case AST_MODULE_LOAD_PRIORITY: 00761 break; 00762 } 00763 00764 return res; 00765 }
| static int verify_key | ( | const unsigned char * | key | ) | [static] |
Definition at line 290 of file loader.c.
References expected_key, key_matches(), MD5Final(), MD5Init(), MD5Update(), and printdigest().
Referenced by inspect_module().
00291 { 00292 struct MD5Context c; 00293 unsigned char digest[16]; 00294 00295 MD5Init(&c); 00296 MD5Update(&c, key, strlen((char *)key)); 00297 MD5Final(digest, &c); 00298 00299 if (key_matches(expected_key, digest)) 00300 return 0; 00301 00302 printdigest(digest); 00303 00304 return -1; 00305 }
char buildopt_sum[33] = AST_BUILDOPT_SUM [static] |
Definition at line 78 of file loader.c.
Referenced by inspect_module().
int do_full_reload = 0 [static] |
Definition at line 121 of file loader.c.
Referenced by ast_process_pending_reloads(), and queue_reload_request().
struct module_list embedded_module_list [static] |
Definition at line 105 of file loader.c.
Referenced by ast_module_register(), and load_modules().
unsigned int embedding = 1 [static] |
Definition at line 80 of file loader.c.
Referenced by ast_module_register(), and load_modules().
unsigned char expected_key[] [static] |
{ 0x87, 0x76, 0x79, 0x35, 0x23, 0xea, 0x3a, 0xd3,
0x25, 0x2a, 0xbb, 0x35, 0x87, 0xe4, 0x22, 0x24 }
Definition at line 74 of file loader.c.
Referenced by verify_key().
| struct ast_module* resource_being_loaded |
Definition at line 129 of file loader.c.
Referenced by ast_module_register().
1.6.1