[dpdk-dev] [PATCH v2 2/3] eal: add internal directory management API

Dmitry Kozlyuk dmitry.kozliuk at gmail.com
Sun Apr 26 17:28:17 CEST 2020


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.kozliuk at 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



More information about the dev mailing list