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

Anonymous Coward asteriskteam at digium.com
Thu Apr 13 07:02:33 CDT 2017


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

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 896bad6..26e8389 100644
--- a/addons/cdr_mysql.c
+++ b/addons/cdr_mysql.c
@@ -353,9 +353,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));
@@ -366,12 +377,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);
@@ -507,13 +513,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 */
@@ -584,7 +593,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))) {
@@ -593,7 +604,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))) {
@@ -659,7 +672,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) {
@@ -673,7 +687,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 8d13c96..ada7e27 100644
--- a/addons/chan_mobile.c
+++ b/addons/chan_mobile.c
@@ -4706,9 +4706,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;
 	}
 
@@ -4716,6 +4720,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;
 	}
 
@@ -4740,10 +4746,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 3f3d11c..1c9f37b 100644
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -1607,7 +1607,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 68bcfde..0ad24c6 100644
--- a/apps/app_agent_pool.c
+++ b/apps/app_agent_pool.c
@@ -2655,7 +2655,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. */
@@ -2679,8 +2679,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 ace4df1..5b7a90c 100644
--- a/apps/app_alarmreceiver.c
+++ b/apps/app_alarmreceiver.c
@@ -977,7 +977,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 f47db45..30023fc 100644
--- a/apps/app_authenticate.c
+++ b/apps/app_authenticate.c
@@ -272,7 +272,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 7862179..196179a 100644
--- a/apps/app_cdr.c
+++ b/apps/app_cdr.c
@@ -251,7 +251,7 @@
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(appcdr_message_type);
@@ -261,7 +261,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 a7fd92a..6986fbe 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -3935,7 +3935,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 */
@@ -3943,7 +3943,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 */
@@ -3968,7 +3968,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 51921a9..9e7ddff 100644
--- a/apps/app_dahdiras.c
+++ b/apps/app_dahdiras.c
@@ -225,7 +225,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 4ff5cd6..2fd77c6 100644
--- a/apps/app_forkcdr.c
+++ b/apps/app_forkcdr.c
@@ -201,7 +201,7 @@
 	int res = 0;
 
 	if (!router) {
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 
 	res |= STASIS_MESSAGE_TYPE_INIT(forkcdr_message_type);
@@ -210,7 +210,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 f5cec1e..1fa094e 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -8876,7 +8876,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 34c4822..b0185c1 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -14976,7 +14976,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 27bcf63..d44a2de 100644
--- a/apps/app_zapateller.c
+++ b/apps/app_zapateller.c
@@ -134,7 +134,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 bb63ea0..9d4abbc 100644
--- a/cdr/cdr_custom.c
+++ b/cdr/cdr_custom.c
@@ -205,7 +205,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();
@@ -218,7 +218,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 f75efdd..09aef4e 100644
--- a/cel/cel_custom.c
+++ b/cel/cel_custom.c
@@ -193,14 +193,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;
 }
@@ -209,7 +210,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 a10aada..1ea6ea9 100644
--- a/cel/cel_odbc.c
+++ b/cel/cel_odbc.c
@@ -803,13 +803,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;
 }
@@ -818,7 +819,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 5c028c3..7a6f841 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -926,6 +926,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
  *
@@ -996,37 +1016,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 71dbd35..55a9dba 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -19606,11 +19606,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);
@@ -19618,7 +19618,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
@@ -19636,7 +19636,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(
@@ -19647,7 +19647,7 @@
 #endif	/* defined(HAVE_PRI_CCSS) */
 		)) {
 		__unload_module();
-		return AST_MODULE_LOAD_FAILURE;
+		return AST_MODULE_LOAD_DECLINE;
 	}
 #endif
 #if defined(HAVE_SS7)
@@ -19670,7 +19670,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 469a172..8941634 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -14878,7 +14878,7 @@
 	if (calltoken_ignores) {
 		ao2_ref(calltoken_ignores, -1);
 	}
-	return AST_MODULE_LOAD_FAILURE;
+	return -1;
 }
 
 
@@ -15083,12 +15083,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));
@@ -15099,28 +15101,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);
 
@@ -15129,8 +15139,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);
 
@@ -15149,6 +15161,7 @@
 			ast_timer_close(timer);
 			timer = NULL;
 		}
+		__unload_module();
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -15174,7 +15187,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)) {
@@ -15184,7 +15197,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 6df5d3f..33f4f46 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -4862,11 +4862,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);
@@ -4875,7 +4875,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())) {
@@ -4883,7 +4883,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)) {
@@ -4899,7 +4899,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 0c71092..1f44914 100644
--- a/channels/chan_motif.c
+++ b/channels/chan_motif.c
@@ -2790,7 +2790,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 d50defe..b4a0532 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -259,12 +259,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 84a1391..8771107 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -1437,6 +1437,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
  *
@@ -1474,12 +1499,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);
 
