[Asterisk-code-review] modules: change module LOAD FAILUREs to LOAD DECLINES (asterisk[master])

Anonymous Coward asteriskteam at digium.com
Thu Apr 13 07:03:43 CDT 2017


Anonymous Coward #1000019 has submitted this change and it was merged. ( https://gerrit.asterisk.org/5452 )

Change subject: modules:  change module LOAD_FAILUREs to LOAD_DECLINES
......................................................................


modules:  change module LOAD_FAILUREs to LOAD_DECLINES

In all non-pbx modules, AST_MODULE_LOAD_FAILURE has been changed
to AST_MODULE_LOAD_DECLINE.  This prevents asterisk from exiting
if a module can't be loaded.  If the user wishes to retain the
FAILURE behavior for a specific module, they can use the "require"
or "preload-require" keyword in modules.conf.

A new API was added to logger: ast_is_logger_initialized().  This
allows asterisk.c/check_init() to print to the error log once the
logger subsystem is ready instead of just to stdout.  If something
does fail before the logger is initialized, we now print to stderr
instead of stdout.

Change-Id: I5f4b50623d9b5a6cb7c5624a8c5c1274c13b2b25
---
M addons/cdr_mysql.c
M addons/chan_mobile.c
M apps/app_adsiprog.c
M apps/app_agent_pool.c
M apps/app_alarmreceiver.c
M apps/app_authenticate.c
M apps/app_cdr.c
M apps/app_confbridge.c
M apps/app_dahdiras.c
M apps/app_forkcdr.c
M apps/app_queue.c
M apps/app_voicemail.c
M apps/app_zapateller.c
M cdr/cdr_custom.c
M cel/cel_custom.c
M cel/cel_odbc.c
M channels/chan_alsa.c
M channels/chan_dahdi.c
M channels/chan_iax2.c
M channels/chan_mgcp.c
M channels/chan_motif.c
M channels/chan_nbs.c
M channels/chan_oss.c
M channels/chan_phone.c
M channels/chan_pjsip.c
M channels/chan_sip.c
M channels/chan_skinny.c
M channels/chan_unistim.c
M codecs/codec_a_mu.c
M codecs/codec_adpcm.c
M codecs/codec_alaw.c
M codecs/codec_g722.c
M codecs/codec_g726.c
M codecs/codec_gsm.c
M codecs/codec_ilbc.c
M codecs/codec_lpc10.c
M codecs/codec_resample.c
M codecs/codec_ulaw.c
M formats/format_g723.c
M formats/format_g726.c
M formats/format_g729.c
M formats/format_gsm.c
M formats/format_h263.c
M formats/format_h264.c
M formats/format_ilbc.c
M formats/format_jpeg.c
M formats/format_ogg_vorbis.c
M formats/format_pcm.c
M formats/format_sln.c
M formats/format_vox.c
M formats/format_wav.c
M formats/format_wav_gsm.c
M funcs/func_cdr.c
M funcs/func_holdintercept.c
M funcs/func_talkdetect.c
M include/asterisk/logger.h
M main/asterisk.c
M main/loader.c
M main/logger.c
M res/res_ari.c
M res/res_ari_events.c
M res/res_ari_model.c
M res/res_calendar.c
M res/res_chan_stats.c
M res/res_config_sqlite.c
M res/res_config_sqlite3.c
M res/res_endpoint_stats.c
M res/res_hep_rtcp.c
M res/res_http_websocket.c
M res/res_limit.c
M res/res_pjsip/config_transport.c
M res/res_pjsip_nat.c
M res/res_pjsip_one_touch_record_info.c
M res/res_pjsip_outbound_publish.c
M res/res_pjsip_outbound_registration.c
M res/res_pjsip_pubsub.c
M res/res_pjsip_sdp_rtp.c
M res/res_pjsip_send_to_voicemail.c
M res/res_pjsip_t38.c
M res/res_smdi.c
M res/res_stasis.c
M res/res_stasis_device_state.c
M res/res_stasis_playback.c
M res/res_stasis_recording.c
M res/res_stasis_test.c
M res/res_statsd.c
M rest-api-templates/res_ari_resource.c.mustache
M tests/test_bucket.c
M tests/test_channel_feature_hooks.c
89 files changed, 422 insertions(+), 331 deletions(-)

Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, approved



diff --git a/addons/cdr_mysql.c b/addons/cdr_mysql.c
index 0878950..f8f4192 100644
--- a/addons/cdr_mysql.c
+++ b/addons/cdr_mysql.c
@@ -351,9 +351,20 @@
 	return 0;
 }
 
+static void free_strings(void)
+{
+	struct unload_string *us;
+
+	AST_LIST_LOCK(&unload_strings);
+	while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
+		ast_free(us->str);
+		ast_free(us);
+	}
+	AST_LIST_UNLOCK(&unload_strings);
+}
+
 static int my_unload_module(int reload)
 { 
-	struct unload_string *us;
 	struct column *entry;
 
 	ast_cli_unregister_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));
@@ -364,12 +375,7 @@
 		records = 0;
 	}
 
-	AST_LIST_LOCK(&unload_strings);
-	while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {
-		ast_free(us->str);
-		ast_free(us);
-	}
-	AST_LIST_UNLOCK(&unload_strings);
+	free_strings();
 
 	if (!reload) {
 		AST_RWLIST_WRLOCK(&columns);
@@ -505,13 +511,16 @@
 	} else {
 		calldate_compat = 0;
 	}
