Fix shutdown crash caused by modules being left open.
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:26 +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 36b316f..b3c2b20 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 d5616e9..a80c7f8 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 d4b39a2..56fc107 100644 (file)
@@ -2010,8 +2010,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 6617783..dacfce1 100644 (file)
@@ -607,7 +607,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;
@@ -655,7 +655,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)