vlib: add description field in plugin registration
[vpp.git] / src / vlib / unix / plugin.c
index 4aba95c..9b341cc 100644 (file)
@@ -105,13 +105,13 @@ load_one_plugin (plugin_main_t * pm, plugin_info_t * pi, int from_early_init)
        }
       if (reg->default_disabled && pc->is_enabled == 0)
        {
-         clib_warning ("Plugin disabled: %s (default)", pi->name);
+         clib_warning ("Plugin disabled (default): %s", pi->name);
          goto error;
        }
     }
   else if (reg->default_disabled)
     {
-      clib_warning ("Plugin disabled: %s (default)", pi->name);
+      clib_warning ("Plugin disabled (default): %s", pi->name);
       goto error;
     }
 
@@ -163,7 +163,7 @@ load_one_plugin (plugin_main_t * pm, plugin_info_t * pi, int from_early_init)
   pi->version = str_array_to_vec ((char *) &reg->version,
                                  sizeof (reg->version));
 
-  if (reg && reg->early_init)
+  if (reg->early_init)
     {
       clib_error_t *(*ei) (vlib_main_t *);
       void *h;
@@ -184,7 +184,10 @@ load_one_plugin (plugin_main_t * pm, plugin_info_t * pi, int from_early_init)
                      (char *) pi->name, reg->early_init);
     }
 
-  clib_warning ("Loaded plugin: %s", pi->name);
+  if (reg->description)
+    clib_warning ("Loaded plugin: %s (%s)", pi->name, reg->description);
+  else
+    clib_warning ("Loaded plugin: %s", pi->name);
 
   return 0;
 error:
@@ -220,6 +223,15 @@ split_plugin_path (plugin_main_t * pm)
   return rv;
 }
 
+static int
+plugin_name_sort_cmp (void *a1, void *a2)
+{
+  plugin_info_t *p1 = a1;
+  plugin_info_t *p2 = a2;
+
+  return strcmp ((char *) p1->name, (char *) p2->name);
+}
+
 int
 vlib_load_new_plugins (plugin_main_t * pm, int from_early_init)
 {
@@ -229,6 +241,7 @@ vlib_load_new_plugins (plugin_main_t * pm, int from_early_init)
   uword *p;
   plugin_info_t *pi;
   u8 **plugin_path;
+  u32 *load_fail_indices = 0;
   int i;
 
   plugin_path = split_plugin_path (pm);
@@ -271,22 +284,15 @@ vlib_load_new_plugins (plugin_main_t * pm, int from_early_init)
            goto ignore;
 
          plugin_name = format (0, "%s%c", entry->d_name, 0);
+         /* Have we seen this plugin already? */
          p = hash_get_mem (pm->plugin_by_name_hash, plugin_name);
          if (p == 0)
            {
+             /* No, add it to the plugin vector */
              vec_add2 (pm->plugin_info, pi, 1);
              pi->name = plugin_name;
              pi->filename = filename;
              pi->file_info = statb;
-
-             if (load_one_plugin (pm, pi, from_early_init))
-               {
-                 vec_free (plugin_name);
-                 vec_free (filename);
-                 _vec_len (pm->plugin_info) = vec_len (pm->plugin_info) - 1;
-                 memset (pi, 0, sizeof (*pi));
-                 continue;
-               }
              hash_set_mem (pm->plugin_by_name_hash, plugin_name,
                            pi - pm->plugin_info);
            }
@@ -297,6 +303,49 @@ vlib_load_new_plugins (plugin_main_t * pm, int from_early_init)
       vec_free (plugin_path[i]);
     }
   vec_free (plugin_path);
+
+
+  /*
+   * Sort the plugins by name. This is important.
+   * API traces contain absolute message numbers.
+   * Loading plugins in directory (vs. alphabetical) order
+   * makes trace replay incredibly fragile.
+   */
+  vec_sort_with_function (pm->plugin_info, plugin_name_sort_cmp);
+
+  /*
+   * Attempt to load the plugins
+   */
+  for (i = 0; i < vec_len (pm->plugin_info); i++)
+    {
+      pi = vec_elt_at_index (pm->plugin_info, i);
+
+      if (load_one_plugin (pm, pi, from_early_init))
+       {
+         /* Make a note of any which fail to load */
+         vec_add1 (load_fail_indices, i);
+         hash_unset_mem (pm->plugin_by_name_hash, pi->name);
+         vec_free (pi->name);
+         vec_free (pi->filename);
+       }
+    }
+
+  /* Remove plugin info vector elements corresponding to load failures */
+  if (vec_len (load_fail_indices) > 0)
+    {
+      for (i = vec_len (load_fail_indices) - 1; i >= 0; i--)
+       vec_delete (pm->plugin_info, 1, load_fail_indices[i]);
+      vec_free (load_fail_indices);
+    }
+
+  /* Recreate the plugin name hash */
+  for (i = 0; i < vec_len (pm->plugin_info); i++)
+    {
+      pi = vec_elt_at_index (pm->plugin_info, i);
+      hash_unset_mem (pm->plugin_by_name_hash, pi->name);
+      hash_set_mem (pm->plugin_by_name_hash, pi->name, pi - pm->plugin_info);
+    }
+
   return 0;
 }
 
@@ -328,7 +377,7 @@ vlib_plugins_show_cmd_fn (vlib_main_t * vm,
   plugin_info_t *pi;
 
   s = format (s, " Plugin path is: %s\n\n", pm->plugin_path);
-  s = format (s, "     %-41s%s\n", "Plugin", "Version");
+  s = format (s, "     %-41s%-33s%s\n", "Plugin", "Version", "Description");
 
   /* *INDENT-OFF* */
   hash_foreach_mem (key, value, pm->plugin_by_name_hash,
@@ -336,7 +385,8 @@ vlib_plugins_show_cmd_fn (vlib_main_t * vm,
       if (key != 0)
         {
           pi = vec_elt_at_index (pm->plugin_info, value);
-          s = format (s, "%3d. %-40s %s\n", index, key, pi->version);
+          s = format (s, "%3d. %-40s %-32s %s\n", index, key, pi->version,
+                     pi->reg->description ? pi->reg->description : "");
          index++;
         }
     });