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 <[email protected]> --- 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