@@ -1494,32 +1519,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 b7f694f..94116e7 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1418,7 +1418,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) {
@@ -1434,7 +1434,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);
@@ -1510,7 +1510,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 e518523..e8e3666 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2751,7 +2751,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 052fa9e..a646e73 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -35305,17 +35305,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! */
@@ -35330,12 +35330,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);
 
@@ -35346,13 +35346,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;
@@ -35367,7 +35367,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);
@@ -35384,14 +35384,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 96a206c..a654d0f 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -8700,7 +8700,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 */
@@ -8708,7 +8708,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);
@@ -8725,7 +8725,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 af0f2c6..84a6383 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -7128,7 +7128,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 a831abf..ef41a0a 100644
--- a/codecs/codec_a_mu.c
+++ b/codecs/codec_a_mu.c
@@ -143,7 +143,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 fa5d876..7c9c2c9 100644
--- a/codecs/codec_adpcm.c
+++ b/codecs/codec_adpcm.c
@@ -348,7 +348,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 515835d..a4cb80e 100644
--- a/codecs/codec_alaw.c
+++ b/codecs/codec_alaw.c
@@ -132,7 +132,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 d368c38..e5d9f51 100644
--- a/codecs/codec_g722.c
+++ b/codecs/codec_g722.c
@@ -243,7 +243,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 8b44cbb..e60aeb9 100644
--- a/codecs/codec_g726.c
+++ b/codecs/codec_g726.c
@@ -892,7 +892,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 f80c955..fc360d0 100644
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.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_ilbc.c b/codecs/codec_ilbc.c
index fc713be..bf6a092 100644
--- a/codecs/codec_ilbc.c
+++ b/codecs/codec_ilbc.c
@@ -269,7 +269,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 e6dcf8c..d632c12 100644
--- a/codecs/codec_lpc10.c
+++ b/codecs/codec_lpc10.c
@@ -274,7 +274,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 1c73bf3..b9269d1 100644
--- a/codecs/codec_resample.c
+++ b/codecs/codec_resample.c
@@ -155,7 +155,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++) {
@@ -182,7 +182,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 ca2f411..3075d0c 100644
--- a/codecs/codec_ulaw.c
+++ b/codecs/codec_ulaw.c
@@ -183,7 +183,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 777cd74..9a40081 100644
--- a/formats/format_g723.c
+++ b/formats/format_g723.c
@@ -144,7 +144,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 684275c..22ed41d 100644
--- a/formats/format_g726.c
+++ b/formats/format_g726.c
@@ -223,20 +223,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;
@@ -248,6 +234,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 69e6a25..f9de0ec 100644
--- a/formats/format_g729.c
+++ b/formats/format_g729.c
@@ -140,7 +140,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 bf82dd5..c824748 100644
--- a/formats/format_gsm.c
+++ b/formats/format_gsm.c
@@ -185,7 +185,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 f02d030..86abed5 100644
--- a/formats/format_h263.c
+++ b/formats/format_h263.c
@@ -172,7 +172,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 6333091..3e82830 100644
--- a/formats/format_h264.c
+++ b/formats/format_h264.c
@@ -165,7 +165,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 e07eedb..3cfa8e6 100644
--- a/formats/format_ilbc.c
+++ b/formats/format_ilbc.c
@@ -137,7 +137,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 ed21f88..fda1576 100644
--- a/formats/format_jpeg.c
+++ b/formats/format_jpeg.c
@@ -98,7 +98,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 0daf64c..7414ea7 100644
--- a/formats/format_ogg_vorbis.c
+++ b/formats/format_ogg_vorbis.c
@@ -425,7 +425,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 6361cd0..a493f51 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -502,6 +502,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;
@@ -519,17 +527,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 68aa74d..99f70fc 100644
--- a/formats/format_sln.c
+++ b/formats/format_sln.c
@@ -237,6 +237,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;
@@ -253,24 +266,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 5107ab9..582b94f 100644
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -139,7 +139,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 688c3e7..06ed941 100644
--- a/formats/format_wav.c
+++ b/formats/format_wav.c
@@ -538,20 +538,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 d5661fb..240ba3b 100644
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -570,7 +570,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 8dcb2bd..785ac82 100644
--- a/funcs/func_cdr.c
+++ b/funcs/func_cdr.c
@@ -651,7 +651,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);
@@ -667,7 +667,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 3e348c1..6d580c2 100644
--- a/funcs/func_holdintercept.c
+++ b/funcs/func_holdintercept.c
@@ -230,7 +230,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 b8dd2d4..6fcc3fc 100644
--- a/funcs/func_talkdetect.c
+++ b/funcs/func_talkdetect.c
@@ -399,7 +399,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 5c10525..49db383 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -4400,7 +4400,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 9beaf4d..327bb52 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -1245,6 +1245,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 7d0d2de..75b6ea2 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -1655,6 +1655,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 56b0a44..c6fbc6c 100644
--- a/res/res_ari.c
+++ b/res/res_ari.c
@@ -1108,46 +1108,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();
@@ -1169,6 +1129,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 19b6fad..f6817b1 100644
--- a/res/res_ari_events.c
+++ b/res/res_ari_events.c
@@ -419,6 +419,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;
@@ -430,31 +439,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 14265cd..59a205b 100644
--- a/res/res_ari_model.c
+++ b/res/res_ari_model.c
@@ -192,7 +192,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 6f6f711..d0f48fb 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -1882,7 +1882,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)) {
@@ -1896,7 +1896,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 dfca39a..2db4bd5 100644
--- a/res/res_chan_stats.c
+++ b/res/res_chan_stats.c
@@ -150,13 +150,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);
@@ -165,18 +174,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 d116947..2d3c98b 100644
--- a/res/res_config_sqlite.c
+++ b/res/res_config_sqlite.c
@@ -1681,7 +1681,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);
@@ -1701,7 +1701,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);
@@ -1720,7 +1720,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);
@@ -1730,7 +1730,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);
@@ -1745,7 +1745,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);
@@ -1755,7 +1755,7 @@
 
 		if (error) {
 			unload_module();
-			return 1;
+			return AST_MODULE_LOAD_DECLINE;
 		}
 
 		cdr_registered = 1;
