dect
/
asterisk
Archived
13
0
Fork 0

Add the capability to require a module to be loaded, or else Asterisk exits.

Review: https://reviewboard.asterisk.org/r/426/


git-svn-id: http://svn.digium.com/svn/asterisk/trunk@229819 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
oej 2009-11-13 08:52:28 +00:00
parent 83a24475c2
commit 47269d650e
4 changed files with 49 additions and 19 deletions

View File

@ -327,6 +327,10 @@ Miscellaneous
------------- -------------
* SendText is now implemented in chan_gtalk and chan_jingle. It will simply send * SendText is now implemented in chan_gtalk and chan_jingle. It will simply send
XMPP text messages to the remote JID. XMPP text messages to the remote JID.
* Modules.conf has a new option - "require" - that marks a module as critical for
the execution of Asterisk.
If one of the required modules fail to load, Asterisk will exit with a return
code set to 2.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
--- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2 ------------- --- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2 -------------

View File

@ -21,6 +21,14 @@ autoload=yes
; Uncomment the following if you wish to use the Speech Recognition API ; Uncomment the following if you wish to use the Speech Recognition API
;preload => res_speech.so ;preload => res_speech.so
; ;
; If you want Asterisk to fail if a module does not load, then use
; the "require" keyword. Asterisk will exit with a status code of 2
; if a required module does not load.
;
; require = chan_sip.so
; If you want you can combine with preload
; preload-require = res_odbc.so
;
; If you want, load the GTK console right away. ; If you want, load the GTK console right away.
; ;
noload => pbx_gtkconsole.so noload => pbx_gtkconsole.so

View File

