From: Sungtae Kim Date: Tue, 6 Feb 2018 20:27:55 +0000 (+0100) Subject: manager: Add AMI event Load/Unload X-Git-Tag: 16.0.0-rc1~333^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb4cfb8c4309fdb1efa487615d52236497847a1d;p=thirdparty%2Fasterisk.git manager: Add AMI event Load/Unload Add an AMI events Load and Unload for notify when the module has been loaded and unloaded. ASTERISK-27661 Change-Id: Ib916c41eddd63651952998f2f49c57c42ef87a64 --- diff --git a/main/loader.c b/main/loader.c index 6b29f0e969..08d9552ff0 100644 --- a/main/loader.c +++ b/main/loader.c @@ -87,6 +87,40 @@ + + + Raised when a module has been loaded in Asterisk. + + + The name of the module that was loaded + + + The result of the load request. + + Module could not be loaded properly + Module loaded and configured + Module is not configured + + + + + + + + Raised when a module has been unloaded in Asterisk. + + + The name of the module that was unloaded + + + The result of the unload request. + + Module unloaded successfully + + + + + ***/ #ifndef RTLD_NOW @@ -161,6 +195,27 @@ struct ast_module { static AST_DLLIST_HEAD_STATIC(module_list, ast_module); + +struct load_results_map { + int result; + const char *name; +}; + +static const struct load_results_map load_results[] = { + { AST_MODULE_LOAD_SUCCESS, "Success" }, + { AST_MODULE_LOAD_DECLINE, "Decline" }, + { AST_MODULE_LOAD_SKIP, "Skip" }, + { AST_MODULE_LOAD_PRIORITY, "Priority" }, + { AST_MODULE_LOAD_FAILURE, "Failure" }, +}; +#define AST_MODULE_LOAD_UNKNOWN_STRING "Unknown" /* Status string for unknown load status */ + +static void publish_load_message_type(const char* type, const char *name, const char *status); +static void publish_reload_message(const char *name, enum ast_module_reload_result result); +static void publish_load_message(const char *name, enum ast_module_load_result result); +static void publish_unload_message(const char *name, const char* status); + + /* * module_list is cleared by its constructor possibly after * we start accumulating built-in modules, so we need to @@ -1007,6 +1062,7 @@ int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode f unload_dynamic_module(mod); ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name); ast_update_use_count(); + publish_unload_message(resource_name, "Success"); } return res; @@ -1196,29 +1252,30 @@ static void queue_reload_request(const char *module) /*! * \since 12 * \internal - * \brief Publish a \ref stasis message regarding the reload result + * \brief Publish a \ref stasis message regarding the type. */ -static void publish_reload_message(const char *name, enum ast_module_reload_result result) +static void publish_load_message_type(const char* type, const char *name, const char *status) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref); RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref); - char res_buffer[8]; + + ast_assert(type != NULL); + ast_assert(!ast_strlen_zero(name)); + ast_assert(!ast_strlen_zero(status)); if (!ast_manager_get_generic_type()) { return; } - snprintf(res_buffer, sizeof(res_buffer), "%u", result); - event_object = ast_json_pack("{s: s, s: s}", - "Module", S_OR(name, "All"), - "Status", res_buffer); - json_object = ast_json_pack("{s: s, s: i, s: o}", - "type", "Reload", + event_object = ast_json_pack("{s:s, s:s}", + "Module", name, + "Status", status); + json_object = ast_json_pack("{s:s, s:i, s:o}", + "type", type, "class_type", EVENT_FLAG_SYSTEM, "event", ast_json_ref(event_object)); - if (!json_object) { return; } @@ -1236,6 +1293,54 @@ static void publish_reload_message(const char *name, enum ast_module_reload_resu stasis_publish(ast_manager_get_topic(), message); } +static const char* loadresult2str(enum ast_module_load_result result) +{ + int i; + for (i = 0; i < ARRAY_LEN(load_results); i++) { + if (load_results[i].result == result) { + return load_results[i].name; + } + } + + ast_log(LOG_WARNING, "Failed to find correct load result status. result %d\n", result); + return AST_MODULE_LOAD_UNKNOWN_STRING; +} + +/*! + * \internal + * \brief Publish a \ref stasis message regarding the load result + */ +static void publish_load_message(const char *name, enum ast_module_load_result result) +{ + const char *status; + + status = loadresult2str(result); + + publish_load_message_type("Load", name, status); +} + +/*! + * \internal + * \brief Publish a \ref stasis message regarding the unload result + */ +static void publish_unload_message(const char *name, const char* status) +{ + publish_load_message_type("Unload", name, status); +} + +/*! + * \since 12 + * \internal + * \brief Publish a \ref stasis message regarding the reload result + */ +static void publish_reload_message(const char *name, enum ast_module_reload_result result) +{ + char res_buffer[8]; + + snprintf(res_buffer, sizeof(res_buffer), "%u", result); + publish_load_message_type("Reload", S_OR(name, "All"), res_buffer); +} + enum ast_module_reload_result ast_module_reload(const char *name) { struct ast_module *cur; @@ -1462,10 +1567,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp); res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp); if (res) { - ast_log(LOG_WARNING, "Failed to initialize dependency structures for module '%s'.\n", resource_name); - unload_dynamic_module(mod); - - return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + goto prestart_error; } } @@ -1484,12 +1586,20 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi res = start_resource(mod); } + if (ast_fully_booted && !ast_shutdown_final()) { + publish_load_message(resource_name, res); + } + return res; prestart_error: ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); unload_dynamic_module(mod); - return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + res = required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + if (ast_fully_booted && !ast_shutdown_final()) { + publish_load_message(resource_name, res); + } + return res; } int ast_load_resource(const char *resource_name)