@@ -1765,12 +1765,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 0d553b8..11acf64 100644
--- a/res/res_config_sqlite3.c
+++ b/res/res_config_sqlite3.c
@@ -1361,18 +1361,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 28e47d0..2e7742f 100644
--- a/res/res_endpoint_stats.c
+++ b/res/res_endpoint_stats.c
@@ -120,7 +120,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 03db181..fb80184 100644
--- a/res/res_hep_rtcp.c
+++ b/res/res_hep_rtcp.c
@@ -157,7 +157,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 8476e26..9f5d931 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -1451,7 +1451,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 d844efe..6973d7f 100644
--- a/res/res_limit.c
+++ b/res/res_limit.c
@@ -211,7 +211,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 ddcdb8a..6f94b0f 100644
--- a/res/res_pjsip_sdp_rtp.c
+++ b/res/res_pjsip_sdp_rtp.c
@@ -1646,7 +1646,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 1206e5a..346f824 100644
--- a/res/res_pjsip_t38.c
+++ b/res/res_pjsip_t38.c
@@ -940,7 +940,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 770ac62..225a491 100644
--- a/res/res_smdi.c
+++ b/res/res_smdi.c
@@ -1128,7 +1128,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)) {
@@ -1371,7 +1371,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 72a85e3..c68aa8a 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -2113,12 +2113,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 f695ed5..8356283 100644
--- a/res/res_stasis_device_state.c
+++ b/res/res_stasis_device_state.c
@@ -455,13 +455,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 cfddb3a..f909a69 100644
--- a/res/res_stasis_playback.c
+++ b/res/res_stasis_playback.c
@@ -733,13 +733,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 af5c41e..62d1c53 100644
--- a/res/res_stasis_recording.c
+++ b/res/res_stasis_recording.c
@@ -633,13 +633,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 efdbc4b..1b75218 100644
--- a/res/res_stasis_test.c
+++ b/res/res_stasis_test.c
@@ -274,7 +274,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 f3a64e0..8f56cf8 100644
--- a/res/res_statsd.c
+++ b/res/res_statsd.c
@@ -351,7 +351,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 6e96b58..f58adcd 100644
--- a/rest-api-templates/res_ari_resource.c.mustache
+++ b/rest-api-templates/res_ari_resource.c.mustache
@@ -258,6 +258,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;
@@ -272,14 +285,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;
@@ -291,21 +304,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 eb8fc90..94edc91 100644
--- a/tests/test_bucket.c
+++ b/tests/test_bucket.c
@@ -1014,7 +1014,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 94037e2..5ff72c1 100644
--- a/tests/test_channel_feature_hooks.c
+++ b/tests/test_channel_feature_hooks.c
@@ -347,7 +347,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/5451
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5f4b50623d9b5a6cb7c5624a8c5c1274c13b2b25
Gerrit-PatchSet: 6
Gerrit-Project: asterisk
Gerrit-Branch: 14
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