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 177 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, dlclose(), dlerror(), dlopen(), dlsym(), free, fully_booted, key(), LOG_WARNING, malloc, option_console, option_verbose, RTLD_GLOBAL, RTLD_LAZY, RTLD_NOW, term_color(), and VERBOSE_PREFIX_1. Referenced by load_modules().
00178 { 00179 static char fn[256]; 00180 int errors=0; 00181 int res; 00182 struct module *m; 00183 int flags=RTLD_NOW; 00184 #ifdef RTLD_GLOBAL 00185 char *val; 00186 #endif 00187 char *key; 00188 int o; 00189 struct ast_config *cfg; 00190 char tmp[80]; 00191 /* Keep the module file parsing silent */ 00192 o = option_verbose; 00193 if (strncasecmp(resource_name, "res_", 4)) { 00194 option_verbose = 0; 00195 cfg = ast_load(AST_MODULE_CONFIG); 00196 option_verbose = o; 00197 if (cfg) { 00198 #ifdef RTLD_GLOBAL 00199 if ((val = ast_variable_retrieve(cfg, "global", resource_name)) 00200 && ast_true(val)) 00201 flags |= RTLD_GLOBAL; 00202 #endif 00203 ast_destroy(cfg); 00204 } 00205 } else { 00206 /* Resource modules are always loaded global and lazy */ 00207 #ifdef RTLD_GLOBAL 00208 flags = (RTLD_GLOBAL | RTLD_LAZY); 00209 #else 00210 flags = RTLD_LAZY; 00211 #endif 00212 } 00213 00214 if (ast_mutex_lock(&modlock)) 00215 ast_log(LOG_WARNING, "Failed to lock\n"); 00216 m = module_list; 00217 while(m) { 00218 if (!strcasecmp(m->resource, resource_name)) { 00219 ast_log(LOG_WARNING, "Module '%s' already exists\n", resource_name); 00220 ast_mutex_unlock(&modlock); 00221 return -1; 00222 } 00223 m = m->next; 00224 } 00225 m = malloc(sizeof(struct module)); 00226 if (!m) { 00227 ast_log(LOG_WARNING, "Out of memory\n"); 00228 ast_mutex_unlock(&modlock); 00229 return -1; 00230 } 00231 strncpy(m->resource, resource_name, sizeof(m->resource)-1); 00232 if (resource_name[0] == '/') { 00233 strncpy(fn, resource_name, sizeof(fn)-1); 00234 } else { 00235 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_MODULE_DIR, resource_name); 00236 } 00237 m->lib = dlopen(fn, flags); 00238 if (!m->lib) { 00239 ast_log(LOG_WARNING, "%s\n", dlerror()); 00240 free(m); 00241 ast_mutex_unlock(&modlock); 00242 return -1; 00243 } 00244 m->load_module = dlsym(m->lib, "load_module"); 00245 if (m->load_module == NULL) 00246 m->load_module = dlsym(m->lib, "_load_module"); 00247 if (!m->load_module) { 00248 ast_log(LOG_WARNING, "No load_module in module %s\n", fn); 00249 errors++; 00250 } 00251 m->unload_module = dlsym(m->lib, "unload_module"); 00252 if (m->unload_module == NULL) 00253 m->unload_module = dlsym(m->lib, "_unload_module"); 00254 if (!m->unload_module) { 00255 ast_log(LOG_WARNING, "No unload_module in module %s\n", fn); 00256 errors++; 00257 } 00258 m->usecount = dlsym(m->lib, "usecount"); 00259 if (m->usecount == NULL) 00260 m->usecount = dlsym(m->lib, "_usecount"); 00261 if (!m->usecount) { 00262 ast_log(LOG_WARNING, "No usecount in module %s\n", fn); 00263 errors++; 00264 } 00265 m->description = dlsym(m->lib, "description"); 00266 if (m->description == NULL) 00267 m->description = dlsym(m->lib, "_description"); 00268 if (!m->description) { 00269 ast_log(LOG_WARNING, "No description in module %s\n", fn); 00270 errors++; 00271 } 00272 m->key = dlsym(m->lib, "key"); 00273 if (m->key == NULL) 00274 m->key = dlsym(m->lib, "_key"); 00275 if (!m->key) { 00276 ast_log(LOG_WARNING, "No key routine in module %s\n", fn); 00277 errors++; 00278 } 00279 m->reload = dlsym(m->lib, "reload"); 00280 if (m->reload == NULL) 00281 m->reload = dlsym(m->lib, "_reload"); 00282 if (m->key && !(key = m->key())) { 00283 ast_log(LOG_WARNING, "Key routine returned NULL in module %s\n", fn); 00284 errors++; 00285 } else 00286 key = NULL; 00287 if (key && verify_key(key)) { 00288 ast_log(LOG_WARNING, "Unexpected key returned by module %s\n", fn); 00289 errors++; 00290 } 00291 if (errors) { 00292 ast_log(LOG_WARNING, "%d error(s) loading module %s, aborted\n", errors, fn); 00293 dlclose(m->lib); 00294 free(m); 00295 ast_mutex_unlock(&modlock); 00296 return -1; 00297 } 00298 if (!fully_booted) { 00299 if (option_verbose) 00300 ast_verbose( " => (%s)\n", term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp))); 00301 if (option_console && !option_verbose) 00302 ast_verbose( "."); 00303 } else { 00304 if (option_verbose) 00305 ast_verbose(VERBOSE_PREFIX_1 "Loaded %s => (%s)\n", fn, m->description()); 00306 } 00307 m->next = module_list; 00308 00309 module_list = m; 00310 ast_mutex_unlock(&modlock); 00311 if ((res = m->load_module())) { 00312 ast_log(LOG_WARNING, "%s: load_module failed, returning %d\n", m->resource, res); 00313 ast_unload_resource(resource_name, 0); 00314 return -1; 00315 } 00316 ast_update_use_count(); 00317 return 0; 00318 } |
|
Ask this procedure to be run with modules have been updated.
Definition at line 457 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, LOG_WARNING, and malloc.
00458 { 00459 struct loadupdate *tmp; 00460 /* XXX Should be more flexible here, taking > 1 verboser XXX */ 00461 if ((tmp = malloc(sizeof (struct loadupdate)))) { 00462 tmp->updater = v; 00463 if (ast_mutex_lock(&modlock)) 00464 ast_log(LOG_WARNING, "Failed to lock\n"); 00465 tmp->next = updaters; 00466 updaters = tmp; 00467 ast_mutex_unlock(&modlock); 00468 return 0; 00469 } 00470 return -1; 00471 } |
|
No longer run me when modules are updated.
Definition at line 473 of file loader.c. References ast_log(), ast_mutex_lock, ast_mutex_unlock, and LOG_WARNING.
00474 { 00475 int res = -1; 00476 struct loadupdate *tmp, *tmpl=NULL; 00477 if (ast_mutex_lock(&modlock)) 00478 ast_log(LOG_WARNING, "Failed to lock\n"); 00479 tmp = updaters; 00480 while(tmp) { 00481 if (tmp->updater == v) { 00482 if (tmpl) 00483 tmpl->next = tmp->next; 00484 else 00485 updaters = tmp->next; 00486 break; 00487 } 00488 tmpl = tmp; 00489 tmp = tmp->next; 00490 } 00491 if (tmp) 00492 res = 0; 00493 ast_mutex_unlock(&modlock); 00494 return res; 00495 } |
|
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 148 of file loader.c. References ast_enum_reload(), ast_lastreloadtime, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_rtp_reload(), ast_verbose(), option_verbose, reload_manager(), and VERBOSE_PREFIX_3.
00149 { 00150 struct module *m; 00151 00152 /* We'll do the logger and manager the favor of calling its reload here first */ 00153 00154 if (ast_mutex_trylock(&reloadlock)) { 00155 ast_verbose("The previous reload command didn't finish yet\n"); 00156 return; 00157 } 00158 reload_manager(); 00159 ast_enum_reload(); 00160 ast_rtp_reload(); 00161 time(&ast_lastreloadtime); 00162 00163 ast_mutex_lock(&modlock); 00164 m = module_list; 00165 while(m) { 00166 if (m->reload) { 00167 if (option_verbose > 2) 00168 ast_verbose(VERBOSE_PREFIX_3 "Reloading module '%s' (%s)\n", m->resource, m->description()); 00169 m->reload(); 00170 } 00171 m = m->next; 00172 } 00173 ast_mutex_unlock(&modlock); 00174 ast_mutex_unlock(&reloadlock); 00175 } |
|
Definition at line 110 of file asterisk.c. References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc.
00111 { 00112 int res = -1; 00113 struct ast_atexit *ae; 00114 ast_unregister_atexit(func); 00115 ae = malloc(sizeof(struct ast_atexit)); 00116 ast_mutex_lock(&atexitslock); 00117 if (ae) { 00118 memset(ae, 0, sizeof(struct ast_atexit)); 00119 ae->next = atexits; 00120 ae->func = func; 00121 atexits = ae; 00122 res = 0; 00123 } 00124 ast_mutex_unlock(&atexitslock); 00125 return res; 00126 } |
|
Unloads a module.
Definition at line 106 of file loader.c. References AST_FORCE_FIRM, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_update_use_count(), dlclose(), free, LOG_WARNING, and module::next. Referenced by ast_load_resource().
00107 { 00108 struct module *m, *ml = NULL; 00109 int res = -1; 00110 if (ast_mutex_lock(&modlock)) 00111 ast_log(LOG_WARNING, "Failed to lock\n"); 00112 m = module_list; 00113 while(m) { 00114 if (!strcasecmp(m->resource, resource_name)) { 00115 if ((res = m->usecount()) > 0) { 00116 if (force) 00117 ast_log(LOG_WARNING, "Warning: Forcing removal of module %s with use count %d\n", resource_name, res); 00118 else { 00119 ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", resource_name, res); 00120 ast_mutex_unlock(&modlock); 00121 return -1; 00122 } 00123 } 00124 res = m->unload_module(); 00125 if (res) { 00126 ast_log(LOG_WARNING, "Firm unload failed for %s\n", resource_name); 00127 if (force <= AST_FORCE_FIRM) { 00128 ast_mutex_unlock(&modlock); 00129 return -1; 00130 } else 00131 ast_log(LOG_WARNING, "** Dangerous **: Unloading resource anyway, at user request\n"); 00132 } 00133 if (ml) 00134 ml->next = m->next; 00135 else 00136 module_list = m->next; 00137 dlclose(m->lib); 00138 free(m); 00139 } 00140 ml = m; 00141 m = m->next; 00142 } 00143 ast_mutex_unlock(&modlock); 00144 ast_update_use_count(); 00145 return res; 00146 } |
|
Definition at line 128 of file asterisk.c. References ast_mutex_lock, and ast_mutex_unlock. Referenced by ast_register_atexit().
00129 { 00130 struct ast_atexit *ae, *prev = NULL; 00131 ast_mutex_lock(&atexitslock); 00132 ae = atexits; 00133 while(ae) { 00134 if (ae->func == func) { 00135 if (prev) 00136 prev->next = ae->next; 00137 else 00138 atexits = ae->next; 00139 break; 00140 } 00141 prev = ae; 00142 ae = ae->next; 00143 } 00144 ast_mutex_unlock(&atexitslock); 00145 } |
|
Ask for a list of modules, descriptions, and use counts.
Definition at line 441 of file loader.c. References ast_mutex_trylock, ast_mutex_unlock, and module::next.
00442 { 00443 struct module *m; 00444 int unlock = -1; 00445 if (ast_mutex_trylock(&modlock)) 00446 unlock = 0; 00447 m = module_list; 00448 while(m) { 00449 modentry(m->resource, m->description(), m->usecount()); 00450 m = m->next; 00451 } 00452 if (unlock) 00453 ast_mutex_unlock(&modlock); 00454 return 0; 00455 } |
|
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 425 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().
00426 { 00427 /* Notify any module monitors that the use count for a 00428 resource has changed */ 00429 struct loadupdate *m; 00430 if (ast_mutex_lock(&modlock)) 00431 ast_log(LOG_WARNING, "Failed to lock\n"); 00432 m = updaters; 00433 while(m) { 00434 m->updater(); 00435 m = m->next; 00436 } 00437 ast_mutex_unlock(&modlock); 00438 00439 } |
|
Description. Returns a short description of your module. Referenced by ast_channel_register(), ast_channel_register_ex(), and ast_register_application(). |
|
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. |