EAL API and common code
F: lib/librte_eal/common/
+F: lib/librte_eal/unix/
F: lib/librte_eal/include/
F: lib/librte_eal/rte_eal_version.map
F: doc/guides/prog_guide/env_abstraction_layer.rst
#include <sys/mman.h>
#include <stdint.h>
#include <errno.h>
-#include <sys/file.h>
#include <string.h>
+#include <unistd.h>
#include <rte_common.h>
#include <rte_log.h>
char path[PATH_MAX];
void *map_addr;
- if (ftruncate(fd, len)) {
+ if (eal_file_truncate(fd, len)) {
RTE_LOG(ERR, EAL, "Cannot truncate %s\n", path);
- /* pass errno up the chain */
- rte_errno = errno;
return -1;
}
* and see if we succeed. If we don't, someone else is using it
* already.
*/
- fd = open(path, O_CREAT | O_RDWR, 0600);
+ fd = eal_file_open(path, EAL_OPEN_CREATE | EAL_OPEN_READWRITE);
if (fd < 0) {
RTE_LOG(DEBUG, EAL, "%s(): couldn't open %s: %s\n",
- __func__, path, strerror(errno));
- rte_errno = errno;
+ __func__, path, rte_strerror(rte_errno));
goto fail;
- } else if (flock(fd, LOCK_EX | LOCK_NB)) {
+ } else if (eal_file_lock(
+ fd, EAL_FLOCK_EXCLUSIVE, EAL_FLOCK_RETURN)) {
RTE_LOG(DEBUG, EAL, "%s(): couldn't lock %s: %s\n",
- __func__, path, strerror(errno));
+ __func__, path, rte_strerror(rte_errno));
rte_errno = EBUSY;
goto fail;
}
* still attach to it, but no other process could reinitialize
* it.
*/
- if (flock(fd, LOCK_SH | LOCK_NB)) {
- rte_errno = errno;
+ if (eal_file_lock(fd, EAL_FLOCK_SHARED, EAL_FLOCK_RETURN))
goto fail;
- }
if (resize_and_map(fd, data, mmap_len))
goto fail;
eal_get_fbarray_path(path, sizeof(path), arr->name);
- fd = open(path, O_RDWR);
+ fd = eal_file_open(path, EAL_OPEN_READWRITE);
if (fd < 0) {
- rte_errno = errno;
goto fail;
}
/* lock the file, to let others know we're using it */
- if (flock(fd, LOCK_SH | LOCK_NB)) {
- rte_errno = errno;
+ if (eal_file_lock(fd, EAL_FLOCK_SHARED, EAL_FLOCK_RETURN))
goto fail;
- }
if (resize_and_map(fd, data, mmap_len))
goto fail;
* has been detached by all other processes
*/
fd = tmp->fd;
- if (flock(fd, LOCK_EX | LOCK_NB)) {
+ if (eal_file_lock(fd, EAL_FLOCK_EXCLUSIVE, EAL_FLOCK_RETURN)) {
RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n");
rte_errno = EBUSY;
ret = -1;
* we're still holding an exclusive lock, so drop it to
* shared.
*/
- flock(fd, LOCK_SH | LOCK_NB);
+ eal_file_lock(fd, EAL_FLOCK_SHARED, EAL_FLOCK_RETURN);
ret = -1;
goto out;
void eal_free_no_trace(void *addr);
+/** Options for eal_file_open(). */
+enum eal_open_flags {
+ /** Open file for reading. */
+ EAL_OPEN_READONLY = 0x00,
+ /** Open file for reading and writing. */
+ EAL_OPEN_READWRITE = 0x02,
+ /**
+ * Create the file if it doesn't exist.
+ * New files are only accessible to the owner (0600 equivalent).
+ */
+ EAL_OPEN_CREATE = 0x04
+};
+
+/**
+ * Open or create a file.
+ *
+ * @param path
+ * Path to the file.
+ * @param flags
+ * A combination of eal_open_flags controlling operation and FD behavior.
+ * @return
+ * Open file descriptor on success, (-1) on failure and rte_errno is set.
+ */
+int
+eal_file_open(const char *path, int flags);
+
+/** File locking operation. */
+enum eal_flock_op {
+ EAL_FLOCK_SHARED, /**< Acquire a shared lock. */
+ EAL_FLOCK_EXCLUSIVE, /**< Acquire an exclusive lock. */
+ EAL_FLOCK_UNLOCK /**< Release a previously taken lock. */
+};
+
+/** Behavior on file locking conflict. */
+enum eal_flock_mode {
+ EAL_FLOCK_WAIT, /**< Wait until the file gets unlocked to lock it. */
+ EAL_FLOCK_RETURN /**< Return immediately if the file is locked. */
+};
+
+/**
+ * Lock or unlock the file.
+ *
+ * On failure @code rte_errno @endcode is set to the error code
+ * specified by POSIX flock(3) description.
+ *
+ * @param fd
+ * Opened file descriptor.
+ * @param op
+ * Operation to perform.
+ * @param mode
+ * Behavior on conflict.
+ * @return
+ * 0 on success, (-1) on failure.
+ */
+int
+eal_file_lock(int fd, enum eal_flock_op op, enum eal_flock_mode mode);
+
+/**
+ * Truncate or extend the file to the specified size.
+ *
+ * On failure @code rte_errno @endcode is set to the error code
+ * specified by POSIX ftruncate(3) description.
+ *
+ * @param fd
+ * Opened file descriptor.
+ * @param size
+ * Desired file size.
+ * @return
+ * 0 on success, (-1) on failure.
+ */
+int
+eal_file_truncate(int fd, ssize_t size);
+
#endif /* _EAL_PRIVATE_H_ */
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
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_file.c
+
# from arch dir
SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_cpuflags.c
SRCS-$(CONFIG_RTE_EXEC_ENV_FREEBSD) += rte_hypervisor.c
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
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_file.c
+
# from arch dir
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_cpuflags.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUX) += rte_hypervisor.c
subdir('common')
+if not is_windows
+ subdir('unix')
+endif
+
dpdk_conf.set('RTE_EXEC_ENV_' + exec_env.to_upper(), 1)
subdir(exec_env)
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Dmitry Kozlyuk
+ */
+
+#include <sys/file.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <rte_errno.h>
+
+#include "eal_private.h"
+
+int
+eal_file_open(const char *path, int flags)
+{
+ static const int MODE_MASK = EAL_OPEN_READONLY | EAL_OPEN_READWRITE;
+
+ int ret, sys_flags;
+
+ switch (flags & MODE_MASK) {
+ case EAL_OPEN_READONLY:
+ sys_flags = O_RDONLY;
+ break;
+ case EAL_OPEN_READWRITE:
+ sys_flags = O_RDWR;
+ break;
+ default:
+ rte_errno = ENOTSUP;
+ return -1;
+ }
+
+ if (flags & EAL_OPEN_CREATE)
+ sys_flags |= O_CREAT;
+
+ ret = open(path, sys_flags, 0600);
+ if (ret < 0)
+ rte_errno = errno;
+
+ return ret;
+}
+
+int
+eal_file_truncate(int fd, ssize_t size)
+{
+ int ret;
+
+ ret = ftruncate(fd, size);
+ if (ret)
+ rte_errno = errno;
+
+ return ret;
+}
+
+int
+eal_file_lock(int fd, enum eal_flock_op op, enum eal_flock_mode mode)
+{
+ int sys_flags = 0;
+ int ret;
+
+ if (mode == EAL_FLOCK_RETURN)
+ sys_flags |= LOCK_NB;
+
+ switch (op) {
+ case EAL_FLOCK_EXCLUSIVE:
+ sys_flags |= LOCK_EX;
+ break;
+ case EAL_FLOCK_SHARED:
+ sys_flags |= LOCK_SH;
+ break;
+ case EAL_FLOCK_UNLOCK:
+ sys_flags |= LOCK_UN;
+ break;
+ }
+
+ ret = flock(fd, sys_flags);
+ if (ret)
+ rte_errno = errno;
+
+ return ret;
+}
--- /dev/null
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020 Dmitry Kozlyuk
+
+sources += files(
+ 'eal_file.c',
+)