@ -3108,6 +3108,7 @@ int main(int argc, char *argv[])
char *buf; char *buf;
const char *runuser = NULL, *rungroup = NULL; const char *runuser = NULL, *rungroup = NULL;
char *remotesock = NULL; char *remotesock = NULL;
int moduleresult; /*!< Result from the module load subsystem */
/* Remember original args for restart */ /* Remember original args for restart */
if (argc > ARRAY_LEN(_argv) - 1) { if (argc > ARRAY_LEN(_argv) - 1) {
@ -3583,9 +3584,9 @@ int main(int argc, char *argv[])
ast_xmldoc_load_documentation(); ast_xmldoc_load_documentation();
#endif #endif
if (load_modules(1)) { /* Load modules, pre-load only */ if ((moduleresult = load_modules(1))) { /* Load modules, pre-load only */
printf("%s", term_quit()); printf("%s", term_quit());
exit(1); exit(moduleresult == -2 ? 2 : 1);
} }
if (dnsmgr_init()) { /* Initialize the DNS manager */ if (dnsmgr_init()) { /* Initialize the DNS manager */
@ -3657,9 +3658,9 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
if (load_modules(0)) { if ((moduleresult = load_modules(0))) { /* Load modules */
printf("%s", term_quit()); printf("%s", term_quit());
exit(1); exit(moduleresult == -2 ? 2 : 1);
} }
/* loads the cli_permissoins.conf file needed to implement cli restrictions. */ /* loads the cli_permissoins.conf file needed to implement cli restrictions. */

View File

@ -773,7 +773,7 @@ static enum ast_module_load_result start_resource(struct ast_module *mod)
* *
* If the ast_heap is not provided, the module's load function will be executed * If the ast_heap is not provided, the module's load function will be executed
* immediately */ * immediately */
static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap) static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, struct ast_heap *resource_heap, int required)
{ {
struct ast_module *mod; struct ast_module *mod;
enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS; enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;
@ -791,14 +791,14 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi
/* don't generate a warning message during load_modules() */ /* don't generate a warning message during load_modules() */
if (!global_symbols_only) { if (!global_symbols_only) {
ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
return AST_MODULE_LOAD_DECLINE; return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
} else { } else {
return AST_MODULE_LOAD_SKIP; return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SKIP;
} }
} }
#else #else
ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);
return AST_MODULE_LOAD_DECLINE; return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
#endif #endif
} }
@ -807,12 +807,12 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi
#ifdef LOADABLE_MODULES #ifdef LOADABLE_MODULES
unload_dynamic_module(mod); unload_dynamic_module(mod);
#endif #endif
return AST_MODULE_LOAD_DECLINE; return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
} }
if (!mod->lib && mod->info->backup_globals()) { if (!mod->lib && mod->info->backup_globals()) {
ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name); ast_log(LOG_WARNING, "Module '%s' was unable to backup its global data.\n", resource_name);
return AST_MODULE_LOAD_DECLINE; return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;
} }
mod->flags.declined = 0; mod->flags.declined = 0;
@ -831,7 +831,7 @@ int ast_load_resource(const char *resource_name)
{ {
int res; int res;
AST_LIST_LOCK(&module_list); AST_LIST_LOCK(&module_list);
res = load_resource(resource_name, 0, NULL); res = load_resource(resource_name, 0, NULL, 0);
AST_LIST_UNLOCK(&module_list); AST_LIST_UNLOCK(&module_list);
return res; return res;
@ -839,24 +839,31 @@ int ast_load_resource(const char *resource_name)
struct load_order_entry { struct load_order_entry {
char *resource; char *resource;
int required;
AST_LIST_ENTRY(load_order_entry) entry; AST_LIST_ENTRY(load_order_entry) entry;
}; };
AST_LIST_HEAD_NOLOCK(load_order, load_order_entry); AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order) static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
{ {
struct load_order_entry *order; struct load_order_entry *order;
AST_LIST_TRAVERSE(load_order, order, entry) { AST_LIST_TRAVERSE(load_order, order, entry) {
if (!resource_name_match(order->resource, resource)) if (!resource_name_match(order->resource, resource)) {
/* Make sure we have the proper setting for the required field
(we might have both load= and required= lines in modules.conf) */
order->required |= required;
}
return NULL; return NULL;
}
} }
if (!(order = ast_calloc(1, sizeof(*order)))) if (!(order = ast_calloc(1, sizeof(*order))))
return NULL; return NULL;
order->resource = ast_strdup(resource); order->resource = ast_strdup(resource);
order->required = required;
AST_LIST_INSERT_TAIL(load_order, order, entry); AST_LIST_INSERT_TAIL(load_order, order, entry);
return order; return order;
@ -878,7 +885,9 @@ static int mod_load_cmp(void *a, void *b)
return res; return res;
} }
/*! loads modules in order by load_pri, updates mod_count */ /*! loads modules in order by load_pri, updates mod_count
\return -1 on failure to load module, -2 on failure to load required module, otherwise 0
*/
static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count) static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)
{ {
struct ast_heap *resource_heap; struct ast_heap *resource_heap;
@ -893,7 +902,7 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
/* first, add find and add modules to heap */ /* first, add find and add modules to heap */
AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) { AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
switch (load_resource(order->resource, global_symbols, resource_heap)) { switch (load_resource(order->resource, global_symbols, resource_heap, order->required)) {
case AST_MODULE_LOAD_SUCCESS: case AST_MODULE_LOAD_SUCCESS:
case AST_MODULE_LOAD_DECLINE: case AST_MODULE_LOAD_DECLINE:
AST_LIST_REMOVE_CURRENT(entry); AST_LIST_REMOVE_CURRENT(entry);
@ -901,7 +910,9 @@ static int load_resource_list(struct load_order *load_order, unsigned int global
ast_free(order); ast_free(order);
break; break;
case AST_MODULE_LOAD_FAILURE: case AST_MODULE_LOAD_FAILURE:
res = -1; ast_log(LOG_ERROR, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
fprintf(stderr, "*** Failed to load module %s - %s\n", order->resource, order->required ? "Required" : "Not required");
res = order->required ? -2 : -1;
goto done; goto done;
case AST_MODULE_LOAD_SKIP: case AST_MODULE_LOAD_SKIP:
break; break;
@ -978,8 +989,14 @@ int load_modules(unsigned int preload_only)
/* first, find all the modules we have been explicitly requested to load */ /* first, find all the modules we have been explicitly requested to load */
for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) { for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
if (!strcasecmp(v->name, preload_only ? "preload" : "load")) { if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {
add_to_load_order(v->value, &load_order); add_to_load_order(v->value, &load_order, 0);
} }
if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {
/* Add the module to the list and make sure it's required */
add_to_load_order(v->value, &load_order, 1);
ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);
}
} }
/* check if 'autoload' is on */ /* check if 'autoload' is on */
@ -993,7 +1010,7 @@ int load_modules(unsigned int preload_only)
if (mod->flags.running) if (mod->flags.running)
continue; continue;
order = add_to_load_order(mod->resource, &load_order); order = add_to_load_order(mod->resource, &load_order, 0);
} }
#ifdef LOADABLE_MODULES #ifdef LOADABLE_MODULES
@ -1016,7 +1033,7 @@ int load_modules(unsigned int preload_only)
if (find_resource(dirent->d_name, 0)) if (find_resource(dirent->d_name, 0))
continue; continue;
add_to_load_order(dirent->d_name, &load_order); add_to_load_order(dirent->d_name, &load_order, 0);
} }
closedir(dir); closedir(dir);