goto error;
}
+ if (pm->plugins_default_disable)
+ reg->default_disabled = 1;
+
p = hash_get_mem (pm->config_index_by_name, pi->name);
if (p)
{
}
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;
}
handle = dlopen ((char *) pi->filename, RTLD_LAZY);
- /*
- * Note: this can happen if the plugin has an undefined symbol reference,
- * so print a warning. Otherwise, the poor slob won't know what happened.
- * Ask me how I know that...
- */
if (handle == 0)
{
clib_warning ("%s", dlerror ());
- return -1;
+ clib_warning ("Failed to load plugin '%s'", pi->name);
+ goto error;
}
pi->handle = handle;
(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:
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)
{
uword *p;
plugin_info_t *pi;
u8 **plugin_path;
+ u32 *load_fail_indices = 0;
int i;
plugin_path = split_plugin_path (pm);
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);
}
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;
}
return vlib_load_new_plugins (pm, 1 /* from_early_init */ );
}
+u8 *
+vlib_get_vat_plugin_path (void)
+{
+ plugin_main_t *pm = &vlib_plugin_main;
+ return (pm->vat_plugin_path);
+}
+
+u8 *
+vlib_get_vat_plugin_name_filter (void)
+{
+ plugin_main_t *pm = &vlib_plugin_main;
+ return (pm->vat_plugin_name_filter);
+}
+
static clib_error_t *
vlib_plugins_show_cmd_fn (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
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,
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++;
}
});
u8 *s = 0;
if (unformat (input, "path %s", &s))
pm->plugin_path = s;
+ else if (unformat (input, "name-filter %s", &s))
+ pm->plugin_name_filter = s;
+ else if (unformat (input, "vat-path %s", &s))
+ pm->vat_plugin_path = s;
+ else if (unformat (input, "vat-name-filter %s", &s))
+ pm->vat_plugin_name_filter = s;
+ else if (unformat (input, "plugin default %U",
+ unformat_vlib_cli_sub_input, &sub_input))
+ {
+ pm->plugins_default_disable =
+ unformat (&sub_input, "disable") ? 1 : 0;
+ unformat_free (&sub_input);
+ }
else if (unformat (input, "plugin %s %U", &s,
unformat_vlib_cli_sub_input, &sub_input))
{