mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
loader.c: Allow dependent modules to be unloaded recursively.
Because of the (often recursive) nature of module dependencies in Asterisk, hot swapping a module on the fly is cumbersome if a module is depended on by other modules. Currently, dependencies must be popped manually by unloading dependents, unloading the module of interest, and then loading modules again in reverse order. To make this easier, the ability to do this recursively in certain circumstances has been added, as an optional extension to the "module refresh" command. If requested, Asterisk will check if a module that has a positive usecount could be unloaded safely if anything recursively dependent on it were unloaded. If so, it will go ahead and unload all these modules and load them back again. This makes hot swapping modules that provide dependencies much easier. Resolves: #474 UserNote: In certain circumstances, modules with dependency relations can have their dependents automatically recursively unloaded and loaded again using the "module refresh" CLI command or the ModuleLoad AMI command.
This commit is contained in:
@@ -1142,10 +1142,18 @@
|
||||
<enum name="load" />
|
||||
<enum name="unload" />
|
||||
<enum name="reload" />
|
||||
<enum name="refresh">
|
||||
<para>Completely unload and load again a specified module.</para>
|
||||
</enum>
|
||||
</enumlist>
|
||||
<para>If no module is specified for a <literal>reload</literal> loadtype,
|
||||
all modules are reloaded.</para>
|
||||
</parameter>
|
||||
<parameter name="Recursive" required="false">
|
||||
<para>For <literal>refresh</literal> operations, attempt to recursively
|
||||
unload any other modules that are dependent on this module, if that would
|
||||
allow it to successfully unload, and load them again afterwards.</para>
|
||||
</parameter>
|
||||
</syntax>
|
||||
<description>
|
||||
<para>Loads, unloads or reloads an Asterisk module in a running system.</para>
|
||||
@@ -7275,6 +7283,7 @@ static int manager_moduleload(struct mansession *s, const struct message *m)
|
||||
int res;
|
||||
const char *module = astman_get_header(m, "Module");
|
||||
const char *loadtype = astman_get_header(m, "LoadType");
|
||||
const char *recursive = astman_get_header(m, "Recursive");
|
||||
|
||||
if (!loadtype || strlen(loadtype) == 0) {
|
||||
astman_send_error(s, m, "Incomplete ModuleLoad action.");
|
||||
@@ -7297,6 +7306,13 @@ static int manager_moduleload(struct mansession *s, const struct message *m)
|
||||
} else {
|
||||
astman_send_ack(s, m, "Module unloaded.");
|
||||
}
|
||||
} else if (!strcasecmp(loadtype, "refresh")) {
|
||||
res = ast_refresh_resource(module, AST_FORCE_SOFT, !ast_strlen_zero(recursive) && ast_true(recursive));
|
||||
if (res) {
|
||||
astman_send_error(s, m, "Could not refresh module.");
|
||||
} else {
|
||||
astman_send_ack(s, m, "Module unloaded and loaded.");
|
||||
}
|
||||
} else if (!strcasecmp(loadtype, "reload")) {
|
||||
/* TODO: Unify the ack/error messages here with action_reload */
|
||||
if (!ast_strlen_zero(module)) {
|
||||
|
Reference in New Issue
Block a user