diff options
author | Matthew Jordan <mjordan@digium.com> | 2013-05-24 20:44:07 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2013-05-24 20:44:07 +0000 |
commit | 06be8463b683333c79845402d55168ef1b582fa9 (patch) | |
tree | 2fe0871cfec4d5edf3aae763541ff7efa32a444a /main/loader.c | |
parent | c1b51fd2654736fd7c614d1571f904e236006651 (diff) |
Migrate a large number of AMI events over to Stasis-Core
This patch moves a number of AMI events over to the Stasis-Core message bus.
This includes:
* ChanSpyStart/Stop
* MonitorStart/Stop
* MusicOnHoldStart/Stop
* FullyBooted/Reload
* All Voicemail/MWI related events
In addition, it adds some Stasis-Core and AMI support for generic AMI messages,
refactors the message router in AMI to use a single router with topic
forwarding for the topics that AMI cares about, and refactors MWI message
types and topics to be more name compliant.
Review: https://reviewboard.asterisk.org/r/2532
(closes issue ASTERISK-21462)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389733 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/loader.c')
-rw-r--r-- | main/loader.c | 138 |
1 files changed, 94 insertions, 44 deletions
diff --git a/main/loader.c b/main/loader.c index 3bcf37ca9..7e5a5ae3b 100644 --- a/main/loader.c +++ b/main/loader.c @@ -63,6 +63,30 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/utils.h" /*** DOCUMENTATION + <managerEvent language="en_US" name="Reload"> + <managerEventInstance class="EVENT_FLAG_SYSTEM"> + <synopsis>Raised when a module has been reloaded in Asterisk.</synopsis> + <syntax> + <parameter name="Module"> + <para>The name of the module that was reloaded, or + <literal>All</literal> if all modules were reloaded</para> + </parameter> + <parameter name="Status"> + <para>The numeric status code denoting the success or failure + of the reload request.</para> + <enumlist> + <enum name="0"><para>Success</para></enum> + <enum name="1"><para>Request queued</para></enum> + <enum name="2"><para>Module not found</para></enum> + <enum name="3"><para>Error</para></enum> + <enum name="4"><para>Reload already in progress</para></enum> + <enum name="5"><para>Module uninitialized</para></enum> + <enum name="6"><para>Reload not supported</para></enum> + </enumlist> + </parameter> + </syntax> + </managerEventInstance> + </managerEvent> ***/ #ifndef RTLD_NOW @@ -709,22 +733,63 @@ static void queue_reload_request(const char *module) AST_LIST_UNLOCK(&reload_queue); } -int ast_module_reload(const char *name) +/*! + * \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) +{ + 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]; + + snprintf(res_buffer, sizeof(res_buffer), "%d", 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", + "class_type", EVENT_FLAG_SYSTEM, + "event", event_object); + + if (!json_object) { + return; + } + + payload = ast_json_payload_create(json_object); + if (!payload) { + return; + } + + message = stasis_message_create(ast_manager_get_generic_type(), payload); + if (!message) { + return; + } + + stasis_publish(ast_manager_get_topic(), message); +} + +enum ast_module_reload_result ast_module_reload(const char *name) { struct ast_module *cur; - int res = 0; /* return value. 0 = not found, others, see below */ + enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND; int i; /* If we aren't fully booted, we just pretend we reloaded but we queue this up to run once we are booted up. */ if (!ast_fully_booted) { queue_reload_request(name); - return 0; + res = AST_MODULE_RELOAD_QUEUED; + goto module_reload_exit; } if (ast_mutex_trylock(&reloadlock)) { ast_verbose("The previous reload command didn't finish yet\n"); - return -1; /* reload already in progress */ + res = AST_MODULE_RELOAD_IN_PROGRESS; + goto module_reload_exit; } ast_lastreloadtime = ast_tvnow(); @@ -740,26 +805,26 @@ int ast_module_reload(const char *name) if (res != AST_LOCK_SUCCESS) { ast_verbose("Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR); ast_mutex_unlock(&reloadlock); - return -1; + res = AST_MODULE_RELOAD_ERROR; + goto module_reload_exit; } } /* Call "predefined" reload here first */ for (i = 0; reload_classes[i].name; i++) { if (!name || !strcasecmp(name, reload_classes[i].name)) { - if (!reload_classes[i].reload_fn()) { - ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", name); + if (reload_classes[i].reload_fn() == AST_MODULE_LOAD_SUCCESS) { + res = AST_MODULE_RELOAD_SUCCESS; } - res = 2; /* found and reloaded */ } } - if (name && res) { + if (name && res == AST_MODULE_RELOAD_SUCCESS) { if (ast_opt_lock_confdir) { ast_unlock_path(ast_config_AST_CONFIG_DIR); } ast_mutex_unlock(&reloadlock); - return res; + goto module_reload_exit; } AST_LIST_LOCK(&module_list); @@ -770,28 +835,30 @@ int ast_module_reload(const char *name) continue; if (!cur->flags.running || cur->flags.declined) { - if (!name) + if (res == AST_MODULE_RELOAD_NOT_FOUND) { + res = AST_MODULE_RELOAD_UNINITIALIZED; + } + if (!name) { continue; - ast_log(LOG_NOTICE, "The module '%s' was not properly initialized. " - "Before reloading the module, you must run \"module load %s\" " - "and fix whatever is preventing the module from being initialized.\n", - name, name); - res = 2; /* Don't report that the module was not found */ + } break; } if (!info->reload) { /* cannot be reloaded */ - /* Nothing to reload, so reload is successful */ - ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource); - if (res < 1) /* store result if possible */ - res = 1; /* 1 = no reload() method */ - continue; + if (res == AST_MODULE_RELOAD_NOT_FOUND) { + res = AST_MODULE_RELOAD_NOT_IMPLEMENTED; + } + if (!name) { + continue; + } + break; } - - res = 2; ast_verb(3, "Reloading module '%s' (%s)\n", cur->resource, info->description); - if (!info->reload()) { - ast_test_suite_event_notify("MODULE_RELOAD", "Message: %s", cur->resource); + if (info->reload() == AST_MODULE_LOAD_SUCCESS) { + res = AST_MODULE_RELOAD_SUCCESS; + } + if (name) { + break; } } AST_LIST_UNLOCK(&module_list); @@ -801,6 +868,8 @@ int ast_module_reload(const char *name) } ast_mutex_unlock(&reloadlock); +module_reload_exit: + publish_reload_message(name, res); return res; } @@ -1212,25 +1281,6 @@ done: } AST_LIST_UNLOCK(&module_list); - - /* Tell manager clients that are aggressive at logging in that we're done - loading modules. If there's a DNS problem in chan_sip, we might not - even reach this */ - /*** DOCUMENTATION - <managerEventInstance> - <synopsis>Raised when all dynamic modules have finished their initial loading.</synopsis> - <syntax> - <parameter name="ModuleSelection"> - <enumlist> - <enum name="Preload"/> - <enum name="All"/> - </enumlist> - </parameter> - </syntax> - </managerEventInstance> - ***/ - manager_event(EVENT_FLAG_SYSTEM, "ModuleLoadReport", "ModuleLoadStatus: Done\r\nModuleSelection: %s\r\nModuleCount: %d\r\n", preload_only ? "Preload" : "All", modulecount); - return res; } |