[RFC PATCH 24/44] eal: separate plugin paths from loaded plugin objects
Bruce Richardson
bruce.richardson at intel.com
Wed Apr 29 18:58:16 CEST 2026
The one data structure in eal managed both the loaded plugins and the
list of plugin paths provided by the user, separating the two rather
awkwardly by using a flag value. Since we have separate user_cfg and
runtime_state structures, separate the plugin info between the two
structs - user provided directory and file paths in one, and actual
loaded .so paths and pointers in the other.
Signed-off-by: Bruce Richardson <bruce.richardson at intel.com>
---
lib/eal/common/eal_common_options.c | 248 +++++++++++++++-------------
lib/eal/common/eal_internal_cfg.h | 22 +++
2 files changed, 158 insertions(+), 112 deletions(-)
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index 71fc69e80d..63ab7980c1 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -261,21 +261,6 @@ eal_collate_args(int argc, char **argv)
return retval - 1;
}
-TAILQ_HEAD(shared_driver_list, shared_driver);
-
-/* Definition for shared object drivers. */
-struct shared_driver {
- TAILQ_ENTRY(shared_driver) next;
-
- char name[PATH_MAX];
- void* lib_handle;
- bool from_cmdline; /**< true if from -d flag, false if driver found in a directory */
-};
-
-/* List of external loadable drivers */
-static struct shared_driver_list solib_list =
-TAILQ_HEAD_INITIALIZER(solib_list);
-
#ifndef RTE_EXEC_ENV_WINDOWS
/* Default path of external loadable drivers */
static const char *default_solib_dir = RTE_EAL_PMD_PATH;
@@ -489,6 +474,8 @@ eal_reset_internal_config(void)
int i;
TAILQ_INIT(&user_cfg->devopt_list);
+ TAILQ_INIT(&user_cfg->plugin_list);
+ TAILQ_INIT(&runtime_state->loaded_plugins);
user_cfg->memory = 0;
user_cfg->force_nrank = 0;
user_cfg->force_nchannel = 0;
@@ -539,19 +526,18 @@ eal_reset_internal_config(void)
}
static int
-eal_plugin_add(const char *path, bool from_cmdline)
+eal_plugin_path_add(const char *path)
{
- struct shared_driver *solib;
+ struct eal_user_cfg *user_cfg = eal_get_user_configuration();
+ struct eal_plugin_path *p;
- solib = malloc(sizeof(*solib));
- if (solib == NULL) {
- EAL_LOG(ERR, "malloc(solib) failed");
+ p = malloc(sizeof(*p));
+ if (p == NULL) {
+ EAL_LOG(ERR, "malloc(plugin_path) failed");
return -1;
}
- memset(solib, 0, sizeof(*solib));
- strlcpy(solib->name, path, PATH_MAX);
- solib->from_cmdline = from_cmdline;
- TAILQ_INSERT_TAIL(&solib_list, solib, next);
+ strlcpy(p->name, path, PATH_MAX);
+ TAILQ_INSERT_TAIL(&user_cfg->plugin_list, p, next);
return 0;
}
@@ -573,53 +559,6 @@ ends_with(const char *str, const char *tail)
return str_len >= tail_len && strcmp(&str[str_len - tail_len], tail) == 0;
}
-static int
-eal_plugindir_init(const char *path)
-{
- struct dirent *dent = NULL;
- DIR *d = NULL;
-
- if (path == NULL || *path == '\0')
- return 0;
-
- d = opendir(path);
- if (d == NULL) {
- EAL_LOG(ERR, "failed to open directory %s: %s",
- path, strerror(errno));
- return -1;
- }
-
- while ((dent = readdir(d)) != NULL) {
- char *sopath = NULL;
- struct stat sb;
-
- if (!ends_with(dent->d_name, ".so") && !ends_with(dent->d_name, ".so."ABI_VERSION))
- continue;
-
- if (asprintf(&sopath, "%s/%s", path, dent->d_name) < 0) {
- EAL_LOG(ERR, "failed to create full path %s/%s",
- path, dent->d_name);
- continue;
- }
-
- /* if a regular file, add to list to load */
- if (!(stat(sopath, &sb) == 0 && S_ISREG(sb.st_mode))) {
- free(sopath);
- continue;
- }
-
- if (eal_plugin_add(sopath, false) == -1) {
- free(sopath);
- break;
- }
- free(sopath);
- }
-
- closedir(d);
- /* XXX this ignores failures from readdir() itself */
- return (dent == NULL) ? 0 : -1;
-}
-
static int
verify_perms(const char *dirpath)
{
@@ -691,6 +630,65 @@ eal_dlopen(const char *pathname)
return retval;
}
+static int
+eal_plugindir_init(const char *path)
+{
+ struct eal_runtime_state *runtime_state = eal_get_runtime_state();
+ struct dirent *dent = NULL;
+ DIR *d = NULL;
+
+ if (path == NULL || *path == '\0')
+ return 0;
+
+ d = opendir(path);
+ if (d == NULL) {
+ EAL_LOG(ERR, "failed to open directory %s: %s",
+ path, strerror(errno));
+ return -1;
+ }
+
+ while ((dent = readdir(d)) != NULL) {
+ char *sopath = NULL;
+ struct shared_driver *solib;
+ struct stat sb;
+
+ if (!ends_with(dent->d_name, ".so") && !ends_with(dent->d_name, ".so."ABI_VERSION))
+ continue;
+
+ if (asprintf(&sopath, "%s/%s", path, dent->d_name) < 0) {
+ EAL_LOG(ERR, "failed to create full path %s/%s",
+ path, dent->d_name);
+ continue;
+ }
+
+ /* if not a regular file, skip */
+ if (!(stat(sopath, &sb) == 0 && S_ISREG(sb.st_mode))) {
+ free(sopath);
+ continue;
+ }
+
+ solib = calloc(1, sizeof(*solib));
+ if (solib == NULL) {
+ free(sopath);
+ break;
+ }
+ strlcpy(solib->name, sopath, PATH_MAX);
+ free(sopath);
+
+ EAL_LOG(DEBUG, "open shared lib %s", solib->name);
+ solib->lib_handle = eal_dlopen(solib->name);
+ if (solib->lib_handle == NULL) {
+ free(solib);
+ break;
+ }
+ TAILQ_INSERT_TAIL(&runtime_state->loaded_plugins, solib, next);
+ }
+
+ closedir(d);
+ /* XXX this ignores failures from readdir() itself */
+ return (dent == NULL) ? 0 : -1;
+}
+
static int
is_shared_build(void)
{
@@ -731,37 +729,45 @@ is_shared_build(void)
int
eal_plugins_init(void)
{
- struct shared_driver *solib = NULL;
+ struct eal_user_cfg *user_cfg = eal_get_user_configuration();
+ struct eal_runtime_state *runtime_state = eal_get_runtime_state();
+ struct eal_plugin_path *p;
struct stat sb;
- /* If we are not statically linked, add default driver loading
- * path if it exists as a directory.
- * (Using dlopen with NOLOAD flag on EAL, will return NULL if the EAL
- * shared library is not already loaded i.e. it's statically linked.)
- */
+ TAILQ_INIT(&runtime_state->loaded_plugins);
+
+ /* If we are not statically linked, scan the default driver directory. */
if (is_shared_build() &&
*default_solib_dir != '\0' &&
stat(default_solib_dir, &sb) == 0 &&
- S_ISDIR(sb.st_mode))
- eal_plugin_add(default_solib_dir, false);
-
- TAILQ_FOREACH(solib, &solib_list, next) {
+ S_ISDIR(sb.st_mode)) {
+ if (eal_plugindir_init(default_solib_dir) == -1) {
+ EAL_LOG(ERR, "Cannot init plugin directory %s",
+ default_solib_dir);
+ return -1;
+ }
+ }
- if (stat(solib->name, &sb) == 0 && S_ISDIR(sb.st_mode)) {
- if (eal_plugindir_init(solib->name) == -1) {
- EAL_LOG(ERR,
- "Cannot init plugin directory %s",
- solib->name);
+ TAILQ_FOREACH(p, &user_cfg->plugin_list, next) {
+ if (stat(p->name, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+ if (eal_plugindir_init(p->name) == -1) {
+ EAL_LOG(ERR, "Cannot init plugin directory %s",
+ p->name);
return -1;
}
} else {
- EAL_LOG(DEBUG, "open shared lib %s",
- solib->name);
+ struct shared_driver *solib = calloc(1, sizeof(*solib));
+ if (solib == NULL)
+ return -1;
+ strlcpy(solib->name, p->name, PATH_MAX);
+ EAL_LOG(DEBUG, "open shared lib %s", solib->name);
solib->lib_handle = eal_dlopen(solib->name);
- if (solib->lib_handle == NULL)
+ if (solib->lib_handle == NULL) {
+ free(solib);
return -1;
+ }
+ TAILQ_INSERT_TAIL(&runtime_state->loaded_plugins, solib, next);
}
-
}
return 0;
}
@@ -771,40 +777,58 @@ RTE_EXPORT_INTERNAL_SYMBOL(rte_eal_driver_path_next)
const char *
rte_eal_driver_path_next(const char *start, bool cmdline_only)
{
- struct shared_driver *solib;
+ if (cmdline_only) {
+ const struct eal_user_cfg *user_cfg = eal_get_user_configuration();
+ struct eal_plugin_path *p;
- if (start == NULL) {
- solib = TAILQ_FIRST(&solib_list);
- } else {
- /* Find the current entry based on the name string */
- TAILQ_FOREACH(solib, &solib_list, next) {
- if (start == solib->name) {
- solib = TAILQ_NEXT(solib, next);
- break;
+ if (start == NULL) {
+ p = TAILQ_FIRST(&user_cfg->plugin_list);
+ } else {
+ TAILQ_FOREACH(p, &user_cfg->plugin_list, next) {
+ if (start == p->name) {
+ p = TAILQ_NEXT(p, next);
+ break;
+ }
}
+ if (p == NULL)
+ return NULL;
}
- if (solib == NULL)
- return NULL;
- }
+ return p ? p->name : NULL;
+ } else {
+ const struct eal_runtime_state *runtime_state = eal_get_runtime_state();
+ struct shared_driver *solib;
- /* Skip entries that were expanded from directories if cmdline_only is true */
- if (cmdline_only) {
- while (solib != NULL && !solib->from_cmdline)
- solib = TAILQ_NEXT(solib, next);
+ if (start == NULL) {
+ solib = TAILQ_FIRST(&runtime_state->loaded_plugins);
+ } else {
+ TAILQ_FOREACH(solib, &runtime_state->loaded_plugins, next) {
+ if (start == solib->name) {
+ solib = TAILQ_NEXT(solib, next);
+ break;
+ }
+ }
+ if (solib == NULL)
+ return NULL;
+ }
+ return solib ? solib->name : NULL;
}
-
- return solib ? solib->name : NULL;
}
RTE_EXPORT_INTERNAL_SYMBOL(rte_eal_driver_path_count)
unsigned int
rte_eal_driver_path_count(bool cmdline_only)
{
- struct shared_driver *solib;
unsigned int count = 0;
- TAILQ_FOREACH(solib, &solib_list, next) {
- if (!cmdline_only || solib->from_cmdline)
+ if (cmdline_only) {
+ const struct eal_user_cfg *user_cfg = eal_get_user_configuration();
+ struct eal_plugin_path *p;
+ TAILQ_FOREACH(p, &user_cfg->plugin_list, next)
+ count++;
+ } else {
+ const struct eal_runtime_state *runtime_state = eal_get_runtime_state();
+ struct shared_driver *solib;
+ TAILQ_FOREACH(solib, &runtime_state->loaded_plugins, next)
count++;
}
@@ -1987,7 +2011,7 @@ eal_parse_args(void)
return -1;
/* driver loading options */
TAILQ_FOREACH(arg, &args.driver_path, next)
- if (eal_plugin_add(arg->arg, true) < 0)
+ if (eal_plugin_path_add(arg->arg) < 0)
return -1;
if (remap_lcores && args.remap_lcore_ids != (void *)1) {
diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h
index 4decc26d2c..6894bbf9d5 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -57,6 +57,16 @@ struct hugepage_file_discipline {
bool unlink_existing;
};
+/**
+ * A plugin path provided by the user via -d, staged during arg parsing.
+ * Lives in user_cfg->plugin_list; consumed by eal_plugins_init().
+ */
+struct eal_plugin_path {
+ TAILQ_ENTRY(eal_plugin_path) next;
+ char name[PATH_MAX];
+};
+TAILQ_HEAD(eal_plugin_path_list, eal_plugin_path);
+
/**
* A single device option (-a/-b/--vdev) staged during arg parsing.
* Lives in user_cfg->devopt_list; drained by eal_option_device_parse().
@@ -74,6 +84,7 @@ TAILQ_HEAD(eal_devopt_list, device_option);
*/
struct eal_user_cfg {
struct eal_devopt_list devopt_list; /**< staged device options (-a/-b/--vdev) */
+ struct eal_plugin_path_list plugin_list; /**< user-provided plugin paths (-d) */
size_t memory; /**< amount of asked memory */
size_t huge_worker_stack_size; /**< worker thread stack size */
enum rte_proc_type_t process_type; /**< requested process type */
@@ -148,6 +159,16 @@ struct lcore_cfg {
volatile RTE_ATOMIC(enum rte_lcore_state_t) state; /**< lcore state */
};
+/**
+ * A plugin loaded by EAL, including directory-expanded entries.
+ */
+struct shared_driver {
+ TAILQ_ENTRY(shared_driver) next;
+ char name[PATH_MAX];
+ void *lib_handle;
+};
+TAILQ_HEAD(eal_solib_list, shared_driver);
+
/**
* Internal EAL runtime state
* May be modified at runtime, so access must be protected by locks or atomic types
@@ -163,6 +184,7 @@ struct eal_runtime_state {
uint32_t lcore_count; /**< Number of active lcore IDs (role != ROLE_OFF). */
struct lcore_cfg lcore_cfg[RTE_MAX_LCORE];
struct rte_mem_config *mem_config; /**< pointer to memory config (in shared memory) */
+ struct eal_solib_list loaded_plugins; /**< all plugins loaded by eal_plugins_init() */
};
struct eal_user_cfg *eal_get_user_configuration(void);
--
2.51.0
More information about the dev
mailing list