<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/9446">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, but someone else must approve; Approved for Submit
  George Joseph: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">loader: Fix startup issues.<br><br>* Merge the preload and load stages, use load ordering to try preload's<br>  first.  This fixes an issue where `preload=res_config_curl` would fail<br>  unless res_curl and func_curl were also preloaded.  Now it is only<br>  required that those modules be loaded during startup: autoload or<br>  regular load is good enough.<br>* The configuration option `require` and `preload-require` were only<br>  effective if the modules failed to load.  These options will now abort<br>  Asterisk startup if required modules fail to reach the 'Running'<br>  state.<br>* Missing or invalid 'module.conf' did not prevent startup.  Asterisk<br>  doesn't do anything without modules so this a fatal error.<br><br>Change-Id: Ie4176699133f0e3a823b43f90c3348677e43a5f3<br>---<br>M include/asterisk/_private.h<br>M main/asterisk.c<br>M main/loader.c<br>3 files changed, 137 insertions(+), 54 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h</span><br><span>index d19c589..89a8f54 100644</span><br><span>--- a/include/asterisk/_private.h</span><br><span>+++ b/include/asterisk/_private.h</span><br><span>@@ -20,7 +20,7 @@</span><br><span> void set_asterisk_conf_path(const char *path);</span><br><span> void set_socket_path(const char *path);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int load_modules(unsigned int);               /*!< Provided by loader.c */</span><br><span style="color: hsl(120, 100%, 40%);">+int load_modules(void);                /*!< Provided by loader.c */</span><br><span> int modules_shutdown(void);          /*!< Provided by loader.c */</span><br><span> int load_pbx(void);                  /*!< Provided by pbx.c */</span><br><span> int load_pbx_builtins(void);    /*!< Provided by pbx_builtins.c */</span><br><span>diff --git a/main/asterisk.c b/main/asterisk.c</span><br><span>index 7ff167e..2fb32ac 100644</span><br><span>--- a/main/asterisk.c</span><br><span>+++ b/main/asterisk.c</span><br><span>@@ -4139,10 +4139,7 @@</span><br><span>      check_init(ast_local_init(), "Local Proxy Channel Driver");</span><br><span> </span><br><span>    /* We should avoid most config loads before this point as they can't use realtime. */</span><br><span style="color: hsl(0, 100%, 40%);">-       check_init(load_modules(1), "Module Preload");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Load remaining modules */</span><br><span style="color: hsl(0, 100%, 40%);">-    check_init(load_modules(0), "Module");</span><br><span style="color: hsl(120, 100%, 40%);">+      check_init(load_modules(), "Module");</span><br><span> </span><br><span>  /*</span><br><span>    * This has to load after the dynamic modules load, as items in the media</span><br><span>diff --git a/main/loader.c b/main/loader.c</span><br><span>index bc78962..d6837f8 100644</span><br><span>--- a/main/loader.c</span><br><span>+++ b/main/loader.c</span><br><span>@@ -181,6 +181,10 @@</span><br><span>            unsigned int keepuntilshutdown:1;</span><br><span>            /*! The module is built-in. */</span><br><span>               unsigned int builtin:1;</span><br><span style="color: hsl(120, 100%, 40%);">+               /*! The admin has declared this module is required. */</span><br><span style="color: hsl(120, 100%, 40%);">+                unsigned int required:1;</span><br><span style="color: hsl(120, 100%, 40%);">+              /*! This module is marked for preload. */</span><br><span style="color: hsl(120, 100%, 40%);">+             unsigned int preload:1;</span><br><span>      } flags;</span><br><span>     AST_DLLIST_ENTRY(ast_module) entry;</span><br><span>  char resource[0];</span><br><span>@@ -223,12 +227,20 @@</span><br><span> </span><br><span> static int module_vector_cmp(struct ast_module *a, struct ast_module *b)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        int preload_diff = (int)b->flags.preload - (int)a->flags.preload;</span><br><span>      /* if load_pri is not set, default is 128.  Lower is better */</span><br><span>       int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)</span><br><span>                ? a->info->load_pri : AST_MODPRI_DEFAULT;</span><br><span>      int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)</span><br><span>                ? b->info->load_pri : AST_MODPRI_DEFAULT;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   if (preload_diff) {</span><br><span style="color: hsl(120, 100%, 40%);">+           /* -1 preload a but not b */</span><br><span style="color: hsl(120, 100%, 40%);">+          /*  0 preload both or neither */</span><br><span style="color: hsl(120, 100%, 40%);">+              /*  1 preload b but not a */</span><br><span style="color: hsl(120, 100%, 40%);">+          return preload_diff;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  /*</span><br><span>    * Returns comparison values for a vector sorted by priority.</span><br><span>         * <0 a_pri < b_pri</span><br><span>@@ -1469,6 +1481,9 @@</span><br><span>            break;</span><br><span>       case AST_MODULE_LOAD_DECLINE:</span><br><span>                mod->flags.declined = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+           if (mod->flags.required) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 res = AST_MODULE_LOAD_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span>            break;</span><br><span>       case AST_MODULE_LOAD_FAILURE:</span><br><span>        case AST_MODULE_LOAD_SKIP: /* modules should never return this value */</span><br><span>@@ -1494,7 +1509,8 @@</span><br><span>  *</span><br><span>  *  If the module_vector is not provided, the module's load function will be executed</span><br><span>  *  immediately */</span><br><span style="color: hsl(0, 100%, 40%);">-static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging, struct module_vector *module_priorities, int required)</span><br><span style="color: hsl(120, 100%, 40%);">+static enum ast_module_load_result load_resource(const char *resource_name, unsigned int suppress_logging,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct module_vector *module_priorities, int required, int preload)</span><br><span> {</span><br><span>     struct ast_module *mod;</span><br><span>      enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;</span><br><span>@@ -1519,6 +1535,9 @@</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ mod->flags.required |= required;</span><br><span style="color: hsl(120, 100%, 40%);">+   mod->flags.preload |= preload;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (inspect_module(mod)) {</span><br><span>           goto prestart_error;</span><br><span>         }</span><br><span>@@ -1554,7 +1573,7 @@</span><br><span> {</span><br><span>       int res;</span><br><span>     AST_DLLIST_LOCK(&module_list);</span><br><span style="color: hsl(0, 100%, 40%);">-      res = load_resource(resource_name, 0, NULL, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+       res = load_resource(resource_name, 0, NULL, 0, 0);</span><br><span>   if (!res) {</span><br><span>          ast_test_suite_event_notify("MODULE_LOAD", "Message: %s", resource_name);</span><br><span>        }</span><br><span>@@ -1566,12 +1585,14 @@</span><br><span> struct load_order_entry {</span><br><span>     char *resource;</span><br><span>      int required;</span><br><span style="color: hsl(120, 100%, 40%);">+ int preload;</span><br><span style="color: hsl(120, 100%, 40%);">+  int builtin;</span><br><span>         AST_LIST_ENTRY(load_order_entry) entry;</span><br><span> };</span><br><span> </span><br><span> AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required, int preload, int builtin)</span><br><span> {</span><br><span>        struct load_order_entry *order;</span><br><span>      size_t resource_baselen = resource_name_baselen(resource);</span><br><span>@@ -1581,12 +1602,15 @@</span><br><span>                         /* Make sure we have the proper setting for the required field</span><br><span>                          (we might have both load= and required= lines in modules.conf) */</span><br><span>                         order->required |= required;</span><br><span style="color: hsl(0, 100%, 40%);">-                 return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                  order->preload |= preload;</span><br><span style="color: hsl(120, 100%, 40%);">+                 return order;</span><br><span>                }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!(order = ast_calloc(1, sizeof(*order))))</span><br><span style="color: hsl(120, 100%, 40%);">+ order = ast_calloc(1, sizeof(*order));</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!order) {</span><br><span>                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> </span><br><span>        order->resource = ast_strdup(resource);</span><br><span>   if (!order->resource) {</span><br><span>@@ -1595,6 +1619,8 @@</span><br><span>           return NULL;</span><br><span>         }</span><br><span>    order->required = required;</span><br><span style="color: hsl(120, 100%, 40%);">+        order->preload = preload;</span><br><span style="color: hsl(120, 100%, 40%);">+  order->builtin = builtin;</span><br><span>         AST_LIST_INSERT_TAIL(load_order, order, entry);</span><br><span> </span><br><span>  return order;</span><br><span>@@ -1647,7 +1673,7 @@</span><br><span> </span><br><span>            if (lres == AST_MODULE_LOAD_FAILURE) {</span><br><span>                       ast_log(LOG_ERROR, "Failed to load %s.\n", ast_module_name(mod));</span><br><span style="color: hsl(0, 100%, 40%);">-                     res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                     res = -2;</span><br><span>                    break;</span><br><span>               }</span><br><span> </span><br><span>@@ -1745,7 +1771,7 @@</span><br><span>                        enum ast_module_load_result lres;</span><br><span> </span><br><span>                        /* Suppress log messages unless this is the last pass */</span><br><span style="color: hsl(0, 100%, 40%);">-                        lres = load_resource(order->resource, !lasttry, &module_priorities, order->required);</span><br><span style="color: hsl(120, 100%, 40%);">+                       lres = load_resource(order->resource, !lasttry, &module_priorities, order->required, order->preload);</span><br><span>                   ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);</span><br><span>                    switch (lres) {</span><br><span>                      case AST_MODULE_LOAD_SUCCESS:</span><br><span>@@ -1799,24 +1825,9 @@</span><br><span>       return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-int load_modules(unsigned int preload_only)</span><br><span style="color: hsl(120, 100%, 40%);">+static int loader_builtin_init(struct load_order *load_order)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct ast_config *cfg;</span><br><span style="color: hsl(0, 100%, 40%);">- struct load_order_entry *order;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_variable *v;</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int load_count;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct load_order load_order;</span><br><span style="color: hsl(0, 100%, 40%);">-   int res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ast_flags config_flags = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">-  int modulecount = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct dirent *dirent;</span><br><span style="color: hsl(0, 100%, 40%);">-  DIR *dir;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_verb(1, "Asterisk Dynamic Loader Starting:\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   AST_LIST_HEAD_INIT_NOLOCK(&load_order);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     AST_DLLIST_LOCK(&module_list);</span><br><span style="color: hsl(120, 100%, 40%);">+    struct ast_module *mod;</span><br><span> </span><br><span>  /*</span><br><span>    * All built-in modules have registered the first time, now it's time to complete</span><br><span>@@ -1829,42 +1840,79 @@</span><br><span>              ast_module_register(resource_being_loaded->info);</span><br><span>         }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!preload_only) {</span><br><span style="color: hsl(0, 100%, 40%);">-            struct ast_module *mod;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Add all built-in modules to the load order. */</span><br><span style="color: hsl(120, 100%, 40%);">+     AST_DLLIST_TRAVERSE(&module_list, mod, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!mod->flags.builtin) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           /* Add all built-in modules to the load order. */</span><br><span style="color: hsl(0, 100%, 40%);">-               AST_DLLIST_TRAVERSE(&module_list, mod, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (!mod->flags.builtin) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       add_to_load_order(mod->resource, &load_order, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Built-in modules are not preloaded, most have an early load priority. */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!add_to_load_order(mod->resource, load_order, 0, 0, 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -1;</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int loader_config_init(struct load_order *load_order)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int res = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct load_order_entry *order;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_config *cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_variable *v;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_flags config_flags = { 0 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     cfg = ast_config_load2(AST_MODULE_CONFIG, "" /* core, can't reload */, config_flags);</span><br><span>  if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {</span><br><span style="color: hsl(0, 100%, 40%);">-             ast_log(LOG_WARNING, "No '%s' found, no modules will be loaded.\n", AST_MODULE_CONFIG);</span><br><span style="color: hsl(0, 100%, 40%);">-               goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_log(LOG_WARNING, "'%s' invalid or missing.\n", AST_MODULE_CONFIG);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            return -1;</span><br><span>   }</span><br><span> </span><br><span>        /* first, find all the modules we have been explicitly requested to load */</span><br><span>  for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!strcasecmp(v->name, preload_only ? "preload" : "load")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   add_to_load_order(v->value, &load_order, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           int required;</span><br><span style="color: hsl(120, 100%, 40%);">+         int preload = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!strncasecmp(v->name, "preload", strlen("preload"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     preload = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (!strcasecmp(v->name, "preload")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           required = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else if (!strcasecmp(v->name, "preload-require")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            required = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);</span><br><span style="color: hsl(120, 100%, 40%);">+                                goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             } else if (!strcasecmp(v->name, "load")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       required = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+         } else if (!strcasecmp(v->name, "require")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    required = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+         } else if (!strcasecmp(v->name, "noload") || !strcasecmp(v->name, "autoload")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_ERROR, "Unknown configuration option '%s'", v->name);</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto done;</span><br><span>           }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!strcasecmp(v->name, preload_only ? "preload-require" : "require")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* Add the module to the list and make sure it's required */</span><br><span style="color: hsl(0, 100%, 40%);">-                        add_to_load_order(v->value, &load_order, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (required) {</span><br><span>                      ast_debug(2, "Adding module to required list: %s (%s)\n", v->value, v->name);</span><br><span>                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!add_to_load_order(v->value, load_order, required, preload, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span>    }</span><br><span> </span><br><span>        /* check if 'autoload' is on */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!preload_only && ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ast_true(ast_variable_retrieve(cfg, "modules", "autoload"))) {</span><br><span>               /* if we are allowed to load dynamic modules, scan the directory for</span><br><span>                    for all available modules and add them as well */</span><br><span style="color: hsl(0, 100%, 40%);">-            if ((dir = opendir(ast_config_AST_MODULE_DIR))) {</span><br><span style="color: hsl(120, 100%, 40%);">+             DIR *dir = opendir(ast_config_AST_MODULE_DIR);</span><br><span style="color: hsl(120, 100%, 40%);">+                struct dirent *dirent;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if (dir) {</span><br><span>                   while ((dirent = readdir(dir))) {</span><br><span>                            int ld = strlen(dirent->d_name);</span><br><span> </span><br><span>@@ -1881,14 +1929,16 @@</span><br><span>                            if (find_resource(dirent->d_name, 0))</span><br><span>                                     continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                           add_to_load_order(dirent->d_name, &load_order, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (!add_to_load_order(dirent->d_name, load_order, 0, 0, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     closedir(dir);</span><br><span style="color: hsl(120, 100%, 40%);">+                                        goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+                            }</span><br><span>                    }</span><br><span> </span><br><span>                        closedir(dir);</span><br><span>               } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!ast_opt_quiet)</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_log(LOG_WARNING, "Unable to open modules directory '%s'.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                      ast_config_AST_MODULE_DIR);</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_ERROR, "Unable to open modules directory '%s'.\n", ast_config_AST_MODULE_DIR);</span><br><span style="color: hsl(120, 100%, 40%);">+                  goto done;</span><br><span>           }</span><br><span>    }</span><br><span> </span><br><span>@@ -1902,8 +1952,18 @@</span><br><span>               }</span><br><span> </span><br><span>                baselen = resource_name_baselen(v->value);</span><br><span style="color: hsl(0, 100%, 40%);">-           AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+         AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {</span><br><span>                     if (!resource_name_match(v->value, baselen, order->resource)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (order->builtin) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ast_log(LOG_ERROR, "%s is a built-in module, you cannot specify 'noload'.\n", v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+                                 goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+                            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                           if (order->required) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     ast_log(LOG_ERROR, "%s is configured with '%s' and 'noload', this is impossible.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                v->value, order->preload ? "preload-require" : "require");</span><br><span style="color: hsl(120, 100%, 40%);">+                                  goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+                            }</span><br><span>                            AST_LIST_REMOVE_CURRENT(entry);</span><br><span>                              ast_free(order->resource);</span><br><span>                                ast_free(order);</span><br><span>@@ -1912,10 +1972,36 @@</span><br><span>           AST_LIST_TRAVERSE_SAFE_END;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* we are done with the config now, all the information we need is in the</span><br><span style="color: hsl(0, 100%, 40%);">-          load_order list */</span><br><span style="color: hsl(120, 100%, 40%);">+ res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+done:</span><br><span>      ast_config_destroy(cfg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  return res;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int load_modules(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct load_order_entry *order;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int load_count;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct load_order load_order;</span><br><span style="color: hsl(120, 100%, 40%);">+ int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  int modulecount = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_verb(1, "Asterisk Dynamic Loader Starting:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_LIST_HEAD_INIT_NOLOCK(&load_order);</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_DLLIST_LOCK(&module_list);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  res = loader_builtin_init(&load_order);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   res = loader_config_init(&load_order);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (res) {</span><br><span style="color: hsl(120, 100%, 40%);">+            goto done;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  load_count = 0;</span><br><span>      AST_LIST_TRAVERSE(&load_order, order, entry)</span><br><span>             load_count++;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9446">change 9446</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/9446"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ie4176699133f0e3a823b43f90c3348677e43a5f3 </div>
<div style="display:none"> Gerrit-Change-Number: 9446 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>