From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 921D4A0093; Mon, 15 Jun 2020 02:44:23 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4D8D654AE; Mon, 15 Jun 2020 02:44:19 +0200 (CEST) Received: from mail-lj1-f196.google.com (mail-lj1-f196.google.com [209.85.208.196]) by dpdk.org (Postfix) with ESMTP id 4F9B74C8B for ; Mon, 15 Jun 2020 02:44:05 +0200 (CEST) Received: by mail-lj1-f196.google.com with SMTP id z9so17061925ljh.13 for ; Sun, 14 Jun 2020 17:44:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8yGhgO/ojOR0fWqWSA0E+p49S2INPA9kRyVnNjrvaEs=; b=pyIqicyLfr8qP6vgptAyuJQcPN8HsFJDTWB+vcSoh66olHeuZZP7Y8F/5ZAiJxa3wL qUFdCkcetrzICOSF35mjo0ZnXtgO0I+siep96QW5npKdKi13d4Vq/jjD5iFpissVV23d wGB/PNDKO0mw0IT5IZhx6FDVi549PeMRWNuq+vFg/hPDjj41v5kzl8bbLaF8W0cc2WGG xSh4V0FXxD/B8NuD92yE7A+WmBXX9nHWVvxqQyH8XtAAJiTVZSodoqiJDY6tK4ABAgdB PvWCy9NSW7EoZhXxAq62CRj8Np4vXZDX9AzaPOIv43AtnoK+mYlFjd/iNFVzz9fxR7TC OIYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8yGhgO/ojOR0fWqWSA0E+p49S2INPA9kRyVnNjrvaEs=; b=l9WPTSWGEfJ19a6oWf5GRg7c385fKUtxIH37eTJ1IhqfUM/wqua7I+cgWHNrwGSqmY ZU7kZmrPiTrbhFAWFiRAxFs1yD4DCcNCZaTaK4nLcruRlRN94KkA6NbqgHx/USNVqrVG Ng1fQbKA87V9w9vorJicdS/QglqZlP2oKXWepYJ9eeVNml4MtrobaC989U5JL+d0zh8T 6QnnaASrvLVYy0ME6Z5+B+qpwxXpg9Zsv1oi+vGYUaWoucSmhq26neaNfISZInKYMsxm 1WmdGpe31V4drMexZ6iPSpAopY5Z+X+5+pxRfok2ZceUDijrJh4OoZR7AC5KgCnFwlV9 c5Qw== X-Gm-Message-State: AOAM532LqimqTciQZjhnXN+FHHmgAJiwXbxnOJGHcKPFPCYOtyraEZJl dFqPLBleolbmJhycuYsK8Ftz5qzGpPKCfA== X-Google-Smtp-Source: ABdhPJwot3QEMcN9GMszDyrMwm9akPHcFfxFpRHgw+st+1WYt41Al+AOY1yRX1jqSATsBa/Xt9+ttw== X-Received: by 2002:a05:651c:2cf:: with SMTP id f15mr11450324ljo.105.1592181844610; Sun, 14 Jun 2020 17:44:04 -0700 (PDT) Received: from localhost.localdomain (broadband-37-110-65-23.ip.moscow.rt.ru. [37.110.65.23]) by smtp.gmail.com with ESMTPSA id f19sm4176342lfk.24.2020.06.14.17.44.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 14 Jun 2020 17:44:03 -0700 (PDT) From: Dmitry Kozlyuk To: dev@dpdk.org Cc: Dmitry Malloy , Narcisa Ana Maria Vasile , Fady Bader , Tal Shnaiderman , Dmitry Kozlyuk , Thomas Monjalon , Anatoly Burakov , Bruce Richardson Date: Mon, 15 Jun 2020 03:43:44 +0300 Message-Id: <20200615004354.14380-3-dmitry.kozliuk@gmail.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200615004354.14380-1-dmitry.kozliuk@gmail.com> References: <20200610142730.31376-1-dmitry.kozliuk@gmail.com> <20200615004354.14380-1-dmitry.kozliuk@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v9 02/12] eal: introduce internal wrappers for file operations X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Introduce OS-independent wrappers in order to support common EAL code on Unix and Windows: * eal_file_open: open or create a file. * eal_file_lock: lock or unlock an open file. * eal_file_truncate: enforce a given size for an open file. Implementation for Linux and FreeBSD is placed in "unix" subdirectory, which is intended for common code between the two. These thin wrappers require no special maintenance. Common code supporting multi-process doesn't use the new wrappers, because it is inherently Unix-specific and would impose excessive requirements on the wrappers. Signed-off-by: Dmitry Kozlyuk --- MAINTAINERS | 1 + lib/librte_eal/common/eal_common_fbarray.c | 31 ++++----- lib/librte_eal/common/eal_private.h | 73 ++++++++++++++++++++ lib/librte_eal/freebsd/Makefile | 4 ++ lib/librte_eal/linux/Makefile | 4 ++ lib/librte_eal/meson.build | 4 ++ lib/librte_eal/unix/eal_file.c | 80 ++++++++++++++++++++++ lib/librte_eal/unix/meson.build | 6 ++ 8 files changed, 184 insertions(+), 19 deletions(-) create mode 100644 lib/librte_eal/unix/eal_file.c create mode 100644 lib/librte_eal/unix/meson.build diff --git a/MAINTAINERS b/MAINTAINERS index e739b87ea..4d162efd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -170,6 +170,7 @@ EAL API and common code F: lib/librte_eal/common/ F: lib/librte_eal/include/ F: lib/librte_eal/rte_eal_version.map +F: lib/librte_eal/unix/ F: doc/guides/prog_guide/env_abstraction_layer.rst F: app/test/test_alarm.c F: app/test/test_atomic.c diff --git a/lib/librte_eal/common/eal_common_fbarray.c b/lib/librte_eal/common/eal_common_fbarray.c index 4f8f1af73..c52ddb967 100644 --- a/lib/librte_eal/common/eal_common_fbarray.c +++ b/lib/librte_eal/common/eal_common_fbarray.c @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include #include #include @@ -85,10 +85,8 @@ resize_and_map(int fd, void *addr, size_t len) 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; } @@ -772,15 +770,15 @@ rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len, * 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; } @@ -789,10 +787,8 @@ rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len, * 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; @@ -888,17 +884,14 @@ rte_fbarray_attach(struct rte_fbarray *arr) 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; @@ -1025,7 +1018,7 @@ rte_fbarray_destroy(struct rte_fbarray *arr) * 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; @@ -1042,7 +1035,7 @@ rte_fbarray_destroy(struct rte_fbarray *arr) * 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; diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 869ce183a..6733a2321 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -420,4 +420,77 @@ eal_malloc_no_trace(const char *type, size_t size, unsigned int align); 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_ */ diff --git a/lib/librte_eal/freebsd/Makefile b/lib/librte_eal/freebsd/Makefile index af95386d4..0f8741d96 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_file.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 48cc34844..331489f99 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_file.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 e301f4558..8d492897d 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_file.c b/lib/librte_eal/unix/eal_file.c new file mode 100644 index 000000000..1b26475ba --- /dev/null +++ b/lib/librte_eal/unix/eal_file.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Dmitry Kozlyuk + */ + +#include +#include +#include + +#include + +#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; +} diff --git a/lib/librte_eal/unix/meson.build b/lib/librte_eal/unix/meson.build new file mode 100644 index 000000000..21029ba1a --- /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_file.c', +) -- 2.25.4