+
+
+ /*
+ * 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 (not_loaded_indices, i);
+ }
+ }
+
+ /*
+ * Honor override list
+ */
+ for (i = 0; i < vec_len (pm->plugin_info); i++)
+ {
+ uword *p;
+
+ pi = vec_elt_at_index (pm->plugin_info, i);
+
+ p = hash_get_mem (pm->plugin_overrides_by_name_hash, pi->name);
+
+ /* Plugin overridden? */
+ if (p)
+ {
+ PLUGIN_LOG_NOTICE ("Plugin '%s' overridden by '%s'", pi->name,
+ p[0]);
+ vec_add1 (not_loaded_indices, i);
+ }
+ }
+
+ /*
+ * Sort the vector of indices to delete to avoid screwing up
+ * the indices as we delete them.
+ */
+ vec_sort_with_function (not_loaded_indices, index_cmp);
+
+ /*
+ * Remove duplicates, which can happen if a plugin is
+ * disabled from the command line and disabled by
+ * a plugin which is loaded.
+ */
+ for (i = 0; i < vec_len (not_loaded_indices); i++)
+ {
+ if (i < vec_len (not_loaded_indices) - 1)
+ {
+ if (not_loaded_indices[i + 1] == not_loaded_indices[i])
+ {
+ vec_delete (not_loaded_indices, 1, i);
+ i--;
+ }
+ }
+ }
+
+ /* Remove plugin info vector elements corresponding to load failures */
+ if (vec_len (not_loaded_indices) > 0)
+ {
+ for (i = vec_len (not_loaded_indices) - 1; i >= 0; i--)
+ {
+ pi = vec_elt_at_index (pm->plugin_info, not_loaded_indices[i]);
+ hash_unset_mem (pm->plugin_by_name_hash, pi->name);
+ if (pi->handle)
+ {
+ dlclose (pi->handle);
+ PLUGIN_LOG_NOTICE ("Unloaded plugin: %s", pi->name);
+ }
+ vec_free (pi->name);
+ vec_free (pi->filename);
+ vec_delete (pm->plugin_info, 1, not_loaded_indices[i]);
+ }
+ vec_free (not_loaded_indices);
+ }
+
+ /* Recreate the plugin name hash */
+ hash_free (pm->plugin_by_name_hash);
+ pm->plugin_by_name_hash = hash_create_string (0, sizeof (uword));
+
+ for (i = 0; i < vec_len (pm->plugin_info); i++)
+ {
+ pi = vec_elt_at_index (pm->plugin_info, i);
+ hash_set_mem (pm->plugin_by_name_hash, pi->name, pi - pm->plugin_info);
+ }
+