[Asterisk-code-review] RFC: Add support for disabled modules. (asterisk[master])
Corey Farrell
asteriskteam at digium.com
Tue Oct 2 13:43:43 CDT 2018
Corey Farrell has uploaded this change for review. ( https://gerrit.asterisk.org/10377
Change subject: RFC: Add support for disabled modules.
......................................................................
RFC: Add support for disabled modules.
Change-Id: Ic44810ca6ce3deca30bceeb4eaa306d94f6b90e8
---
M include/asterisk/module.h
M main/loader.c
M res/res_statsd.c
3 files changed, 121 insertions(+), 18 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/77/10377/1
diff --git a/include/asterisk/module.h b/include/asterisk/module.h
index 08b4c43..4c3c68a 100644
--- a/include/asterisk/module.h
+++ b/include/asterisk/module.h
@@ -66,11 +66,49 @@
};
enum ast_module_load_result {
- AST_MODULE_LOAD_SUCCESS = 0, /*!< Module loaded and configured */
- AST_MODULE_LOAD_DECLINE = 1, /*!< Module is not configured */
- AST_MODULE_LOAD_SKIP = 2, /*!< Module was skipped for some reason (For loader.c use only. Should never be returned by modules)*/
- AST_MODULE_LOAD_PRIORITY = 3, /*!< Module is not loaded yet, but is added to priority list */
- AST_MODULE_LOAD_FAILURE = -1, /*!< Module could not be loaded properly */
+ /*! Module is loaded and configured. */
+ AST_MODULE_LOAD_SUCCESS = 0,
+ /*!
+ * \brief Module has failed to load, may be in an inconsistent state.
+ *
+ * This value is used when a module fails to start but does not risk
+ * system-wide stability. Declined modules will prevent other any
+ * dependent module from starting.
+ */
+ AST_MODULE_LOAD_DECLINE = 1,
+ /*! \internal
+ * \brief Module was skipped for some reason.
+ *
+ * \note For loader.c use only. Should never be returned by modules.
+ */
+ AST_MODULE_LOAD_SKIP = 2,
+ /*! \internal
+ * \brief Module is not loaded yet, but is added to priority list.
+ *
+ * \note For loader.c use only. Should never be returned by modules.
+ */
+ AST_MODULE_LOAD_PRIORITY = 3,
+ /*!
+ * \brief Module load is successful but disabled.
+ *
+ * Returning this value has the same effect as calling
+ * ast_module_set_disabled(1) then returning AST_MODULE_LOAD_SUCCESS.
+ * It is important that a module not unload if returning LOAD_DISABLED.
+ * load_module will not be called again. It is expected that a disabled
+ * module can be enabled by modifying and reload the module's configuration.
+ *
+ * See \ref ast_module_set_disabled
+ */
+ AST_MODULE_LOAD_DISABLED = 4,
+ /*!
+ * \brief Module could not be loaded properly.
+ *
+ * This return should only be returned by modules for unrecoverable
+ * failures that cause the whole system to become unstable. In almost
+ * all cases \ref AST_MODULE_LOAD_DECLINE or \ref AST_MODULE_LOAD_DISABLED
+ * should be used instead.
+ */
+ AST_MODULE_LOAD_FAILURE = -1,
};
/*!
@@ -136,6 +174,25 @@
int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode);
/*!
+ * \brief Flag a module as disabled.
+ * \param mod Module to flag
+ * \param disabled Zero to clear the flag, non-zero to set.
+ *
+ * \retval 0 Module was not previously disabled
+ * \retval 1 Module was previously disabled
+ */
+int ast_module_set_disabled(struct ast_module *mod, int disabled);
+
+/*!
+ * \brief Retrieve the status of a module.
+ *
+ * \param mod Module to check.
+ *
+ * \returns A string representing the current status of \a mod.
+ */
+const char *ast_module_status(const struct ast_module *mod);
+
+/*!
* \brief Reload asterisk modules.
* \param name the name of the module to reload
*
diff --git a/main/loader.c b/main/loader.c
index eb345b5..8291a7c 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -177,6 +177,8 @@
unsigned int running:1;
/*! The module has declined to start. */
unsigned int declined:1;
+ /*! This module is disabled. */
+ unsigned int disabled:1;
/*! This module is being held open until it's time to shutdown. */
unsigned int keepuntilshutdown:1;
/*! The module is built-in. */
@@ -1048,8 +1050,9 @@
}
}
- if (!error)
- mod->flags.running = mod->flags.declined = 0;
+ if (!error) {
+ mod->flags.running = mod->flags.declined = mod->flags.disabled = 0;
+ }
AST_DLLIST_UNLOCK(&module_list);
@@ -1326,6 +1329,27 @@
publish_load_message_type("Reload", S_OR(name, "All"), res_buffer);
}
+int ast_module_set_disabled(struct ast_module *mod, int disabled)
+{
+ int oldValue;
+
+ /* Ensure all non-zero is always 1 for matching against previous value. */
+ disabled = disabled ? 1 : 0;
+
+ ast_mutex_lock(&reloadlock);
+ oldValue = mod->flags.disabled;
+ mod->flags.disabled = disabled;
+ ast_mutex_unlock(&reloadlock);
+
+ if (disabled != oldValue) {
+ ast_log(LOG_NOTICE, "%s %s.\n",
+ ast_module_name(mod),
+ disabled ? "disabled" : "enabled");
+ }
+
+ return oldValue;
+}
+
enum ast_module_reload_result ast_module_reload(const char *name)
{
struct ast_module *cur;
@@ -1473,9 +1497,17 @@
if (!ast_fully_booted) {
ast_verb(1, "Loading %s.\n", mod->resource);
}
+
+ /* This should normally be a NOOP unless a previous attempted
+ * load set disabled but then returned AST_MODULE_LOAD_DECLINE. */
+ ast_module_set_disabled(mod, 0);
res = mod->info->load();
switch (res) {
+ case AST_MODULE_LOAD_DISABLED:
+ ast_module_set_disabled(mod, 1);
+ res = AST_MODULE_LOAD_SUCCESS;
+ /* fall-through */
case AST_MODULE_LOAD_SUCCESS:
if (!ast_fully_booted) {
ast_verb(2, "%s => (%s)\n", mod->resource, term_color(tmp, mod->info->description, COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
@@ -1782,11 +1814,12 @@
lres = load_resource(order->resource, !lasttry, &module_priorities, order->required, order->preload);
ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);
switch (lres) {
+ case AST_MODULE_LOAD_DISABLED:
case AST_MODULE_LOAD_SUCCESS:
case AST_MODULE_LOAD_SKIP:
- /* We're supplying module_priorities so SUCCESS isn't possible but we
- * still have to test for it. SKIP is only used when we try to start a
- * module that is missing dependencies. */
+ /* We're supplying module_priorities so SUCCESS and DISABLED aren't
+ * possible but we still have to test for them. SKIP is only used
+ * when we try to start a module that is missing dependencies. */
break;
case AST_MODULE_LOAD_DECLINE:
break;
@@ -2073,6 +2106,19 @@
return 0;
}
+const char *ast_module_status(const struct ast_module *mod)
+{
+ if (mod->flags.running) {
+ return mod->flags.disabled ? "Disabled" : "Running";
+ }
+
+ if (mod->flags.declined) {
+ return "Run Declined";
+ }
+
+ return "Not Running";
+}
+
int ast_update_module_list(int (*modentry)(const char *module, const char *description,
int usecnt, const char *status, const char *like,
enum ast_module_support_level support_level),
@@ -2090,7 +2136,7 @@
struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
- cur->flags.running ? "Running" : "Not Running", like, cur->info->support_level);
+ ast_module_status(cur), like, cur->info->support_level);
}
}
@@ -2118,7 +2164,7 @@
struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
total_mod_loaded += modentry(cur->resource, cur->info->description, cur->usecount,
- cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data);
+ ast_module_status(cur), like, cur->info->support_level, data);
}
}
@@ -2147,7 +2193,7 @@
struct ast_module *cur = AST_VECTOR_GET(&alpha_module_list, idx);
conditions_met += modentry(cur->resource, cur->info->description, cur->usecount,
- cur->flags.running? "Running" : "Not Running", like, cur->info->support_level, data,
+ ast_module_status(cur), like, cur->info->support_level, data,
condition);
}
}
diff --git a/res/res_statsd.c b/res/res_statsd.c
index 3e08152..c83a278 100644
--- a/res/res_statsd.c
+++ b/res/res_statsd.c
@@ -271,7 +271,7 @@
CONFIG_INFO_STANDARD(cfg_info, confs, conf_alloc,
.files = ACO_FILES(&conf_file));
-/*! \brief Helper function to check if module is enabled. */
+/*! \brief Helper function to check if module should be enabled. */
static char is_enabled(void)
{
RAII_VAR(struct conf *, cfg, ao2_global_obj_ref(confs), ao2_cleanup);
@@ -303,6 +303,7 @@
ast_debug(3, " statsd server = %s.\n", server);
ast_debug(3, " add newline = %s\n", AST_YESNO(cfg->global->add_newline));
ast_debug(3, " prefix = %s\n", cfg->global->prefix);
+ ast_module_set_disabled(AST_MODULE_SELF, 0);
return 0;
}
@@ -314,6 +315,7 @@
close(socket_fd);
socket_fd = -1;
}
+ ast_module_set_disabled(AST_MODULE_SELF, 1);
}
static int load_module(void)
@@ -340,8 +342,7 @@
CHARFLDSET(struct conf_global_options, prefix));
if (aco_process_config(&cfg_info, 0)) {
- aco_info_destroy(&cfg_info);
- return AST_MODULE_LOAD_DECLINE;
+ return AST_MODULE_LOAD_DISABLED;
}
if (!is_enabled()) {
@@ -349,8 +350,7 @@
}
if (statsd_init() != 0) {
- aco_info_destroy(&cfg_info);
- return AST_MODULE_LOAD_DECLINE;
+ return AST_MODULE_LOAD_DISABLED;
}
return AST_MODULE_LOAD_SUCCESS;
--
To view, visit https://gerrit.asterisk.org/10377
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic44810ca6ce3deca30bceeb4eaa306d94f6b90e8
Gerrit-Change-Number: 10377
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20181002/e1a93e75/attachment-0001.html>
More information about the asterisk-code-review
mailing list