Add functions for handling directories in a platform-independent way: * eal_persistent_data_path() * eal_dir_create()
Currently, only tracing requires this API for its common code. Signed-off-by: Dmitry Kozlyuk <dmitry.kozl...@gmail.com> --- .../common/eal_common_trace_utils.c | 26 +++------- lib/librte_eal/common/eal_filesystem.h | 30 ++++++++++- lib/librte_eal/freebsd/Makefile | 4 ++ lib/librte_eal/linux/Makefile | 4 ++ lib/librte_eal/meson.build | 4 ++ lib/librte_eal/unix/eal_unix_filesystem.c | 51 +++++++++++++++++++ lib/librte_eal/unix/meson.build | 6 +++ 7 files changed, 105 insertions(+), 20 deletions(-) create mode 100644 lib/librte_eal/unix/eal_unix_filesystem.c create mode 100644 lib/librte_eal/unix/meson.build diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c index fce8892c3..78df3b41e 100644 --- a/lib/librte_eal/common/eal_common_trace_utils.c +++ b/lib/librte_eal/common/eal_common_trace_utils.c @@ -3,8 +3,6 @@ */ #include <fnmatch.h> -#include <pwd.h> -#include <sys/stat.h> #include <time.h> #include <rte_common.h> @@ -321,22 +319,14 @@ trace_dir_default_path_get(char *dir_path) { struct trace *trace = trace_obj_get(); uint32_t size = sizeof(trace->dir); - struct passwd *pwd; - char *home_dir; - - /* First check for shell environment variable */ - home_dir = getenv("HOME"); - if (home_dir == NULL) { - /* Fallback to password file entry */ - pwd = getpwuid(getuid()); - if (pwd == NULL) - return -EINVAL; - - home_dir = pwd->pw_dir; - } + const char *perm_dir; + + perm_dir = eal_permanent_data_path(); + if (perm_dir == NULL) + return -EINVAL; /* Append dpdk-traces to directory */ - if (snprintf(dir_path, size, "%s/dpdk-traces/", home_dir) < 0) + if (snprintf(dir_path, size, "%s/dpdk-traces/", perm_dir) < 0) return -ENAMETOOLONG; return 0; @@ -371,7 +361,7 @@ trace_mkdir(void) } /* Create the path if it t exist, no "mkdir -p" available here */ - rc = mkdir(trace->dir, 0700); + rc = eal_dir_create(trace->dir); if (rc < 0 && errno != EEXIST) { trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno)); rte_errno = errno; @@ -385,7 +375,7 @@ trace_mkdir(void) if (rc < 0) return rc; - rc = mkdir(trace->dir, 0700); + rc = eal_dir_create(trace->dir); if (rc < 0) { trace_err("mkdir %s failed [%s]", trace->dir, strerror(errno)); rte_errno = errno; diff --git a/lib/librte_eal/common/eal_filesystem.h b/lib/librte_eal/common/eal_filesystem.h index 5d21f07c2..77fe3be69 100644 --- a/lib/librte_eal/common/eal_filesystem.h +++ b/lib/librte_eal/common/eal_filesystem.h @@ -4,8 +4,8 @@ /** * @file - * Stores functions and path defines for files and directories - * on the filesystem for Linux, that are used by the Linux EAL. + * Stores functions and path defines for files and directories used by DPDK. + * Parts of this file are Unix-specific for historical reasons. */ #ifndef EAL_FILESYSTEM_H @@ -28,6 +28,32 @@ eal_create_runtime_dir(void); int eal_clean_runtime_dir(void); +/** + * Get absolute path to the directory where permanent data can be stored. + * + * @return + * Statically allocated string on success, NULL on failure. + */ +const char * +eal_permanent_data_path(void); + +/** + * Create a directory accessible to the current user only. + * + * This function does not create intermediate directories, + * thus only the last path component may be nonexistent. + * + * This function succeeds if path already exists and is a directory. + * + * Platform-independent code should use forward slash as path separator. + * + * @param path + * Path to be created. + * @return + * 0 on success, (-1) on failure and rte_errno is set. + */ +int eal_dir_create(const char *path); + /** Function to return hugefile prefix that's currently set up */ const char * eal_get_hugefile_prefix(void); diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index a8400f20a..5170a85ab 100644 --- a/lib/librte_eal/freebsd/Makefile +++ b/lib/librte_eal/freebsd/Makefile @@ -7,6 +7,7 @@ LIB = librte_eal.a ARCH_DIR ?= $(RTE_ARCH) VPATH += $(RTE_SDK)/lib/librte_eal/$(ARCH_DIR) +VPATH += $(RTE_SDK)/lib/librte_eal/unix VPATH += $(RTE_SDK)/lib/librte_eal/common CFLAGS += -I$(SRCDIR)/include @@ -74,6 +75,9 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_service.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_random.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_reciprocal.c +# from unix dir +SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += eal_unix_filesystem.c + # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_cpuflags.c SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_hypervisor.c diff --git a/lib/librte_eal/linux/Makefile b/lib/librte_eal/linux/Makefile index a77eb1757..bdbcb9801 100644 --- a/lib/librte_eal/linux/Makefile +++ b/lib/librte_eal/linux/Makefile @@ -7,6 +7,7 @@ LIB = librte_eal.a ARCH_DIR ?= $(RTE_ARCH) VPATH += $(RTE_SDK)/lib/librte_eal/$(ARCH_DIR) +VPATH += $(RTE_SDK)/lib/librte_eal/unix VPATH += $(RTE_SDK)/lib/librte_eal/common CFLAGS += -I$(SRCDIR)/include @@ -81,6 +82,9 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_service.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_random.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_reciprocal.c +# from unix dir +SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += eal_unix_filesystem.c + # from arch dir SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_cpuflags.c SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_hypervisor.c diff --git a/lib/librte_eal/meson.build b/lib/librte_eal/meson.build index 0267c3b9d..98c97dd07 100644 --- a/lib/librte_eal/meson.build +++ b/lib/librte_eal/meson.build @@ -6,6 +6,10 @@ subdir('include') subdir('common') +if not is_windows + subdir('unix') +endif + dpdk_conf.set('RTE_EXEC_ENV_' + exec_env.to_upper(), 1) subdir(exec_env) diff --git a/lib/librte_eal/unix/eal_unix_filesystem.c b/lib/librte_eal/unix/eal_unix_filesystem.c new file mode 100644 index 000000000..f5a64eecc --- /dev/null +++ b/lib/librte_eal/unix/eal_unix_filesystem.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2020 Dmitry Kozlyuk + */ + +#include <stdlib.h> + +#include <pwd.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <rte_errno.h> + +#include <eal_filesystem.h> + +const char * +eal_permanent_data_path(void) +{ + static char path[PATH_MAX]; /* static so auto-zeroed */ + + const char *home_dir; + struct passwd *pwd; + + if (path[0] != '\0') + return path; + + /* First check for shell environment variable */ + home_dir = getenv("HOME"); + if (home_dir == NULL) { + /* Fallback to password file entry */ + pwd = getpwuid(getuid()); + if (pwd == NULL) + return NULL; + + home_dir = pwd->pw_dir; + } + + if (strlen(home_dir) >= sizeof(path)) + return NULL; + + strncpy(path, home_dir, sizeof(path)); + return path; +} + +int +eal_dir_create(const char *path) +{ + int ret = mkdir(path, 0700); + if (ret) + rte_errno = errno; + return ret; +} diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build new file mode 100644 index 000000000..fafa41685 --- /dev/null +++ b/lib/librte_eal/unix/meson.build @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020 Dmitry Kozlyuk + +sources += files( + 'eal_unix_filesystem.c', +) -- 2.25.1