+	ast_free(compat);
 
 	if (res < 0) {
 		if (reload) {
 			AST_RWLIST_UNLOCK(&columns);
 		}
 		ast_config_destroy(cfg);
-		return AST_MODULE_LOAD_FAILURE;
+		free_strings();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Check for any aliases */
@@ -582,7 +591,9 @@
 			connected = 0;
 			AST_RWLIST_UNLOCK(&columns);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			free_strings();
+
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		if (!(result = mysql_store_result(&mysql))) {
@@ -591,7 +602,9 @@
 			connected = 0;
 			AST_RWLIST_UNLOCK(&columns);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			free_strings();
+
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		while ((row = mysql_fetch_row(result))) {
@@ -657,7 +670,8 @@
 	AST_RWLIST_UNLOCK(&columns);
 	ast_config_destroy(cfg);
 	if (res < 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		my_unload_module(0);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!reload) {
@@ -671,7 +685,12 @@
 		res = ast_cli_register_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));
 	}
 
-	return res;
+	if (res) {
+		my_unload_module(0);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int load_module(void)
diff --git a/addons/chan_mobile.c b/addons/chan_mobile.c
index bd39bee..8f04af7 100644
--- a/addons/chan_mobile.c
+++ b/addons/chan_mobile.c
@@ -4704,9 +4704,13 @@
 	ast_format_cap_append(mbl_tech.capabilities, DEVICE_FRAME_FORMAT, 0);
 	/* Check if we have Bluetooth, no point loading otherwise... */
 	dev_id = hci_get_route(NULL);
+
 	s = hci_open_dev(dev_id);
 	if (dev_id < 0 || s < 0) {
 		ast_log(LOG_ERROR, "No Bluetooth devices found. Not loading module.\n");
+		ao2_ref(mbl_tech.capabilities, -1);
+		mbl_tech.capabilities = NULL;
+		hci_close_dev(s);
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -4714,6 +4718,8 @@
 
 	if (mbl_load_config()) {
 		ast_log(LOG_ERROR, "Errors reading config file %s. Not loading module.\n", MBL_CONFIG);
+		ao2_ref(mbl_tech.capabilities, -1);
+		mbl_tech.capabilities = NULL;
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -4738,10 +4744,9 @@
 	return AST_MODULE_LOAD_SUCCESS;
 
 e_cleanup:
-	if (sdp_session)
-		sdp_close(sdp_session);
+	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Bluetooth Mobile Device Channel Driver",
diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c
index 9d73702..6d485d6 100644
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -1605,7 +1605,7 @@
 static int load_module(void)
 {
 	if (ast_register_application_xml(app, adsi_exec))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/apps/app_agent_pool.c b/apps/app_agent_pool.c
index 4563b58..2e0c8e8 100644
--- a/apps/app_agent_pool.c
+++ b/apps/app_agent_pool.c
@@ -2653,7 +2653,7 @@
 	agents = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, agent_pvt_sort_cmp, agent_pvt_cmp);
 	if (!agents) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Init agent holding bridge v_table. */
@@ -2677,8 +2677,9 @@
 	res |= ast_register_application_xml(app_agent_request, agent_request_exec);
 
 	if (res) {
+		ast_log(LOG_ERROR, "Unable to register application. Not loading module.\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (load_config()) {
diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c
index 2169617..07885d2 100644
--- a/apps/app_alarmreceiver.c
+++ b/apps/app_alarmreceiver.c
@@ -975,7 +975,7 @@
 {
 	if (load_config(0)) {
 		if (ast_register_application_xml(app, alarmreceiver_exec)) {
-			return AST_MODULE_LOAD_FAILURE;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 		return AST_MODULE_LOAD_SUCCESS;
 	}
diff --git a/apps/app_authenticate.c b/apps/app_authenticate.c
index f58ed36..e0ad4a0 100644
--- a/apps/app_authenticate.c
+++ b/apps/app_authenticate.c
@@ -270,7 +270,7 @@
 static int load_module(void)
 {
 	if (ast_register_application_xml(app, auth_exec))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/apps/app_cdr.c b/apps/app_cdr.c
index 17dea43..1500c89 100644
--- a/apps/app_cdr.c
+++ b/apps/app_cdr.c
@@ -249,7 +249,7 @@
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type);
@@ -259,7 +259,8 @@
 	                                 appcdr_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 5ec20dd..a9f917b 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -3955,7 +3955,7 @@
 	if (register_channel_tech(conf_record_get_tech())
 		|| register_channel_tech(conf_announce_get_tech())) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Create a container to hold the conference bridges */
@@ -3963,7 +3963,7 @@
 		conference_bridge_hash_cb, conference_bridge_cmp_cb);
 	if (!conference_bridges) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Setup manager stasis subscriptions */
@@ -3988,7 +3988,7 @@
 	res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/apps/app_dahdiras.c b/apps/app_dahdiras.c
index 6eaa1bd..10c2962 100644
--- a/apps/app_dahdiras.c
+++ b/apps/app_dahdiras.c
@@ -223,7 +223,7 @@
 
 static int load_module(void)
 {
-	return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS);
+	return ((ast_register_application_xml(app, dahdiras_exec)) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
 }
 
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "DAHDI ISDN Remote Access Server");
diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c
index acd8982..5946c50 100644
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -199,7 +199,7 @@
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
@@ -208,7 +208,9 @@
 	                                 forkcdr_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/apps/app_queue.c b/apps/app_queue.c
index ae2d645..2389f0b 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -8892,7 +8892,7 @@
 		if (!(new_rl = ast_calloc(1, sizeof(*new_rl)))) {
 			AST_LIST_UNLOCK(&rule_lists);
 			ast_config_destroy(cfg);
-			return AST_MODULE_LOAD_FAILURE;
+			return AST_MODULE_LOAD_DECLINE;
 		} else {
 			ast_copy_string(new_rl->name, rulecat, sizeof(new_rl->name));
 			AST_LIST_INSERT_TAIL(&rule_lists, new_rl, list);
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index aebaafa..de82670 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -14974,7 +14974,7 @@
 	umask(my_umask);
 
 	if (!(inprocess_container = ao2_container_alloc(573, inprocess_hash_fn, inprocess_cmp_fn))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* compute the location of the voicemail spool directory */
diff --git a/apps/app_zapateller.c b/apps/app_zapateller.c
index e876a70..f62f7bb 100644
--- a/apps/app_zapateller.c
+++ b/apps/app_zapateller.c
@@ -132,7 +132,7 @@
 
 static int load_module(void)
 {
-	return ((ast_register_application_xml(app, zapateller_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS);
+	return ((ast_register_application_xml(app, zapateller_exec)) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
 }
 
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Block Telemarketers with Special Information Tone");
diff --git a/cdr/cdr_custom.c b/cdr/cdr_custom.c
index 7d8b9d8..fec20ea 100644
--- a/cdr/cdr_custom.c
+++ b/cdr/cdr_custom.c
@@ -203,7 +203,7 @@
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	load_config();
@@ -216,7 +216,7 @@
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/cel/cel_custom.c b/cel/cel_custom.c
index d165541..d05a126 100644
--- a/cel/cel_custom.c
+++ b/cel/cel_custom.c
@@ -191,14 +191,15 @@
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	load_config();
 	AST_RWLIST_UNLOCK(&sinks);
 
 	if (ast_cel_backend_register(CUSTOM_BACKEND_NAME, custom_log)) {
-		return AST_MODULE_LOAD_FAILURE;
+		free_config();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
@@ -207,7 +208,7 @@
 {
 	if (AST_RWLIST_WRLOCK(&sinks)) {
 		ast_log(LOG_ERROR, "Unable to lock sink list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/cel/cel_odbc.c b/cel/cel_odbc.c
index 2ab5114..a0cc6e3 100644
--- a/cel/cel_odbc.c
+++ b/cel/cel_odbc.c
@@ -801,13 +801,14 @@
 
 	if (AST_RWLIST_WRLOCK(&odbc_tables)) {
 		ast_log(LOG_ERROR, "Unable to lock column list.  Load failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	load_config();
 	AST_RWLIST_UNLOCK(&odbc_tables);
 	if (ast_cel_backend_register(ODBC_BACKEND_NAME, odbc_log)) {
 		ast_log(LOG_ERROR, "Unable to subscribe to CEL events\n");
-		return AST_MODULE_LOAD_FAILURE;
+		free_config();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
@@ -816,7 +817,7 @@
 {
 	if (AST_RWLIST_WRLOCK(&odbc_tables)) {
 		ast_log(LOG_ERROR, "Unable to lock column list.  Reload failed.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	free_config();
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index c50b540..c53c1a3 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -924,6 +924,26 @@
 	AST_CLI_DEFINE(console_mute, "Disable/Enable mic input"),
 };
 
+static int unload_module(void)
+{
+	ast_channel_unregister(&alsa_tech);
+	ast_cli_unregister_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
+
+	if (alsa.icard)
+		snd_pcm_close(alsa.icard);
+	if (alsa.ocard)
+		snd_pcm_close(alsa.ocard);
+	if (alsa.owner)
+		ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
+	if (alsa.owner)
+		return -1;
+
+	ao2_cleanup(alsa_tech.capabilities);
+	alsa_tech.capabilities = NULL;
+
+	return 0;
+}
+
 /*!
  * \brief Load the module
  *
@@ -994,37 +1014,21 @@
 	if (soundcard_init() < 0) {
 		ast_verb(2, "No sound card detected -- console channel will be unavailable\n");
 		ast_verb(2, "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
+		unload_module();
+
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_channel_register(&alsa_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_cli_register_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
 
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-	ast_channel_unregister(&alsa_tech);
-	ast_cli_unregister_multiple(cli_alsa, ARRAY_LEN(cli_alsa));
-
-	if (alsa.icard)
-		snd_pcm_close(alsa.icard);
-	if (alsa.ocard)
-		snd_pcm_close(alsa.ocard);
-	if (alsa.owner)
-		ast_softhangup(alsa.owner, AST_SOFTHANGUP_APPUNLOAD);
-	if (alsa.owner)
-		return -1;
-
-	ao2_cleanup(alsa_tech.capabilities);
-	alsa_tech.capabilities = NULL;
-
-	return 0;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ALSA Console Channel Driver",
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 97c80c8..72fbe6e 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -19530,11 +19530,11 @@
 #endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
 
 	if (STASIS_MESSAGE_TYPE_INIT(dahdichannel_type)) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(dahdi_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(dahdi_tech.capabilities, ast_format_slin, 0);
 	ast_format_cap_append(dahdi_tech.capabilities, ast_format_ulaw, 0);
@@ -19542,7 +19542,7 @@
 
 	if (dahdi_native_load(&dahdi_tech)) {
 		ao2_ref(dahdi_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 #ifdef HAVE_PRI
@@ -19560,7 +19560,7 @@
 	if (ast_cc_agent_register(&dahdi_pri_cc_agent_callbacks)
 		|| ast_cc_monitor_register(&dahdi_pri_cc_monitor_callbacks)) {
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #endif	/* defined(HAVE_PRI_CCSS) */
 	if (sig_pri_load(
@@ -19571,7 +19571,7 @@
 #endif	/* defined(HAVE_PRI_CCSS) */
 		)) {
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #endif
 #if defined(HAVE_SS7)
@@ -19594,7 +19594,7 @@
 	if (ast_channel_register(&dahdi_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'DAHDI'\n");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #ifdef HAVE_PRI
 	ast_cli_register_multiple(dahdi_pri_cli, ARRAY_LEN(dahdi_pri_cli));
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 38dc5c0..d15b55d 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -14886,7 +14886,7 @@
 	if (calltoken_ignores) {
 		ao2_ref(calltoken_ignores, -1);
 	}
-	return AST_MODULE_LOAD_FAILURE;
+	return -1;
 }
 
 
@@ -15091,12 +15091,14 @@
 	struct iax2_registry *reg = NULL;
 
 	if (!(iax2_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append_by_type(iax2_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
 
 	if (load_objects()) {
-		return AST_MODULE_LOAD_FAILURE;
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	memset(iaxs, 0, sizeof(iaxs));
@@ -15107,28 +15109,36 @@
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
-		return AST_MODULE_LOAD_FAILURE;
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sched_start_thread(sched)) {
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
 		ast_log(LOG_ERROR, "Failed to create I/O context\n");
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(netsock = ast_netsock_list_alloc())) {
 		ast_log(LOG_ERROR, "Failed to create netsock list\n");
 		io_context_destroy(io);
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_netsock_init(netsock);
 
@@ -15137,8 +15147,10 @@
 		ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
 		io_context_destroy(io);
 		ast_sched_context_destroy(sched);
+		ao2_ref(iax2_tech.capabilities, -1);
+		iax2_tech.capabilities = NULL;
 		sched = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_netsock_init(outsock);
 
@@ -15157,6 +15169,7 @@
 			ast_timer_close(timer);
 			timer = NULL;
 		}
+		__unload_module();
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -15182,7 +15195,7 @@
  	if (ast_channel_register(&iax2_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_register_switch(&iax2_switch)) {
@@ -15192,7 +15205,7 @@
 	if (start_network_thread()) {
 		ast_log(LOG_ERROR, "Unable to start network thread\n");
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	} else {
 		ast_verb(2, "IAX Ready and Listening\n");
 	}
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index af79e21..6cac4bc 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -4860,11 +4860,11 @@
 static int load_module(void)
 {
 	if (!(global_capability = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	if (!(mgcp_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		ao2_ref(global_capability, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(global_capability, ast_format_ulaw, 0);
 	ast_format_cap_append(mgcp_tech.capabilities, ast_format_ulaw, 0);
@@ -4873,7 +4873,7 @@
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
@@ -4881,7 +4881,7 @@
 		ast_sched_context_destroy(sched);
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (reload_config(0)) {
@@ -4897,7 +4897,7 @@
 		ast_sched_context_destroy(sched);
 		ao2_ref(global_capability, -1);
 		ao2_ref(mgcp_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_rtp_glue_register(&mgcp_rtp_glue);
diff --git a/channels/chan_motif.c b/channels/chan_motif.c
index 5828a11..7d696e8 100644
--- a/channels/chan_motif.c
+++ b/channels/chan_motif.c
@@ -2788,7 +2788,7 @@
 	ao2_cleanup(jingle_tech.capabilities);
 	jingle_tech.capabilities = NULL;
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 /*! \brief Reload module */
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index 61e5398..a12470c 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -257,12 +257,14 @@
 static int load_module(void)
 {
 	if (!(nbs_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(nbs_tech.capabilities, ast_format_slin, 0);
 	/* Make sure we can register our channel type */
 	if (ast_channel_register(&nbs_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
+		ao2_ref(nbs_tech.capabilities, -1);
+		nbs_tech.capabilities = NULL;
 		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 3e1e38d..ec112de 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -1435,6 +1435,31 @@
 #endif
 }
 
+static int unload_module(void)
+{
+	struct chan_oss_pvt *o, *next;
+
+	ast_channel_unregister(&oss_tech);
+	ast_cli_unregister_multiple(cli_oss, ARRAY_LEN(cli_oss));
+
+	o = oss_default.next;
+	while (o) {
+		close(o->sounddev);
+		if (o->owner)
+			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
+		if (o->owner)
+			return -1;
+		next = o->next;
+		ast_free(o->name);
+		ast_free(o);
+		o = next;
+	}
+	ao2_cleanup(oss_tech.capabilities);
+	oss_tech.capabilities = NULL;
+
+	return 0;
+}
+
 /*!
  * \brief Load the module
  *
@@ -1472,12 +1497,12 @@
 	if (find_desc(oss_active) == NULL) {
 		ast_log(LOG_NOTICE, "Device %s not found\n", oss_active);
 		/* XXX we could default to 'dsp' perhaps ? */
-		/* XXX should cleanup allocated memory etc. */
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(oss_tech.capabilities = ast_format_cap_alloc(0))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(oss_tech.capabilities, ast_format_slin, 0);
 
@@ -1492,32 +1517,6 @@
 	ast_cli_register_multiple(cli_oss, ARRAY_LEN(cli_oss));
 
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-
-static int unload_module(void)
-{
-	struct chan_oss_pvt *o, *next;
-
-	ast_channel_unregister(&oss_tech);
-	ast_cli_unregister_multiple(cli_oss, ARRAY_LEN(cli_oss));
-
-	o = oss_default.next;
-	while (o) {
-		close(o->sounddev);
-		if (o->owner)
-			ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
-		if (o->owner)
-			return -1;
-		next = o->next;
-		ast_free(o->name);
-		ast_free(o);
-		o = next;
-	}
-	ao2_cleanup(oss_tech.capabilities);
-	oss_tech.capabilities = NULL;
-
-	return 0;
 }
 
 AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "OSS Console Channel Driver");
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index aa10a56..76891ac 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1416,7 +1416,7 @@
 	if (ast_mutex_lock(&iflock)) {
 		/* It's a little silly to lock it, but we mind as well just to be sure */
 		ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	v = ast_variable_browse(cfg, "interfaces");
 	while(v) {
@@ -1432,7 +1432,7 @@
 					ast_config_destroy(cfg);
 					ast_mutex_unlock(&iflock);
 					__unload_module();
-					return AST_MODULE_LOAD_FAILURE;
+					return AST_MODULE_LOAD_DECLINE;
 				}
 		} else if (!strcasecmp(v->name, "silencesupression")) {
 			silencesupression = ast_true(v->value);
@@ -1508,7 +1508,7 @@
 		ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");
 		ast_config_destroy(cfg);
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_config_destroy(cfg);
 	/* And start the monitor for the first time */
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index 46c74ad..a928164 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2749,7 +2749,7 @@
 	ast_channel_unregister(&chan_pjsip_tech);
 	ast_rtp_glue_unregister(&chan_pjsip_rtp_glue);
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 /*! \brief Unload the PJSIP channel from Asterisk */
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5419a1d..affe937 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -35287,17 +35287,17 @@
 
 	if (STASIS_MESSAGE_TYPE_INIT(session_timeout_type)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(sip_tech.capabilities = ast_format_cap_alloc(0))) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sip_api_provider_register(&chan_sip_api_provider)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* the fact that ao2_containers can't resize automatically is a major worry! */
@@ -35312,12 +35312,12 @@
 		|| !threadt) {
 		ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(sip_cfg.caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append_by_type(sip_tech.capabilities, AST_MEDIA_TYPE_AUDIO);
 
@@ -35328,13 +35328,13 @@
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create scheduler context\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(io = io_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create I/O context\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	sip_reloadreason = CHANNEL_MODULE_LOAD;
@@ -35349,7 +35349,7 @@
 	if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
 		ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	/* Make sure the auth will always fail. */
 	ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET);
@@ -35366,14 +35366,14 @@
 
 	if (ast_msg_tech_register(&sip_msg_tech)) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Make sure we can register our sip channel type */
 	if (ast_channel_register(&sip_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 #ifdef TEST_FRAMEWORK
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index d1c2b92..a053000 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -8698,7 +8698,7 @@
 		ao2_ref(skinny_tech.capabilities, -1);
 		ao2_ref(default_cap, -1);
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Make sure we can register our skinny channel type */
@@ -8706,7 +8706,7 @@
 		ao2_ref(default_cap, -1);
 		ao2_ref(skinny_tech.capabilities, -1);
 		ast_log(LOG_ERROR, "Unable to register channel class 'Skinny'\n");
-		return -1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_rtp_glue_register(&skinny_rtp_glue);
@@ -8723,7 +8723,7 @@
 		ast_channel_unregister(&skinny_tech);
 		ao2_ref(default_cap, -1);
 		ao2_ref(skinny_tech.capabilities, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index f825221..b820cf5 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -7126,7 +7126,7 @@
 	global_cap = NULL;
 	ao2_cleanup(unistim_tech.capabilities);
 	unistim_tech.capabilities = NULL;
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 static int unload_module(void)
diff --git a/codecs/codec_a_mu.c b/codecs/codec_a_mu.c
index ea8d014..a2cce4e 100644
--- a/codecs/codec_a_mu.c
+++ b/codecs/codec_a_mu.c
@@ -141,7 +141,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c
index 3076d26..0b2f90f 100644
--- a/codecs/codec_adpcm.c
+++ b/codecs/codec_adpcm.c
@@ -346,7 +346,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_alaw.c b/codecs/codec_alaw.c
index ba16936..ebaca74 100644
--- a/codecs/codec_alaw.c
+++ b/codecs/codec_alaw.c
@@ -130,7 +130,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_g722.c b/codecs/codec_g722.c
index 9c868d3..48b5e4a 100644
--- a/codecs/codec_g722.c
+++ b/codecs/codec_g722.c
@@ -241,7 +241,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}	
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_g726.c b/codecs/codec_g726.c
index 4bf39b7..3b76628 100644
--- a/codecs/codec_g726.c
+++ b/codecs/codec_g726.c
@@ -890,7 +890,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}	
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c
index 2ae42a6..296747e 100644
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.c
@@ -239,7 +239,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_ilbc.c b/codecs/codec_ilbc.c
index 16466a9..d691f70 100644
--- a/codecs/codec_ilbc.c
+++ b/codecs/codec_ilbc.c
@@ -267,7 +267,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_lpc10.c b/codecs/codec_lpc10.c
index 5f6ffff..00e3022 100644
--- a/codecs/codec_lpc10.c
+++ b/codecs/codec_lpc10.c
@@ -272,7 +272,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_resample.c b/codecs/codec_resample.c
index b54f5c9..e0d530d 100644
--- a/codecs/codec_resample.c
+++ b/codecs/codec_resample.c
@@ -153,7 +153,7 @@
 
 	trans_size = ARRAY_LEN(codec_list) * (ARRAY_LEN(codec_list) - 1);
 	if (!(translators = ast_calloc(1, sizeof(struct ast_translator) * trans_size))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	for (x = 0; x < ARRAY_LEN(codec_list); x++) {
@@ -180,7 +180,7 @@
 	ast_unregister_translator won't fail.*/
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/codecs/codec_ulaw.c b/codecs/codec_ulaw.c
index cf4e358..e0a4f68 100644
--- a/codecs/codec_ulaw.c
+++ b/codecs/codec_ulaw.c
@@ -181,7 +181,7 @@
 
 	if (res) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/formats/format_g723.c b/formats/format_g723.c
index 750baca..04e03b6 100644
--- a/formats/format_g723.c
+++ b/formats/format_g723.c
@@ -142,7 +142,7 @@
 	g723_1_f.format = ast_format_g723;
 
 	if (ast_format_def_register(&g723_1_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_g726.c b/formats/format_g726.c
index f3b09f0..08e669e 100644
--- a/formats/format_g726.c
+++ b/formats/format_g726.c
@@ -221,20 +221,6 @@
 	{	.desc_size = 0 }	/* terminator */
 };
 
-static int load_module(void)
-{
-	int i;
-
-	for (i = 0; f[i].desc_size ; i++) {
-		f[i].format = ast_format_g726;
-		if (ast_format_def_register(&f[i])) {	/* errors are fatal */
-			ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
-			return AST_MODULE_LOAD_FAILURE;
-		}
-	}
-	return AST_MODULE_LOAD_SUCCESS;
-}
-
 static int unload_module(void)
 {
 	int i;
@@ -246,6 +232,21 @@
 	return(0);
 }
 
+static int load_module(void)
+{
+	int i;
+
+	for (i = 0; f[i].desc_size ; i++) {
+		f[i].format = ast_format_g726;
+		if (ast_format_def_register(&f[i])) {	/* errors are fatal */
+			ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
+			unload_module();
+			return AST_MODULE_LOAD_DECLINE;
+		}
+	}
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw G.726 (16/24/32/40kbps) data",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
diff --git a/formats/format_g729.c b/formats/format_g729.c
index 6e0632c..49e5802 100644
--- a/formats/format_g729.c
+++ b/formats/format_g729.c
@@ -138,7 +138,7 @@
 {
 	g729_f.format = ast_format_g729;
 	if (ast_format_def_register(&g729_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_gsm.c b/formats/format_gsm.c
index 777d49a..a2b6d36 100644
--- a/formats/format_gsm.c
+++ b/formats/format_gsm.c
@@ -183,7 +183,7 @@
 {
 	gsm_f.format = ast_format_gsm;
 	if (ast_format_def_register(&gsm_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_h263.c b/formats/format_h263.c
index 027f604..4cc3db5 100644
--- a/formats/format_h263.c
+++ b/formats/format_h263.c
@@ -170,7 +170,7 @@
 {
 	h263_f.format = ast_format_h263;
 	if (ast_format_def_register(&h263_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_h264.c b/formats/format_h264.c
index 38f2734..60b0902 100644
--- a/formats/format_h264.c
+++ b/formats/format_h264.c
@@ -163,7 +163,7 @@
 {
 	h264_f.format = ast_format_h264;
 	if (ast_format_def_register(&h264_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_ilbc.c b/formats/format_ilbc.c
index b556d6c..eab465d 100644
--- a/formats/format_ilbc.c
+++ b/formats/format_ilbc.c
@@ -135,7 +135,7 @@
 {
 	ilbc_f.format = ast_format_ilbc;
 	if (ast_format_def_register(&ilbc_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_jpeg.c b/formats/format_jpeg.c
index f69c547..798141d 100644
--- a/formats/format_jpeg.c
+++ b/formats/format_jpeg.c
@@ -96,7 +96,7 @@
 {
 	jpeg_format.format = ast_format_jpeg;
 	if (ast_image_register(&jpeg_format))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_ogg_vorbis.c b/formats/format_ogg_vorbis.c
index 4c42181..d4212a1 100644
--- a/formats/format_ogg_vorbis.c
+++ b/formats/format_ogg_vorbis.c
@@ -423,7 +423,7 @@
 {
 	vorbis_f.format = ast_format_slin;
 	if (ast_format_def_register(&vorbis_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 0b1706e..fedc063 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -500,6 +500,14 @@
 	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,	/* this many shorts */
 };
 
+static int unload_module(void)
+{
+	return ast_format_def_unregister(pcm_f.name)
+		|| ast_format_def_unregister(alaw_f.name)
+		|| ast_format_def_unregister(au_f.name)
+		|| ast_format_def_unregister(g722_f.name);
+}
+
 static int load_module(void)
 {
 	int i;
@@ -517,17 +525,11 @@
 	if ( ast_format_def_register(&pcm_f)
 		|| ast_format_def_register(&alaw_f)
 		|| ast_format_def_register(&au_f)
-		|| ast_format_def_register(&g722_f) )
-		return AST_MODULE_LOAD_FAILURE;
+		|| ast_format_def_register(&g722_f) ) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-	return ast_format_def_unregister(pcm_f.name)
-		|| ast_format_def_unregister(alaw_f.name)
-		|| ast_format_def_unregister(au_f.name)
-		|| ast_format_def_unregister(g722_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
diff --git a/formats/format_sln.c b/formats/format_sln.c
index 32972d0..af3f691 100644
--- a/formats/format_sln.c
+++ b/formats/format_sln.c
@@ -235,6 +235,19 @@
 	&slin192_f,
 };
 
+static int unload_module(void)
+{
+	int res = 0;
+	int i = 0;
+
+	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
+		if (ast_format_def_unregister(slin_list[i]->name)) {
+			res = -1;
+		}
+	}
+	return res;
+}
+
 static int load_module(void)
 {
 	int i;
@@ -251,24 +264,12 @@
 
 	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
 		if (ast_format_def_register(slin_list[i])) {
-			return AST_MODULE_LOAD_FAILURE;
+			unload_module();
+			return AST_MODULE_LOAD_DECLINE;
 		}
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-	int res = 0;
-	int i = 0;
-
-	for (i = 0; i < ARRAY_LEN(slin_list); i++) {
-		if (ast_format_def_unregister(slin_list[i]->name)) {
-			res |= AST_MODULE_LOAD_FAILURE;
-		}
-	}
-	return res;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN) 8khz-192khz",
diff --git a/formats/format_vox.c b/formats/format_vox.c
index eb8ab0ea..5a70c34 100644
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -137,7 +137,7 @@
 {
 	vox_f.format = ast_format_adpcm;
 	if (ast_format_def_register(&vox_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/formats/format_wav.c b/formats/format_wav.c
index a415140..049ead4 100644
--- a/formats/format_wav.c
+++ b/formats/format_wav.c
@@ -536,20 +536,22 @@
 	.desc_size = sizeof(struct wav_desc),
 };
 
+static int unload_module(void)
+{
+	return ast_format_def_unregister(wav_f.name)
+		|| ast_format_def_unregister(wav16_f.name);
+}
+
 static int load_module(void)
 {
 	wav_f.format = ast_format_slin;
 	wav16_f.format = ast_format_slin16;
 	if (ast_format_def_register(&wav_f)
-		|| ast_format_def_register(&wav16_f))
-		return AST_MODULE_LOAD_FAILURE;
+		|| ast_format_def_register(&wav16_f)) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-	return ast_format_def_unregister(wav_f.name)
-		|| ast_format_def_unregister(wav16_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV/WAV16 format (8kHz/16kHz Signed Linear)",
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index 21a8508..eef06ce 100644
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -568,7 +568,7 @@
 {
 	wav49_f.format = ast_format_gsm;
 	if (ast_format_def_register(&wav49_f))
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
diff --git a/funcs/func_cdr.c b/funcs/func_cdr.c
index 83942db..82ff488 100644
--- a/funcs/func_cdr.c
+++ b/funcs/func_cdr.c
@@ -649,7 +649,7 @@
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(cdr_read_message_type);
@@ -665,7 +665,8 @@
 	                                 cdr_read_callback, NULL);
 
 	if (res) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/funcs/func_holdintercept.c b/funcs/func_holdintercept.c
index c243546..2a1cbb8 100644
--- a/funcs/func_holdintercept.c
+++ b/funcs/func_holdintercept.c
@@ -228,7 +228,7 @@
 /*! \internal \brief Load the module */
 static int load_module(void)
 {
-	return ast_custom_function_register(&hold_intercept_function) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return ast_custom_function_register(&hold_intercept_function) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Hold interception dialplan function");
diff --git a/funcs/func_talkdetect.c b/funcs/func_talkdetect.c
index 02963f2..5c7f41a 100644
--- a/funcs/func_talkdetect.c
+++ b/funcs/func_talkdetect.c
@@ -397,7 +397,7 @@
 
 	res |= ast_custom_function_register(&talk_detect_function);
 
-	return res ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Talk detection dialplan function");
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index 9f9f671..2f629df 100644
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -500,6 +500,13 @@
  */
 void ast_verb_console_set(int verb_level);
 
+/*!
+ * \brief Test if logger is initialized
+ *
+ * \retval true if the logger is initialized
+ */
+int ast_is_logger_initialized(void);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/asterisk.c b/main/asterisk.c
index 68859ab..16313ea 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -4354,7 +4354,11 @@
 static inline void check_init(int init_result, const char *name)
 {
 	if (init_result) {
-		printf("%s initialization failed.\n%s", name, term_quit());
+		if (ast_is_logger_initialized()) {
+			ast_log(LOG_ERROR, "%s initialization failed.  ASTERISK EXITING!\n%s", name, term_quit());
+		} else {
+			fprintf(stderr, "%s initialization failed.  ASTERISK EXITING!\n%s", name, term_quit());
+		}
 		ast_run_atexits(0);
 		exit(init_result == -2 ? 2 : 1);
 	}
diff --git a/main/loader.c b/main/loader.c
index 380fe1c..d550007 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -1243,6 +1243,7 @@
 		case AST_MODULE_LOAD_DECLINE:
 			break;
 		case AST_MODULE_LOAD_FAILURE:
+			ast_log(LOG_ERROR, "*** Failed to load module %s\n", mod->resource);
 			res = -1;
 			goto done;
 		case AST_MODULE_LOAD_SKIP:
diff --git a/main/logger.c b/main/logger.c
index 146d919..8c8162d 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -1653,6 +1653,11 @@
 	}
 }
 
+int ast_is_logger_initialized(void)
+{
+	return logger_initialized;
+}
+
 /*!
  * \brief Start the ast_queue_log() logger.
  *
diff --git a/res/res_ari.c b/res/res_ari.c
index 549d783..054d3bf 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -1106,46 +1106,6 @@
 	.no_decode_uri = 1,
 };
 
-static int load_module(void)
-{
-	ast_mutex_init(&root_handler_lock);
-
-	/* root_handler may have been built during a declined load */
-	if (!root_handler) {
-		root_handler = root_handler_create();
-	}
-	if (!root_handler) {
-		return AST_MODULE_LOAD_FAILURE;
-	}
-
-	/* oom_json may have been built during a declined load */
-	if (!oom_json) {
-		oom_json = ast_json_pack(
-			"{s: s}", "error", "Allocation failed");
-	}
-	if (!oom_json) {
-		/* Ironic */
-		return AST_MODULE_LOAD_FAILURE;
-	}
-
-	if (ast_ari_config_init() != 0) {
-		return AST_MODULE_LOAD_DECLINE;
-	}
-
-	if (is_enabled()) {
-		ast_debug(3, "ARI enabled\n");
-		ast_http_uri_link(&http_uri);
-	} else {
-		ast_debug(3, "ARI disabled\n");
-	}
-
-	if (ast_ari_cli_register() != 0) {
-		return AST_MODULE_LOAD_FAILURE;
-	}
-
-	return AST_MODULE_LOAD_SUCCESS;
-}
-
 static int unload_module(void)
 {
 	ast_ari_cli_unregister();
@@ -1167,6 +1127,49 @@
 	return 0;
 }
 
+static int load_module(void)
+{
+	ast_mutex_init(&root_handler_lock);
+
+	/* root_handler may have been built during a declined load */
+	if (!root_handler) {
+		root_handler = root_handler_create();
+	}
+	if (!root_handler) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	/* oom_json may have been built during a declined load */
+	if (!oom_json) {
+		oom_json = ast_json_pack(
+			"{s: s}", "error", "Allocation failed");
+	}
+	if (!oom_json) {
+		/* Ironic */
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (ast_ari_config_init() != 0) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (is_enabled()) {
+		ast_debug(3, "ARI enabled\n");
+		ast_http_uri_link(&http_uri);
+	} else {
+		ast_debug(3, "ARI disabled\n");
+	}
+
+	if (ast_ari_cli_register() != 0) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
 static int reload_module(void)
 {
 	char was_enabled = is_enabled();
diff --git a/res/res_ari_events.c b/res/res_ari_events.c
index 8ccb887..8d8a303 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -417,6 +417,15 @@
 	.children = { &events_user, }
 };
 
+static int unload_module(void)
+{
+	ast_ari_remove_handler(&events);
+	ao2_cleanup(events.ws_server);
+	events.ws_server = NULL;
+	stasis_app_unref();
+	return 0;
+}
+
 static int load_module(void)
 {
 	int res = 0;
@@ -428,31 +437,27 @@
 
 	events.ws_server = ast_websocket_server_create();
 	if (!events.ws_server) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	protocol = ast_websocket_sub_protocol_alloc("ari");
 	if (!protocol) {
 		ao2_ref(events.ws_server, -1);
 		events.ws_server = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	protocol->session_attempted = ast_ari_events_event_websocket_ws_attempted_cb;
 	protocol->session_established = ast_ari_events_event_websocket_ws_established_cb;
 	res |= ast_websocket_server_add_protocol2(events.ws_server, protocol);
 	stasis_app_ref();
 	res |= ast_ari_add_handler(&events);
-	return res;
-}
 
-static int unload_module(void)
-{
-	ast_ari_remove_handler(&events);
-	ao2_cleanup(events.ws_server);
-	events.ws_server = NULL;
-	ast_ari_websocket_events_event_websocket_dtor();
-	stasis_app_unref();
-	return 0;
+	if (res) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - WebSocket resource",
diff --git a/res/res_ari_model.c b/res/res_ari_model.c
index dd8e1af..015b1e7 100644
--- a/res/res_ari_model.c
+++ b/res/res_ari_model.c
@@ -190,7 +190,7 @@
 		REG_EXTENDED | REG_ICASE | REG_NOSUB);
 
 	if (res != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_calendar.c b/res/res_calendar.c
index 92b73c1..666b0e1 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -1888,7 +1888,7 @@
 {
 	if (!(calendars = ao2_container_alloc(CALENDAR_BUCKETS, calendar_hash_fn, calendar_cmp_fn))) {
 		ast_log(LOG_ERROR, "Unable to allocate calendars container!\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (load_config(0)) {
@@ -1902,7 +1902,9 @@
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create sched context\n");
-		return AST_MODULE_LOAD_FAILURE;
+		ast_config_destroy(calendar_config);
+		calendar_config = NULL;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_pthread_create_background(&refresh_thread, NULL, do_refresh, NULL) < 0) {
diff --git a/res/res_chan_stats.c b/res/res_chan_stats.c
index 9a26db7..061d086 100644
--- a/res/res_chan_stats.c
+++ b/res/res_chan_stats.c
@@ -148,13 +148,22 @@
 	}
 }
 
+static int unload_module(void)
+{
+	stasis_unsubscribe_and_join(sub);
+	sub = NULL;
+	stasis_message_router_unsubscribe_and_join(router);
+	router = NULL;
+	return 0;
+}
+
 static int load_module(void)
 {
 	/* You can create a message router to route messages by type */
 	router = stasis_message_router_create(
 		ast_channel_topic_all_cached());
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	stasis_message_router_add(router, stasis_cache_update_type(),
 		updates, NULL);
@@ -163,18 +172,10 @@
 	/* Or a subscription to receive all of the messages from a topic */
 	sub = stasis_subscribe(ast_channel_topic_all(), statsmaker, NULL);
 	if (!sub) {
-		return AST_MODULE_LOAD_FAILURE;
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
-	stasis_unsubscribe_and_join(sub);
-	sub = NULL;
-	stasis_message_router_unsubscribe_and_join(router);
-	router = NULL;
-	return 0;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Example of how to use Stasis",
diff --git a/res/res_config_sqlite.c b/res/res_config_sqlite.c
index 96a10b4..0f91131 100644
--- a/res/res_config_sqlite.c
+++ b/res/res_config_sqlite.c
@@ -1680,7 +1680,7 @@
 		ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 		sqlite_freemem(errormsg);
 		unload_module();
-		return 1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	sqlite_freemem(errormsg);
@@ -1700,7 +1700,7 @@
 		if (!query) {
 			ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
 			unload_module();
-			return 1;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		ast_debug(1, "SQL query: %s\n", query);
@@ -1719,7 +1719,7 @@
 				ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 				sqlite_freemem(errormsg);
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 
 			sqlite_freemem(errormsg);
@@ -1729,7 +1729,7 @@
 			if (!query) {
 				ast_log(LOG_ERROR, "Unable to allocate SQL query\n");
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 
 			ast_debug(1, "SQL query: %s\n", query);
@@ -1744,7 +1744,7 @@
 				ast_log(LOG_ERROR, "%s\n", S_OR(errormsg, sqlite_error_string(error)));
 				sqlite_freemem(errormsg);
 				unload_module();
-				return 1;
+				return AST_MODULE_LOAD_DECLINE;
 			}
 		}
 		sqlite_freemem(errormsg);
@@ -1754,7 +1754,7 @@
 
 		if (error) {
 			unload_module();
-			return 1;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		cdr_registered = 1;
@@ -1764,12 +1764,12 @@
 
 	if (error) {
 		unload_module();
-		return 1;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	cli_status_registered = 1;
 
-	return 0;
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Realtime SQLite configuration",
diff --git a/res/res_config_sqlite3.c b/res/res_config_sqlite3.c
index 087843a..0025548 100644
--- a/res/res_config_sqlite3.c
+++ b/res/res_config_sqlite3.c
@@ -1359,18 +1359,18 @@
 	discover_sqlite3_caps();
 
 	if (!((databases = ao2_container_alloc(DB_BUCKETS, db_hash_fn, db_cmp_fn)))) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (parse_config(0)) {
 		ao2_ref(databases, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(ast_config_engine_register(&sqlite3_config_engine))) {
 		ast_log(LOG_ERROR, "The config API must have changed, this shouldn't happen.\n");
 		ao2_ref(databases, -1);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_endpoint_stats.c b/res/res_endpoint_stats.c
index 249cbea..1e3f104 100644
--- a/res/res_endpoint_stats.c
+++ b/res/res_endpoint_stats.c
@@ -118,7 +118,7 @@
 
 	router = stasis_message_router_create(ast_endpoint_topic_all_cached());
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	stasis_message_router_add(router, stasis_cache_update_type(), cache_update_cb, NULL);
 
diff --git a/res/res_hep_rtcp.c b/res/res_hep_rtcp.c
index 25b90c7..7191f46 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -155,7 +155,7 @@
 	stasis_rtp_subscription = stasis_subscribe(ast_rtp_topic(),
 		rtp_topic_handler, NULL);
 	if (!stasis_rtp_subscription) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 799eb84..60332f5 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -1441,7 +1441,7 @@
 {
 	websocketuri.data = websocket_server_internal_create();
 	if (!websocketuri.data) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_http_uri_link(&websocketuri);
 	websocket_add_protocol_internal("echo", websocket_echo_callback);
diff --git a/res/res_limit.c b/res/res_limit.c
index bff777d..a308c41 100644
--- a/res/res_limit.c
+++ b/res/res_limit.c
@@ -209,7 +209,7 @@
 
 static int load_module(void)
 {
-	return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits");
diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c
index d180296..62bc9d6 100644
--- a/res/res_pjsip/config_transport.c
+++ b/res/res_pjsip/config_transport.c
@@ -1348,7 +1348,7 @@
 	transport_states = ao2_container_alloc(DEFAULT_STATE_BUCKETS, internal_state_hash, internal_state_cmp);
 	if (!transport_states) {
 		ast_log(LOG_ERROR, "Unable to allocate transport states container\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return -1;
 	}
 
 	ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport");
diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index a26180b..9205622 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -361,13 +361,13 @@
 
 	if (ast_sip_register_service(&nat_module)) {
 		ast_log(LOG_ERROR, "Could not register NAT module for incoming and outgoing requests\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sip_session_register_supplement(&nat_supplement)) {
 		ast_log(LOG_ERROR, "Could not register NAT session supplement for incoming and outgoing INVITE requests\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_one_touch_record_info.c b/res/res_pjsip_one_touch_record_info.c
index 2d53fd4..ec5f9be 100644
--- a/res/res_pjsip_one_touch_record_info.c
+++ b/res/res_pjsip_one_touch_record_info.c
@@ -112,7 +112,7 @@
 
 	if (ast_sip_session_register_supplement(&info_supplement)) {
 		ast_log(LOG_ERROR, "Unable to register One Touch Recording supplement\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_outbound_publish.c b/res/res_pjsip_outbound_publish.c
index a19a9bb..c413cb0 100644
--- a/res/res_pjsip_outbound_publish.c
+++ b/res/res_pjsip_outbound_publish.c
@@ -1631,7 +1631,7 @@
 
 	shutdown_group = ast_serializer_shutdown_group_alloc();
 	if (!shutdown_group) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_outbound_publish");
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index 704239b..8a840ff 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -2082,7 +2082,7 @@
 
 	shutdown_group = ast_serializer_shutdown_group_alloc();
 	if (!shutdown_group) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Create outbound registration states container. */
@@ -2091,7 +2091,7 @@
 	if (!new_states) {
 		ast_log(LOG_ERROR, "Unable to allocate registration states container\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ao2_global_obj_replace_unref(current_states, new_states);
 	ao2_ref(new_states, -1);
@@ -2135,7 +2135,7 @@
 			&registration_observer)) {
 		ast_log(LOG_ERROR, "Unable to register observers.\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	/* Register how this module identifies endpoints. */
@@ -2146,7 +2146,7 @@
 	if (!cli_formatter) {
 		ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	cli_formatter->name = "registration";
 	cli_formatter->print_header = cli_print_header;
diff --git a/res/res_pjsip_pubsub.c b/res/res_pjsip_pubsub.c
index f046762..a1f3f24 100644
--- a/res/res_pjsip_pubsub.c
+++ b/res/res_pjsip_pubsub.c
@@ -5225,13 +5225,13 @@
 
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_ERROR, "Could not create scheduler for publication expiration\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (ast_sched_start_thread(sched)) {
 		ast_log(LOG_ERROR, "Could not start scheduler thread for publication expiration\n");
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &str_PUBLISH);
@@ -5239,7 +5239,7 @@
 	if (ast_sip_register_service(&pubsub_module)) {
 		ast_log(LOG_ERROR, "Could not register pubsub service\n");
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_config(sorcery, "res_pjsip_pubsub");
@@ -5249,7 +5249,7 @@
 		ast_log(LOG_ERROR, "Could not register subscription persistence object support\n");
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_sorcery_object_field_register(sorcery, "subscription_persistence", "packet", "", OPT_CHAR_ARRAY_T, 0,
 		CHARFLDSET(struct subscription_persistence, packet));
@@ -5277,7 +5277,7 @@
 	if (apply_list_configuration(sorcery)) {
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	ast_sorcery_apply_default(sorcery, "inbound-publication", "config", "pjsip.conf,criteria=type=inbound-publication");
@@ -5286,7 +5286,7 @@
 		ast_log(LOG_ERROR, "Could not register subscription persistence object support\n");
 		ast_sip_unregister_service(&pubsub_module);
 		ast_sched_context_destroy(sched);
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_sorcery_object_field_register(sorcery, "inbound-publication", "type", "", OPT_NOOP_T, 0, 0);
 	ast_sorcery_object_field_register_custom(sorcery, "inbound-publication", "endpoint", "",
diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c
index 7c861da..dfa6957 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1650,7 +1650,7 @@
 end:
 	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP SDP RTP/AVP stream handler",
diff --git a/res/res_pjsip_send_to_voicemail.c b/res/res_pjsip_send_to_voicemail.c
index bd70bcf..1cd28ce 100644
--- a/res/res_pjsip_send_to_voicemail.c
+++ b/res/res_pjsip_send_to_voicemail.c
@@ -219,7 +219,7 @@
 
 	if (ast_sip_session_register_supplement(&refer_supplement)) {
 		ast_log(LOG_ERROR, "Unable to register Send to Voicemail supplement\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c
index bae4ff1..4f082d7 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -938,7 +938,7 @@
 end:
 	unload_module();
 
-	return AST_MODULE_LOAD_FAILURE;
+	return AST_MODULE_LOAD_DECLINE;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP T.38 UDPTL Support",
diff --git a/res/res_smdi.c b/res/res_smdi.c
index 4c7a451..e2e5b17 100644
--- a/res/res_smdi.c
+++ b/res/res_smdi.c
@@ -1126,7 +1126,7 @@
 	if (!AST_LIST_EMPTY(&mwi_monitor.mailbox_mappings) && mwi_monitor.thread == AST_PTHREADT_NULL
 		&& ast_pthread_create_background(&mwi_monitor.thread, NULL, mwi_monitor_handler, NULL)) {
 		ast_log(LOG_ERROR, "Failed to start MWI monitoring thread.  This module will not operate.\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return -1;
 	}
 
 	if (ao2_container_count(new_ifaces)) {
@@ -1369,7 +1369,7 @@
 	res = smdi_load(0);
 	if (res < 0) {
 		_unload_module(1);
-		return res;
+		return AST_MODULE_LOAD_DECLINE;
 	} else if (res == 1) {
 		_unload_module(1);
 		ast_log(LOG_NOTICE, "No SMDI interfaces are available to listen on, not starting SMDI listener.\n");
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 1967209..9ea0d63 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -2111,12 +2111,12 @@
 		37, bridges_channel_hash_fn, bridges_channel_sort_fn, NULL);
 	if (!apps_registry || !app_controls || !app_bridges || !app_bridges_moh || !app_bridges_playback) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (messaging_init()) {
 		unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	bridge_stasis_init();
diff --git a/res/res_stasis_device_state.c b/res/res_stasis_device_state.c
index e16bd8e..344cb40 100644
--- a/res/res_stasis_device_state.c
+++ b/res/res_stasis_device_state.c
@@ -453,13 +453,14 @@
 	populate_cache();
 	if (ast_devstate_prov_add(DEVICE_STATE_PROVIDER_STASIS,
 				  stasis_device_state_cb)) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	if (!(device_state_subscriptions = ao2_container_alloc(
 		      DEVICE_STATE_BUCKETS, device_state_subscriptions_hash,
 		      device_state_subscriptions_cmp))) {
-		return AST_MODULE_LOAD_FAILURE;
+		ast_devstate_prov_del(DEVICE_STATE_PROVIDER_STASIS);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	stasis_app_register_event_source(&device_state_event_source);
diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c
index 4370f17..c6f2136 100644
--- a/res/res_stasis_playback.c
+++ b/res/res_stasis_playback.c
@@ -731,13 +731,14 @@
 
 	r = STASIS_MESSAGE_TYPE_INIT(stasis_app_playback_snapshot_type);
 	if (r != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	playbacks = ao2_container_alloc(PLAYBACK_BUCKETS, playback_hash,
 		playback_cmp);
 	if (!playbacks) {
-		return AST_MODULE_LOAD_FAILURE;
+		STASIS_MESSAGE_TYPE_CLEANUP(stasis_app_playback_snapshot_type);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_stasis_recording.c b/res/res_stasis_recording.c
index 630205c..56984cb 100644
--- a/res/res_stasis_recording.c
+++ b/res/res_stasis_recording.c
@@ -631,13 +631,14 @@
 
 	r = STASIS_MESSAGE_TYPE_INIT(stasis_app_recording_snapshot_type);
 	if (r != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	recordings = ao2_container_alloc(RECORDING_BUCKETS, recording_hash,
 		recording_cmp);
 	if (!recordings) {
-		return AST_MODULE_LOAD_FAILURE;
+		STASIS_MESSAGE_TYPE_CLEANUP(stasis_app_recording_snapshot_type);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	return AST_MODULE_LOAD_SUCCESS;
 }
diff --git a/res/res_stasis_test.c b/res/res_stasis_test.c
index 8b5bad7..19d2a42 100644
--- a/res/res_stasis_test.c
+++ b/res/res_stasis_test.c
@@ -272,7 +272,7 @@
 static int load_module(void)
 {
 	if (STASIS_MESSAGE_TYPE_INIT(stasis_test_message_type) != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/res/res_statsd.c b/res/res_statsd.c
index 22c4ba2..3d7dd16 100644
--- a/res/res_statsd.c
+++ b/res/res_statsd.c
@@ -349,7 +349,8 @@
 	}
 
 	if (statsd_init() != 0) {
-		return AST_MODULE_LOAD_FAILURE;
+		aco_info_destroy(&cfg_info);
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/rest-api-templates/res_ari_resource.c.mustache b/rest-api-templates/res_ari_resource.c.mustache
index c28a62c..ca4e2f1 100644
--- a/rest-api-templates/res_ari_resource.c.mustache
+++ b/rest-api-templates/res_ari_resource.c.mustache
@@ -256,6 +256,19 @@
 {{> rest_handler}}
 {{/root_path}}
 
+static int unload_module(void)
+{
+	ast_ari_remove_handler(&{{root_full_name}});
+{{#apis}}
+{{#has_websocket}}
+	ao2_cleanup({{full_name}}.ws_server);
+	{{full_name}}.ws_server = NULL;
+{{/has_websocket}}
+{{/apis}}
+	stasis_app_unref();
+	return 0;
+}
+
 static int load_module(void)
 {
 	int res = 0;
@@ -270,14 +283,14 @@
 
 	{{full_name}}.ws_server = ast_websocket_server_create();
 	if (!{{full_name}}.ws_server) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	protocol = ast_websocket_sub_protocol_alloc("{{websocket_protocol}}");
 	if (!protocol) {
 		ao2_ref({{full_name}}.ws_server, -1);
 		{{full_name}}.ws_server = NULL;
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	protocol->session_attempted = ast_ari_{{c_name}}_{{c_nickname}}_ws_attempted_cb;
 	protocol->session_established = ast_ari_{{c_name}}_{{c_nickname}}_ws_established_cb;
@@ -289,21 +302,12 @@
 {{/apis}}
 	stasis_app_ref();
 	res |= ast_ari_add_handler(&{{root_full_name}});
-	return res;
-}
+	if (res) {
+		unload_module();
+		return AST_MODULE_LOAD_DECLINE;
+	}
 
-static int unload_module(void)
-{
-	ast_ari_remove_handler(&{{root_full_name}});
-{{#apis}}
-{{#has_websocket}}
-	ao2_cleanup({{full_name}}.ws_server);
-	{{full_name}}.ws_server = NULL;
-	ast_ari_websocket_events_event_websocket_dtor();
-{{/has_websocket}}
-{{/apis}}
-	stasis_app_unref();
-	return 0;
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - {{{description}}}",
diff --git a/tests/test_bucket.c b/tests/test_bucket.c
index 2b6e059..2cf5267 100644
--- a/tests/test_bucket.c
+++ b/tests/test_bucket.c
@@ -1012,7 +1012,7 @@
 	if (ast_bucket_scheme_register("test", &bucket_test_wizard, &bucket_file_test_wizard,
 		ast_bucket_file_temporary_create, ast_bucket_file_temporary_destroy)) {
 		ast_log(LOG_ERROR, "Failed to register Bucket test wizard scheme implementation\n");
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	AST_TEST_REGISTER(bucket_scheme_register);
diff --git a/tests/test_channel_feature_hooks.c b/tests/test_channel_feature_hooks.c
index c9fdf09..a325484 100644
--- a/tests/test_channel_feature_hooks.c
+++ b/tests/test_channel_feature_hooks.c
@@ -345,7 +345,7 @@
 {
 	test_features_chan_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
 	if (!test_features_chan_tech.capabilities) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 	ast_format_cap_append(test_features_chan_tech.capabilities, TEST_CHANNEL_FORMAT, 0);
 	ast_channel_register(&test_features_chan_tech);

-- 
To view, visit https://gerrit.asterisk.org/5452
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5f4b50623d9b5a6cb7c5624a8c5c1274c13b2b25
Gerrit-PatchSet: 8
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-code-review mailing list