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" |
#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 (const char *name) |
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: AST_MUTEX_DEFINE_STATIC(localuser_lock); \ 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 196 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, module::description, dlclose(), dlerror(), dlopen(), dlsym(), free, fully_booted, module::key, module::lib, module::load_module, LOG_WARNING, malloc, module::next, option_console, option_verbose, module::reload, module::resource, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), module::unload_module, module::usecount, and VERBOSE_PREFIX_1. Referenced by load_modules(). 00197 { 00198 static char fn[256]; 00199 int errors=0; 00200 int res; 00201 struct module *m; 00202 int flags=RTLD_NOW; 00203 #ifdef RTLD_GLOBAL 00204 char *val; 00205 #endif 00206 char *key; 00207 int o; 00208 struct ast_config *cfg; 00209 char tmp[80]; 00210 /* Keep the module file parsing silent */ 00211 o = option_verbose; 00212 if (strncasecmp(resource_name, "res_", 4)) { 00213 option_verbose = 0; 00214 cfg = ast_load(AST_MODULE_CONFIG); 00215 option_verbose = o; 00216 if (cfg) { 00217 #ifdef RTLD_GLOBAL 00218 if ((val = ast_variable_retrieve(cfg, "global", resource_name)) 00219 && ast_true(val)) 00220 flags |= RTLD_GLOBAL; 00221 #endif 00222 ast_destroy(cfg); 00223 } 00224 } else { 00225 /* Resource modules are always loaded global and lazy */ 00226 #ifdef RTLD_GLOBAL 00227 flags = (RTLD_GLOBAL | RTLD_LAZY); 00228 #else 00229 flags = RTLD_LAZY; 00230 #endif 00231 } 00232 00233 if (ast_mutex_lock(&modlock)) 00234 ast_log(LOG_WARNING, "Failed to lock\n"); 00235 m = module_list; 00236 while(m) { 00237 if (!strcasecmp(m->resource, resource_name)) { 00238 ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name); 00239 ast_mutex_unlock(&modlock); 00240 return -1; 00241 } 00242 m = m->next; 00243 } 00244 m = malloc(sizeof(struct module)); 00245 if (!m) { 00246 ast_log(LOG_WARNING, "Out of memory\n"); 00247 ast_mutex_unlock(&modlock); 00248 return -1; 00249 } 00250 strncpy(m->resource, resource_name, sizeof(m->resource)-1); 00251 if (resource_name[0] == '/') { 00252 strncpy(fn, resource_name, sizeof(fn)-1); 00253 } else { 00254 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name); 00255 } 00256 m->lib = dlopen(fn, flags); 00257 if (!m->lib) { 00258 ast_log(LOG_WARNING, "%s\n", dlerror()); 00259 free(m); 00260 ast_mutex_unlock(&modlock); 00261 return -1; 00262 } 00263 m->load_module = dlsym(m->lib, "load_module"); 00264 if (m->load_module == NULL) 00265 m->load_module = dlsym(m->lib, "_load_module"); 00266 if (!m->load_module) { 00267 ast_log(LOG_WARNING, "No load_module in module %s\n", fn); 00268 errors++; 00269 } 00270 m->unload_module = dlsym(m->lib, "unload_module"); 00271 if (m->unload_module == NULL) 00272 m->unload_module = dlsym(m->lib, "_unload_module"); 00273 if (!m->unload_module) { 00274 ast_log(LOG_WARNING, "No unload_module in module %s\n", fn); 00275 errors++; 00276 } 00277 m->usecount = dlsym(m->lib, "usecount"); 00278 if (m->usecount == NULL) 00279 m->usecount = dlsym(m->lib, "_usecount"); 00280 if (!m->usecount) { 00281 ast_log(LOG_WARNING, "No usecount in module %s\n", fn); 00282 errors++; 00283 } 00284 m->description = dlsym(m->lib, "description"); 00285 if (m->description == NULL) 00286 m->description = dlsym(m->lib, "_description"); 00287 if (!m->description) { 00288 ast_log(LOG_WARNING, "No description in module %s\n", fn); 00289 errors++; 00290 } 00291 m->key = dlsym(m->lib, "key"); 00292 if (m->key == NULL) 00293 m->key = dlsym(m->lib, "_key"); 00294 if (!m->key) { 00295 ast_log(LOG_WARNING, "No key routine in module %s\n", fn); 00296 errors++; 00297 } 00298 m->reload = dlsym(m->lib, "reload"); 00299 if (m->reload == NULL) 00300 m->reload = dlsym(m->lib, "_reload"); 00301 if (!m->key || !(key = m->key())) { 00302 ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn); 00303 key = NULL; 00304 errors++; 00305 } 00306 if (key && verify_key(key)) { 00307 ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn); 00308 errors++; 00309 } 00310 if (errors) { 00311 ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn); 00312 dlclose(m->lib); 00313 free(m); 00314 ast_mutex_unlock(&modlock); 00315 return -1; 00316 } 00317 if (!fully_booted) { 00318 if (option_verbose) 00319 ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00320 if (option_console && !option_verbose) 00321 ast_verbose( "."); 00322 } else { 00323 if (option_verbose) 00324 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description()); 00325 } 00326 00327 // add module 'm' to end of module_list chain 00328 // so reload commands will be issued in same order modules were loaded 00329 m->next = NULL; 00330 if (module_list == NULL) { 00331 // empty list so far, add at front 00332 module_list = m; 00333 } 00334 else { 00335 struct module *i; 00336 // find end of chain, and add there 00337 for (i = module_list; i->next; i = i->next) 00338 ; 00339 i->next = m; 00340 } 00341 00342 modlistver = rand(); 00343 ast_mutex_unlock(&modlock); 00344 if ((res = m->load_module())) { 00345 ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res); 00346 ast_unload_resource(resource_name, 0); 00347 return -1; 00348 } 00349 ast_update_use_count(); 00350 return 0; 00351 }
|
|
Ask this procedure to be run with modules have been updated.
Definition at line 490 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and malloc. 00491 { 00492 struct loadupdate *tmp; 00493 /* XXX Should be more flexible here, taking > 1 verboser XXX */ 00494 if ((tmp = malloc(sizeof (struct loadupdate)))) { 00495 tmp->updater = v; 00496 if (ast_mutex_lock(&modlock)) 00497 ast_log(LOG_WARNING, "Failed to lock\n"); 00498 tmp->next = updaters; 00499 updaters = tmp; 00500 ast_mutex_unlock(&modlock); 00501 return 0; 00502 } 00503 return -1; 00504 }
|
|
No longer run me when modules are updated.
Definition at line 506 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING. 00507 { 00508 int res = -1; 00509 struct loadupdate *tmp, *tmpl=NULL; 00510 if (ast_mutex_lock(&modlock)) 00511 ast_log(LOG_WARNING, "Failed to lock\n"); 00512 tmp = updaters; 00513 while(tmp) { 00514 if (tmp->updater == v) { 00515 if (tmpl) 00516 tmpl->next = tmp->next; 00517 else 00518 updaters = tmp->next; 00519 break; 00520 } 00521 tmpl = tmp; 00522 tmp = tmp->next; 00523 } 00524 if (tmp) 00525 res = 0; 00526 ast_mutex_unlock(&modlock); 00527 return res; 00528 }
|
|
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 152 of file loader.c. References ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_rtp_reload(), ast_verbose(), module::description, module::next, option_verbose, read_ast_cust_config(), module::reload, reload(), reload_manager(), module::resource, and VERBOSE_PREFIX_3. 00153 { 00154 struct module *m; 00155 int oldversion; 00156 int (*reload)(void); 00157 00158 /* We'll do the logger and manager the favor of calling its reload here first */ 00159 00160 if (ast_mutex_trylock(&reloadlock)) { 00161 ast_verbose("The previous reload command didn't finish yet\n"); 00162 return; 00163 } 00164 if (!name || !strcasecmp(name, "astconfig")) 00165 read_ast_cust_config(); 00166 if (!name || !strcasecmp(name, "manager")) 00167 reload_manager(); 00168 if (!name || !strcasecmp(name, "enum")) 00169 ast_enum_reload(); 00170 if (!name || !strcasecmp(name, "rtp")) 00171 ast_rtp_reload(); 00172 time(&ast_lastreloadtime); 00173 00174 ast_mutex_lock(&modlock); 00175 oldversion = modlistver; 00176 m = module_list; 00177 while(m) { 00178 if (!name || !strcasecmp(name, m->resource)) { 00179 reload = m->reload; 00180 ast_mutex_unlock(&modlock); 00181 if (reload) { 00182 if (option_verbose > 2) 00183 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); 00184 reload(); 00185 } 00186 ast_mutex_lock(&modlock); 00187 if (oldversion != modlistver) 00188 break; 00189 } 00190 m = m->next; 00191 } 00192 ast_mutex_unlock(&modlock); 00193 ast_mutex_unlock(&reloadlock); 00194 }
|
|
Definition at line 135 of file asterisk.c. References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc. 00136 { 00137 int res = -1; 00138 struct ast_atexit *ae; 00139 ast_unregister_atexit(func); 00140 ae = malloc(sizeof(struct ast_atexit)); 00141 ast_mutex_lock(&atexitslock); 00142 if (ae) { 00143 memset(ae, 0, sizeof(struct ast_atexit)); 00144 ae->next = atexits; 00145 ae->func = func; 00146 atexits = ae; 00147 res = 0; 00148 } 00149 ast_mutex_unlock(&atexitslock); 00150 return res; 00151 }
|
|
Unloads a module.
Definition at line 108 of file loader.c. References AST_FORCE_FIRM, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_update_use_count(), dlclose(), free, module::lib, LOG_WARNING, module::next, module::resource, module::unload_module, and module::usecount. Referenced by ast_load_resource(). 00109 { 00110 struct module *m, *ml = NULL; 00111 int res = -1; 00112 if (ast_mutex_lock(&modlock)) 00113 ast_log(LOG_WARNING, "Failed to lock\n"); 00114 m = module_list; 00115 while(m) { 00116 if (!strcasecmp(m->resource, resource_name)) { 00117 if ((res = m->usecount()) > 0) { 00118 if (force) 00119 ast_log(LOG_WARNING, "Warning: Forcing removal of module %s with use count %d\n", resource_name, res); 00120 else { 00121 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res); 00122 ast_mutex_unlock(&modlock); 00123 return -1; 00124 } 00125 } 00126 res = m->unload_module(); 00127 if (res) { 00128 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00129 if (force <= AST_FORCE_FIRM) { 00130 ast_mutex_unlock(&modlock); 00131 return -1; 00132 } else 00133 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00134 } 00135 if (ml) 00136 ml->next = m->next; 00137 else 00138 module_list = m->next; 00139 dlclose(m->lib); 00140 free(m); 00141 break; 00142 } 00143 ml = m; 00144 m = m->next; 00145 } 00146 modlistver = rand(); 00147 ast_mutex_unlock(&modlock); 00148 ast_update_use_count(); 00149 return res; 00150 }
|
|
Definition at line 153 of file asterisk.c. References ast_mutex_lock, and ast_mutex_unlock. Referenced by ast_register_atexit(). 00154 { 00155 struct ast_atexit *ae, *prev = NULL; 00156 ast_mutex_lock(&atexitslock); 00157 ae = atexits; 00158 while(ae) { 00159 if (ae->func == func) { 00160 if (prev) 00161 prev->next = ae->next; 00162 else 00163 atexits = ae->next; 00164 break; 00165 } 00166 prev = ae; 00167 ae = ae->next; 00168 } 00169 ast_mutex_unlock(&atexitslock); 00170 }
|
|
Ask for a list of modules, descriptions, and use counts.
Definition at line 474 of file loader.c. References ast_mutex_trylock, ast_mutex_unlock, module::description, module::next, module::resource, and module::usecount. 00475 { 00476 struct module *m; 00477 int unlock = -1; 00478 if (ast_mutex_trylock(&modlock)) 00479 unlock = 0; 00480 m = module_list; 00481 while(m) { 00482 modentry(m->resource, m->description(), m->usecount()); 00483 m = m->next; 00484 } 00485 if (unlock) 00486 ast_mutex_unlock(&modlock); 00487 return 0; 00488 }
|
|
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 458 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(). 00459 { 00460 /* Notify any module monitors that the use count for a 00461 resource has changed */ 00462 struct loadupdate *m; 00463 if (ast_mutex_lock(&modlock)) 00464 ast_log(LOG_WARNING, "Failed to lock\n"); 00465 m = updaters; 00466 while(m) { 00467 m->updater(); 00468 m = m->next; 00469 } 00470 ast_mutex_unlock(&modlock); 00471 00472 }
|
|
Description. Returns a short description of your module. |
|
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_config_destroy_all(), 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. Referenced by ast_module_reload(). |
|
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. |