]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix shutdown crash caused by modules being left open. 19/4219/1
authorCorey Farrell <git@cfware.com>
Fri, 28 Oct 2016 02:49:43 +0000 (22:49 -0400)
committerCorey Farrell <git@cfware.com>
Fri, 28 Oct 2016 15:24:13 +0000 (10:24 -0500)
It is only safe to run ast_register_cleanup callbacks when all modules
have been unloaded.  Previously these callbacks were run during graceful
shutdown, making it possible to crash during shutdown.

ASTERISK-26513 #close

Change-Id: Ibfa635bb688d1227ec54aa211d90d6bd45052e21

include/asterisk/_private.h
include/asterisk/module.h
main/asterisk.c
main/loader.c

index 36b316f2a32fd389baa9c6d8361bd9bc6e417b95..b3c2b200206faacbbd3e85d1fc7c5fb5202e6914 100644 (file)
@@ -16,6 +16,7 @@
 #define _ASTERISK__PRIVATE_H
 
 int load_modules(unsigned int);                /*!< Provided by loader.c */
+int modules_shutdown(void);            /*!< Provided by loader.c */
 int load_pbx(void);                    /*!< Provided by pbx.c */
 int load_pbx_builtins(void);   /*!< Provided by pbx_builtins.c */
 int load_pbx_functions_cli(void);      /*!< Provided by pbx_functions.c */
index d5616e9d82dc1cd4dc6b665a18a30f64710e219c..a80c7f843ae72e994383eeac71e70a6e3e42dc48 100644 (file)
@@ -228,13 +228,6 @@ int ast_loader_register(int (*updater)(void));
  */
 int ast_loader_unregister(int (*updater)(void));
 
-/*!
- * \brief Run the unload() callback for all loaded modules
- *
- * This function should be called when Asterisk is shutting down gracefully.
- */
-void ast_module_shutdown(void);
-
 /*! 
  * \brief Match modules names for the Asterisk cli.
  * \param line Unused by this function, but this should be the line we are
index 94481eecff3b9fadb5afad8cefd11dff2695150c..377f421d21a60799b293d785f5699ae69618501f 100644 (file)
@@ -2055,8 +2055,9 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
        struct ast_json *json_object = NULL;
        int run_cleanups = niceness >= SHUTDOWN_NICE;
 
-       if (run_cleanups) {
-               ast_module_shutdown();
+       if (run_cleanups && modules_shutdown()) {
+               ast_verb(0, "Some modules could not be unloaded, switching to fast shutdown\n");
+               run_cleanups = 0;
        }
 
        if (!restart) {
index 36a3d5f61b6727019a5d8e01cf2edb162921a6e2..442854474c26c247834881f25ba9e616137bcf3e 100644 (file)
@@ -609,7 +609,7 @@ static struct ast_module *load_dynamic_module(const char *resource_in, unsigned
 
 #endif
 
-void ast_module_shutdown(void)
+int modules_shutdown(void)
 {
        struct ast_module *mod;
        int somethingchanged = 1, final = 0;
@@ -657,7 +657,10 @@ void ast_module_shutdown(void)
                }
        } while (somethingchanged && !final);
 
+       final = AST_DLLIST_EMPTY(&module_list);
        AST_DLLIST_UNLOCK(&module_list);
+
+       return !final;
 }
 
 int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode force)