<p>George Joseph <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/15625">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Sean Bright: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved; Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">loader: Output warnings for deprecated modules.<br><br>Using the information from the MODULEINFO XML we can<br>now output useful information at the end of module<br>loading for deprecated modules. This includes the<br>version it was deprecated in, the version it will be<br>removed in, and the replacement if available.<br><br>ASTERISK-29339<br><br>Change-Id: I2080dab97d2186be94c421b41dabf6d79a11611a<br>---<br>M main/loader.c<br>1 file changed, 147 insertions(+), 31 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/main/loader.c b/main/loader.c</span><br><span>index 033693e..f06016c 100644</span><br><span>--- a/main/loader.c</span><br><span>+++ b/main/loader.c</span><br><span>@@ -153,37 +153,7 @@</span><br><span> static struct ast_vector_string startup_errors;</span><br><span> static struct ast_str *startup_error_builder;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#if defined(HAVE_PERMANENT_DLOPEN)</span><br><span style="color: hsl(0, 100%, 40%);">-#define FIRST_DLOPEN 999</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct ao2_container *info_list = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct info_list_obj {</span><br><span style="color: hsl(0, 100%, 40%);">- const struct ast_module_info *info;</span><br><span style="color: hsl(0, 100%, 40%);">-     int dlopened;</span><br><span style="color: hsl(0, 100%, 40%);">-   char name[0];</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%);">-static struct info_list_obj *info_list_obj_alloc(const char *name,</span><br><span style="color: hsl(0, 100%, 40%);">-       const struct ast_module_info *info)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct info_list_obj *new_entry;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!new_entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</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%);">-       strcpy(new_entry->name, name); /* SAFE */</span><br><span style="color: hsl(0, 100%, 40%);">-    new_entry->info = info;</span><br><span style="color: hsl(0, 100%, 40%);">-      new_entry->dlopened = FIRST_DLOPEN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return new_entry;</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%);">-AO2_STRING_FIELD_CMP_FN(info_list_obj, name)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+#if defined(HAVE_PERMANENT_DLOPEN) || defined(AST_XML_DOCS)</span><br><span> static char *get_name_from_resource(const char *resource)</span><br><span> {</span><br><span>        int len;</span><br><span>@@ -219,6 +189,38 @@</span><br><span>      /* Unable to allocate memory. */</span><br><span>     return NULL;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if defined(HAVE_PERMANENT_DLOPEN)</span><br><span style="color: hsl(120, 100%, 40%);">+#define FIRST_DLOPEN 999</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ao2_container *info_list = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct info_list_obj {</span><br><span style="color: hsl(120, 100%, 40%);">+        const struct ast_module_info *info;</span><br><span style="color: hsl(120, 100%, 40%);">+   int dlopened;</span><br><span style="color: hsl(120, 100%, 40%);">+ char name[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 struct info_list_obj *info_list_obj_alloc(const char *name,</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct ast_module_info *info)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct info_list_obj *new_entry;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!new_entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</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%);">+   strcpy(new_entry->name, name); /* SAFE */</span><br><span style="color: hsl(120, 100%, 40%);">+  new_entry->info = info;</span><br><span style="color: hsl(120, 100%, 40%);">+    new_entry->dlopened = FIRST_DLOPEN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return new_entry;</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%);">+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)</span><br><span> </span><br><span> static void manual_mod_reg(const void *lib, const char *resource)</span><br><span> {</span><br><span>@@ -2341,6 +2343,16 @@</span><br><span>  int res = 0;</span><br><span>         int modulecount = 0;</span><br><span>         int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ast_module *cur;</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ast_str *warning_msg;</span><br><span style="color: hsl(120, 100%, 40%);">+  char deprecated_in[33];</span><br><span style="color: hsl(120, 100%, 40%);">+       char removed_in[33];</span><br><span style="color: hsl(120, 100%, 40%);">+  char replacement[129];</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+        struct timeval start_time = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+      struct timeval end_time;</span><br><span style="color: hsl(120, 100%, 40%);">+      int64_t usElapsed;</span><br><span> </span><br><span>       ast_verb(1, "Asterisk Dynamic Loader Starting:\n");</span><br><span> </span><br><span>@@ -2388,8 +2400,103 @@</span><br><span>          ast_free(order);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+    warning_msg = ast_str_create(512);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_DLLIST_TRAVERSE(&module_list, cur, entry) {</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+              char *mod_name = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+                struct ast_xml_xpath_results *results;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!cur->flags.running || cur->flags.declined) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</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%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+              mod_name = get_name_from_resource(cur->resource);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!warning_msg || !mod_name) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* If we can't allocate memory, we have bigger issues */</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_free(mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</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%);">+           results = ast_xmldoc_query("/docs/module[@name='%s']/deprecated_in", mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+             deprecated_in[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+              if (results) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!ast_strlen_zero(result_tmp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_copy_string(deprecated_in, result_tmp, sizeof(deprecated_in));</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_xml_xpath_results_free(results);</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%);">+           results = ast_xmldoc_query("/docs/module[@name='%s']/removed_in", mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                removed_in[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+         if (results) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!ast_strlen_zero(result_tmp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_copy_string(removed_in, result_tmp, sizeof(removed_in));</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_xml_xpath_results_free(results);</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%);">+           results = ast_xmldoc_query("/docs/module[@name='%s']/replacement", mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+               replacement[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+                if (results) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        const char *result_tmp = ast_xml_get_text(ast_xml_xpath_get_first_result(results));</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (!ast_strlen_zero(result_tmp)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_copy_string(replacement, result_tmp, sizeof(replacement));</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_xml_xpath_results_free(results);</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%);">+           ast_str_reset(warning_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED || !ast_strlen_zero(deprecated_in)</span><br><span style="color: hsl(120, 100%, 40%);">+                        || !ast_strlen_zero(removed_in) || !ast_strlen_zero(replacement)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   int already_butted = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_str_append(&warning_msg, -1, "Module '%s' has been loaded", mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (!ast_strlen_zero(deprecated_in)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                ast_str_append(&warning_msg, -1, " but %s deprecated in Asterisk version %s",</span><br><span style="color: hsl(120, 100%, 40%);">+                                    cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED ? "was" : "will be", deprecated_in);</span><br><span style="color: hsl(120, 100%, 40%);">+                             already_butted = 1;</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 (!ast_strlen_zero(removed_in)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_str_append(&warning_msg, -1, " %s will be removed in Asterisk version %s", already_butted ? "and" : "but", removed_in);</span><br><span style="color: hsl(120, 100%, 40%);">+                 } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              ast_str_append(&warning_msg, -1, " %s may be removed in a future release", already_butted ? "and" : "but");</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%);">+                   ast_str_append(&warning_msg, -1, ".");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (!ast_strlen_zero(replacement)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          ast_str_append(&warning_msg, -1, " Its replacement is '%s'.", replacement);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ast_str_strlen(warning_msg)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    ast_log(LOG_WARNING, "%s\n", ast_str_buffer(warning_msg));</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%);">+           ast_free(mod_name);</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+            if (cur->info->support_level == AST_MODULE_SUPPORT_DEPRECATED) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_log(LOG_WARNING, "The deprecated module '%s' has been loaded and is running, it may be removed in a future version\n", cur->resource);</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</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%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_free(warning_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     AST_DLLIST_UNLOCK(&module_list);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   for (i = 0; i < AST_VECTOR_SIZE(&startup_errors); i++) {</span><br><span>              char *str = AST_VECTOR_GET(&startup_errors, i);</span><br><span> </span><br><span>@@ -2401,6 +2508,15 @@</span><br><span>     ast_free(startup_error_builder);</span><br><span>     startup_error_builder = NULL;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     end_time = ast_tvnow();</span><br><span style="color: hsl(120, 100%, 40%);">+       usElapsed = ast_tvdiff_us(end_time, start_time);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef AST_XML_DOCS</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_debug(1, "Loader time with AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_debug(1, "Loader time without AST_XML_DOCS: %ld.%06ld\n", usElapsed / 1000000, usElapsed % 1000000);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         return res;</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/15625">change 15625</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/c/asterisk/+/15625"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-Change-Id: I2080dab97d2186be94c421b41dabf6d79a11611a </div>
<div style="display:none"> Gerrit-Change-Number: 15625 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>