[dpdk-dev] [PATCH v4 3/5] eal: prevent secondary process init while sending messages
Anatoly Burakov
anatoly.burakov at intel.com
Fri Mar 2 16:14:10 CET 2018
Currently, it is possible to spin up a secondary process while
either sendmsg or request is in progress. Fix this by adding
directory locks during init, sendmsg and requests.
Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
---
Notes:
v4: fixed resource leaks and added support for init files
introduced in v4 series
v4: fix resource leaks, also lock when removing init file
v3: no changes
v2: no changes
lib/librte_eal/common/eal_common_proc.c | 81 +++++++++++++++++++++++++++++++--
1 file changed, 77 insertions(+), 4 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index 4d227fe..94672ba 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -436,10 +436,30 @@ int
rte_mp_channel_set_ready(void)
{
char path[PATH_MAX] = {0};
+ int dir_fd, ret;
+
+ /* lock the directory */
+ dir_fd = open(mp_dir_path, O_RDONLY);
+ if (dir_fd < 0) {
+ RTE_LOG(ERR, EAL, "failed to open %s: %s\n",
+ mp_dir_path, strerror(errno));
+ return -1;
+ }
+ if (flock(dir_fd, LOCK_EX)) {
+ RTE_LOG(ERR, EAL, "failed to lock %s: %s\n",
+ mp_dir_path, strerror(errno));
+ close(dir_fd);
+ return -1;
+ }
create_initfile_path(process_peer_name, path, PATH_MAX);
- return unlink(path);
+ ret = unlink(path);
+
+ flock(dir_fd, LOCK_UN);
+ close(dir_fd);
+
+ return ret;
}
int
@@ -447,6 +467,7 @@ rte_mp_channel_init(void)
{
char thread_name[RTE_MAX_THREAD_NAME_LEN];
char *path;
+ int dir_fd;
pthread_t tid;
snprintf(mp_filter, PATH_MAX, ".%s_unix_*",
@@ -456,19 +477,38 @@ rte_mp_channel_init(void)
snprintf(mp_dir_path, PATH_MAX, "%s", dirname(path));
free(path);
+ /* lock the directory */
+ dir_fd = open(mp_dir_path, O_RDONLY);
+ if (dir_fd < 0) {
+ RTE_LOG(ERR, EAL, "failed to open %s: %s\n",
+ mp_dir_path, strerror(errno));
+ return -1;
+ }
+
+ if (flock(dir_fd, LOCK_EX)) {
+ RTE_LOG(ERR, EAL, "failed to lock %s: %s\n",
+ mp_dir_path, strerror(errno));
+ close(dir_fd);
+ return -1;
+ }
+
if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
unlink_sockets(mp_filter)) {
RTE_LOG(ERR, EAL, "failed to unlink mp sockets\n");
+ close(dir_fd);
return -1;
}
- if (open_socket_fd() < 0)
+ if (open_socket_fd() < 0) {
+ close(dir_fd);
return -1;
+ }
if (pthread_create(&tid, NULL, mp_handle, NULL) < 0) {
RTE_LOG(ERR, EAL, "failed to create mp thead: %s\n",
strerror(errno));
close(mp_fd);
+ close(dir_fd);
mp_fd = -1;
return -1;
}
@@ -476,6 +516,11 @@ rte_mp_channel_init(void)
/* try best to set thread name */
snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "rte_mp_handle");
rte_thread_setname(tid, thread_name);
+
+ /* unlock the directory */
+ flock(dir_fd, LOCK_UN);
+ close(dir_fd);
+
return 0;
}
@@ -551,7 +596,7 @@ send_msg(const char *dst_path, struct rte_mp_msg *msg, int type)
static int
mp_send(struct rte_mp_msg *msg, const char *peer, int type)
{
- int ret = 0;
+ int dir_fd, ret = 0;
DIR *mp_dir;
struct dirent *ent;
@@ -573,6 +618,17 @@ mp_send(struct rte_mp_msg *msg, const char *peer, int type)
rte_errno = errno;
return -1;
}
+
+ dir_fd = dirfd(mp_dir);
+ /* lock the directory to prevent processes spinning up while we send */
+ if (flock(dir_fd, LOCK_EX)) {
+ RTE_LOG(ERR, EAL, "Unable to lock directory %s\n",
+ mp_dir_path);
+ rte_errno = errno;
+ closedir(mp_dir);
+ return -1;
+ }
+
while ((ent = readdir(mp_dir))) {
char path[PATH_MAX];
const char *peer_name;
@@ -592,7 +648,10 @@ mp_send(struct rte_mp_msg *msg, const char *peer, int type)
else if (ready > 0)
ret = send_msg(path, msg, type);
}
+ /* unlock the dir */
+ flock(dir_fd, LOCK_UN);
+ /* dir_fd automatically closed on closedir */
closedir(mp_dir);
return ret;
}
@@ -713,7 +772,7 @@ int __rte_experimental
rte_mp_request(struct rte_mp_msg *req, struct rte_mp_reply *reply,
const struct timespec *ts)
{
- int ret = 0;
+ int dir_fd, ret = 0;
DIR *mp_dir;
struct dirent *ent;
struct timeval now;
@@ -748,6 +807,17 @@ rte_mp_request(struct rte_mp_msg *req, struct rte_mp_reply *reply,
rte_errno = errno;
return -1;
}
+
+ dir_fd = dirfd(mp_dir);
+ /* lock the directory to prevent processes spinning up while we send */
+ if (flock(dir_fd, LOCK_EX)) {
+ RTE_LOG(ERR, EAL, "Unable to lock directory %s\n",
+ mp_dir_path);
+ closedir(mp_dir);
+ rte_errno = errno;
+ return -1;
+ }
+
while ((ent = readdir(mp_dir))) {
const char *peer_name;
char path[PATH_MAX];
@@ -772,7 +842,10 @@ rte_mp_request(struct rte_mp_msg *req, struct rte_mp_reply *reply,
if (mp_request_one(path, req, reply, &end))
ret = -1;
}
+ /* unlock the directory */
+ flock(dir_fd, LOCK_UN);
+ /* dir_fd automatically closed on closedir */
closedir(mp_dir);
return ret;
}
--
2.7.4
More information about the dev
mailing list