Go to the source code of this file.
Defines | |
#define | ASTERISK_GPL_KEY "This paragraph is Copyright (C) 2000, Linux Support Services, Inc. \In order for your module to load, it must return this key via a function \called \"key\". Any code which includes this paragraph must be licensed under \the GNU General Public License version 2 or later (at your option). Linux \Support Services, Inc. reserves the right to allow other parties to license \this paragraph under other terms as well." |
#define | AST_MODULE_CONFIG "modules.conf" /*! Module configuration file */ |
#define | AST_FORCE_SOFT 0 |
#define | AST_FORCE_FIRM 1 |
#define | AST_FORCE_HARD 2 |
#define | STANDARD_LOCAL_USER |
#define | LOCAL_USER_DECL |
#define | LOCAL_USER_ADD(u) |
#define | LOCAL_USER_REMOVE(u) |
#define | STANDARD_HANGUP_LOCALUSERS |
#define | STANDARD_USECOUNT(res) |
Functions | |
int | load_module (void) |
Initialize the module. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
char * | description (void) |
Description. | |
char * | key (void) |
Returns the ASTERISK_GPL_KEY. | |
int | reload (void) |
Reload stuff. | |
int | ast_load_resource (char *resource_name) |
Loads a module. | |
int | ast_unload_resource (char *resource_name, int force) |
Unloads a module. | |
void | ast_update_use_count (void) |
Notify when usecount has been changed. | |
int | ast_update_module_list (int(*modentry)(char *module, char *description, int usecnt)) |
Ask for a list of modules, descriptions, and use counts. | |
int | ast_loader_register (int(*updater)(void)) |
Ask this procedure to be run with modules have been updated. | |
int | ast_loader_unregister (int(*updater)(void)) |
No longer run me when modules are updated. | |
void | ast_module_reload (void) |
Reload all modules. | |
int | ast_register_atexit (void(*func)(void)) |
void | ast_unregister_atexit (void(*func)(void)) |
|
Definition at line 80 of file module.h. Referenced by ast_unload_resource(). |
|
|
|
|
|
Definition at line 77 of file module.h. Referenced by ast_load_resource(), and load_modules(). |
|
reload configs |
|
|
|
Value: static ast_mutex_t localuser_lock = AST_MUTEX_INITIALIZER; \ static struct localuser *localusers = NULL; \ static int localusecnt = 0; |
|
|
|
|
|
Value: struct localuser { \ struct ast_channel *chan; \ struct localuser *next; \ } |
|
Value: { \ ast_mutex_lock(&localuser_lock); \ res = localusecnt; \ ast_mutex_unlock(&localuser_lock); \ } |
|
Loads a module.
Definition at line 166 of file loader.c. References ast_config_AST_MODULE_DIR, ast_destroy(), ast_load(), ast_log(), AST_MODULE_CONFIG, ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_unload_resource(), ast_update_use_count(), ast_variable_retrieve(), ast_verbose(), COLOR_BLACK, COLOR_BROWN, free, fully_booted, key(), LOG_WARNING, malloc, option_console, option_verbose, RTLD_NOW, term_color(), and VERBOSE_PREFIX_1. Referenced by load_modules().
00167 { 00168 static char fn[256]; 00169 int errors=0; 00170 int res; 00171 struct module *m; 00172 int flags=RTLD_NOW; 00173 #ifdef RTLD_GLOBAL 00174 char *val; 00175 #endif 00176 char *key; 00177 int o; 00178 struct ast_config *cfg; 00179 char tmp[80]; 00180 /* Keep the module file parsing silent */ 00181 o = option_verbose; 00182 if (strncasecmp(resource_name, "res_", 4)) { 00183 option_verbose = 0; 00184 cfg = ast_load(AST_MODULE_CONFIG); 00185 option_verbose = o; 00186 if (cfg) { 00187 #ifdef RTLD_GLOBAL 00188 if ((val = ast_variable_retrieve(cfg, "global", resource_name)) 00189 && ast_true(val)) 00190 flags |= RTLD_GLOBAL; 00191 #endif 00192 ast_destroy(cfg); 00193 } 00194 } else { 00195 /* Resource modules are always loaded global and lazy */ 00196 #ifdef RTLD_GLOBAL 00197 flags = (RTLD_GLOBAL | RTLD_LAZY); 00198 #else 00199 flags = RTLD_LAZY; 00200 #endif 00201 } 00202 00203 if (ast_mutex_lock(&modlock)) 00204 ast_log(LOG_WARNING, "Failed to lock\n"); 00205 m = module_list; 00206 while(m) { 00207 if (!strcasecmp(m->resource, resource_name)) { 00208 ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name); 00209 ast_mutex_unlock(&modlock); 00210 return -1; 00211 } 00212 m = m->next; 00213 } 00214 m = malloc(sizeof(struct module)); 00215 if (!m) { 00216 ast_log(LOG_WARNING, "Out of memory\n"); 00217 ast_mutex_unlock(&modlock); 00218 return -1; 00219 } 00220 strncpy(m->resource, resource_name, sizeof(m->resource)-1); 00221 if (resource_name[0] == '/') { 00222 strncpy(fn, resource_name, sizeof(fn)-1); 00223 } else { 00224 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name); 00225 } 00226 m->lib = dlopen(fn, flags); 00227 if (!m->lib) { 00228 ast_log(LOG_WARNING, "%s\n", dlerror()); 00229 free(m); 00230 ast_mutex_unlock(&modlock); 00231 return -1; 00232 } 00233 m->load_module = dlsym(m->lib, "load_module"); 00234 if (m->load_module == NULL) 00235 m->load_module = dlsym(m->lib, "_load_module"); 00236 if (!m->load_module) { 00237 ast_log(LOG_WARNING, "No load_module in module %s\n", fn); 00238 errors++; 00239 } 00240 m->unload_module = dlsym(m->lib, "unload_module"); 00241 if (m->unload_module == NULL) 00242 m->unload_module = dlsym(m->lib, "_unload_module"); 00243 if (!m->unload_module) { 00244 ast_log(LOG_WARNING, "No unload_module in module %s\n", fn); 00245 errors++; 00246 } 00247 m->usecount = dlsym(m->lib, "usecount"); 00248 if (m->usecount == NULL) 00249 m->usecount = dlsym(m->lib, "_usecount"); 00250 if (!m->usecount) { 00251 ast_log(LOG_WARNING, "No usecount in module %s\n", fn); 00252 errors++; 00253 } 00254 m->description = dlsym(m->lib, "description"); 00255 if (m->description == NULL) 00256 m->description = dlsym(m->lib, "_description"); 00257 if (!m->description) { 00258 ast_log(LOG_WARNING, "No description in module %s\n", fn); 00259 errors++; 00260 } 00261 m->key = dlsym(m->lib, "key"); 00262 if (m->key == NULL) 00263 m->key = dlsym(m->lib, "_key"); 00264 if (!m->key) { 00265 ast_log(LOG_WARNING, "No key routine in module %s\n", fn); 00266 errors++; 00267 } 00268 m->reload = dlsym(m->lib, "reload"); 00269 if (m->reload == NULL) 00270 m->reload = dlsym(m->lib, "_reload"); 00271 if (m->key && !(key = m->key())) { 00272 ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn); 00273 errors++; 00274 } else 00275 key = NULL; 00276 if (key && verify_key(key)) { 00277 ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn); 00278 errors++; 00279 } 00280 if (errors) { 00281 ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn); 00282 dlclose(m->lib); 00283 free(m); 00284 ast_mutex_unlock(&modlock); 00285 return -1; 00286 } 00287 if (!fully_booted) { 00288 if (option_verbose) 00289 ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00290 if (option_console && !option_verbose) 00291 ast_verbose( "."); 00292 } else { 00293 if (option_verbose) 00294 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description()); 00295 } 00296 m->next = module_list; 00297 00298 module_list = m; 00299 ast_mutex_unlock(&modlock); 00300 if ((res = m->load_module())) { 00301 ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res); 00302 ast_unload_resource(resource_name, 0); 00303 return -1; 00304 } 00305 ast_update_use_count(); 00306 return 0; 00307 } |
|
Ask this procedure to be run with modules have been updated.
Definition at line 446 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and malloc.
00447 { 00448 struct loadupdate *tmp; 00449 /* XXX Should be more flexible here, taking > 1 verboser XXX */ 00450 if ((tmp = malloc(sizeof (struct loadupdate)))) { 00451 tmp->updater = v; 00452 if (ast_mutex_lock(&modlock)) 00453 ast_log(LOG_WARNING, "Failed to lock\n"); 00454 tmp->next = updaters; 00455 updaters = tmp; 00456 ast_mutex_unlock(&modlock); 00457 return 0; 00458 } 00459 return -1; 00460 } |
|
No longer run me when modules are updated.
Definition at line 462 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.
00463 { 00464 int res = -1; 00465 struct loadupdate *tmp, *tmpl=NULL; 00466 if (ast_mutex_lock(&modlock)) 00467 ast_log(LOG_WARNING, "Failed to lock\n"); 00468 tmp = updaters; 00469 while(tmp) { 00470 if (tmp->updater == v) { 00471 if (tmpl) 00472 tmpl->next = tmp->next; 00473 else 00474 updaters = tmp->next; 00475 break; 00476 } 00477 tmpl = tmp; 00478 tmp = tmp->next; 00479 } 00480 if (tmp) 00481 res = 0; 00482 ast_mutex_unlock(&modlock); 00483 return res; 00484 } |
|
Reload all modules. This reloads all modules set to load in asterisk. It does NOT run the unload routine and then loads them again, it runs the given reload routine. Definition at line 143 of file loader.c. References ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock, ast_mutex_unlock, ast_rtp_reload(), ast_verbose(), option_verbose, reload_manager(), and VERBOSE_PREFIX_3.
00144 { 00145 struct module *m; 00146 00147 /* We'll do the logger and manager the favor of calling its reload here first */ 00148 reload_manager(); 00149 ast_enum_reload(); 00150 ast_rtp_reload(); 00151 time(&ast_lastreloadtime); 00152 00153 ast_mutex_lock(&modlock); 00154 m = module_list; 00155 while(m) { 00156 if (m->reload) { 00157 if (option_verbose > 2) 00158 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); 00159 m->reload(); 00160 } 00161 m = m->next; 00162 } 00163 ast_mutex_unlock(&modlock); 00164 } |
|
Definition at line 109 of file asterisk.c. References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc.
00110 { 00111 int res = -1; 00112 struct ast_atexit *ae; 00113 ast_unregister_atexit(func); 00114 ae = malloc(sizeof(struct ast_atexit)); 00115 ast_mutex_lock(&atexitslock); 00116 if (ae) { 00117 memset(ae, 0, sizeof(struct ast_atexit)); 00118 ae->next = atexits; 00119 ae->func = func; 00120 atexits = ae; 00121 res = 0; 00122 } 00123 ast_mutex_unlock(&atexitslock); 00124 return res; 00125 } |
|
Unloads a module.
Definition at line 101 of file loader.c. References AST_FORCE_FIRM, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_update_use_count(), free, LOG_WARNING, and module::next. Referenced by ast_load_resource().
00102 { 00103 struct module *m, *ml = NULL; 00104 int res = -1; 00105 if (ast_mutex_lock(&modlock)) 00106 ast_log(LOG_WARNING, "Failed to lock\n"); 00107 m = module_list; 00108 while(m) { 00109 if (!strcasecmp(m->resource, resource_name)) { 00110 if ((res = m->usecount()) > 0) { 00111 if (force) 00112 ast_log(LOG_WARNING, "Warning: Forcing removal of module %s with use count %d\n", resource_name, res); 00113 else { 00114 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res); 00115 ast_mutex_unlock(&modlock); 00116 return -1; 00117 } 00118 } 00119 res = m->unload_module(); 00120 if (res) { 00121 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00122 if (force <= AST_FORCE_FIRM) { 00123 ast_mutex_unlock(&modlock); 00124 return -1; 00125 } else 00126 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00127 } 00128 if (ml) 00129 ml->next = m->next; 00130 else 00131 module_list = m->next; 00132 dlclose(m->lib); 00133 free(m); 00134 } 00135 ml = m; 00136 m = m->next; 00137 } 00138 ast_mutex_unlock(&modlock); 00139 ast_update_use_count(); 00140 return res; 00141 } |
|
Definition at line 127 of file asterisk.c. References ast_mutex_lock, and ast_mutex_unlock. Referenced by ast_register_atexit().
00128 { 00129 struct ast_atexit *ae, *prev = NULL; 00130 ast_mutex_lock(&atexitslock); 00131 ae = atexits; 00132 while(ae) { 00133 if (ae->func == func) { 00134 if (prev) 00135 prev->next = ae->next; 00136 else 00137 atexits = ae->next; 00138 break; 00139 } 00140 prev = ae; 00141 ae = ae->next; 00142 } 00143 ast_mutex_unlock(&atexitslock); 00144 } |
|
Ask for a list of modules, descriptions, and use counts.
Definition at line 430 of file loader.c. References ast_mutex_trylock, ast_mutex_unlock, and module::next.
00431 { 00432 struct module *m; 00433 int unlock = -1; 00434 if (ast_mutex_trylock(&modlock)) 00435 unlock = 0; 00436 m = module_list; 00437 while(m) { 00438 modentry(m->resource, m->description(), m->usecount()); 00439 m = m->next; 00440 } 00441 if (unlock) 00442 ast_mutex_unlock(&modlock); 00443 return 0; 00444 } |
|
Notify when usecount has been changed. This function goes through and calulates use counts. It also notifies anybody trying to keep track of them. Definition at line 414 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING. Referenced by ast_load_resource(), and ast_unload_resource().
00415 { 00416 /* Notify any module monitors that the use count for a 00417 resource has changed */ 00418 struct loadupdate *m; 00419 if (ast_mutex_lock(&modlock)) 00420 ast_log(LOG_WARNING, "Failed to lock\n"); 00421 m = updaters; 00422 while(m) { 00423 m->updater(); 00424 m = m->next; 00425 } 00426 ast_mutex_unlock(&modlock); 00427 00428 } |
|
Description. Returns a short description of your module. Referenced by ast_channel_register(), ast_channel_register_ex(), ast_register_application(), and load_pbx(). |
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message, i.e. char *key(void){return ASTERISK_GPL_KEY;} Referenced by ast_db_del(), ast_db_deltree(), ast_db_get(), ast_db_gettree(), ast_db_put(), ast_load_resource(), ast_privacy_check(), and ast_privacy_set(). |
|
Initialize the module. This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc. |
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload. Return 0 on success, and other than 0 on problem. |
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit). Return 0 on success, or other than 0 if there is a problem. |
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. |