1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2018 Intel Corporation
16 #include <sys/types.h>
17 #include <sys/socket.h>
21 #include <rte_common.h>
22 #include <rte_cycles.h>
24 #include <rte_errno.h>
25 #include <rte_lcore.h>
28 #include "eal_private.h"
29 #include "eal_filesystem.h"
30 #include "eal_internal_cfg.h"
32 static int mp_fd = -1;
33 static char mp_filter[PATH_MAX]; /* Filter for secondary process sockets */
34 static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */
35 static pthread_mutex_t mp_mutex_action = PTHREAD_MUTEX_INITIALIZER;
38 TAILQ_ENTRY(action_entry) next;
39 char action_name[RTE_MP_MAX_NAME_LEN];
43 /** Double linked list of actions. */
44 TAILQ_HEAD(action_entry_list, action_entry);
46 static struct action_entry_list action_entry_list =
47 TAILQ_HEAD_INITIALIZER(action_entry_list);
50 rte_eal_primary_proc_alive(const char *config_file_path)
55 config_fd = open(config_file_path, O_RDONLY);
59 path = eal_runtime_config_path();
60 config_fd = open(path, O_RDONLY);
65 int ret = lockf(config_fd, F_TEST, 0);
71 static struct action_entry *
72 find_action_entry_by_name(const char *name)
74 struct action_entry *entry;
76 TAILQ_FOREACH(entry, &action_entry_list, next) {
77 if (strncmp(entry->action_name, name, RTE_MP_MAX_NAME_LEN) == 0)
85 validate_action_name(const char *name)
88 RTE_LOG(ERR, EAL, "Action name cannot be NULL\n");
92 if (strnlen(name, RTE_MP_MAX_NAME_LEN) == 0) {
93 RTE_LOG(ERR, EAL, "Length of action name is zero\n");
97 if (strnlen(name, RTE_MP_MAX_NAME_LEN) == RTE_MP_MAX_NAME_LEN) {
104 int __rte_experimental
105 rte_mp_action_register(const char *name, rte_mp_t action)
107 struct action_entry *entry;
109 if (validate_action_name(name))
112 entry = malloc(sizeof(struct action_entry));
117 strcpy(entry->action_name, name);
118 entry->action = action;
120 pthread_mutex_lock(&mp_mutex_action);
121 if (find_action_entry_by_name(name) != NULL) {
122 pthread_mutex_unlock(&mp_mutex_action);
127 TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
128 pthread_mutex_unlock(&mp_mutex_action);
132 void __rte_experimental
133 rte_mp_action_unregister(const char *name)
135 struct action_entry *entry;
137 if (validate_action_name(name))
140 pthread_mutex_lock(&mp_mutex_action);
141 entry = find_action_entry_by_name(name);
143 pthread_mutex_unlock(&mp_mutex_action);
146 TAILQ_REMOVE(&action_entry_list, entry, next);
147 pthread_mutex_unlock(&mp_mutex_action);
152 read_msg(struct rte_mp_msg *msg)
157 char control[CMSG_SPACE(sizeof(msg->fds))];
158 struct cmsghdr *cmsg;
159 int buflen = sizeof(*msg) - sizeof(msg->fds);
161 memset(&msgh, 0, sizeof(msgh));
163 iov.iov_len = buflen;
167 msgh.msg_control = control;
168 msgh.msg_controllen = sizeof(control);
170 msglen = recvmsg(mp_fd, &msgh, 0);
172 RTE_LOG(ERR, EAL, "recvmsg failed, %s\n", strerror(errno));
176 if (msglen != buflen || (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC))) {
177 RTE_LOG(ERR, EAL, "truncted msg\n");
181 /* read auxiliary FDs if any */
182 for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
183 cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
184 if ((cmsg->cmsg_level == SOL_SOCKET) &&
185 (cmsg->cmsg_type == SCM_RIGHTS)) {
186 memcpy(msg->fds, CMSG_DATA(cmsg), sizeof(msg->fds));
195 process_msg(struct rte_mp_msg *msg)
197 struct action_entry *entry;
198 rte_mp_t action = NULL;
200 RTE_LOG(DEBUG, EAL, "msg: %s\n", msg->name);
201 pthread_mutex_lock(&mp_mutex_action);
202 entry = find_action_entry_by_name(msg->name);
204 action = entry->action;
205 pthread_mutex_unlock(&mp_mutex_action);
208 RTE_LOG(ERR, EAL, "Cannot find action: %s\n", msg->name);
209 else if (action(msg) < 0)
210 RTE_LOG(ERR, EAL, "Fail to handle message: %s\n", msg->name);
214 mp_handle(void *arg __rte_unused)
216 struct rte_mp_msg msg;
219 if (read_msg(&msg) == 0)
229 struct sockaddr_un un;
230 const char *prefix = eal_mp_socket_path();
232 mp_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
234 RTE_LOG(ERR, EAL, "failed to create unix socket\n");
238 memset(&un, 0, sizeof(un));
239 un.sun_family = AF_UNIX;
240 if (rte_eal_process_type() == RTE_PROC_PRIMARY)
241 snprintf(un.sun_path, sizeof(un.sun_path), "%s", prefix);
243 snprintf(un.sun_path, sizeof(un.sun_path), "%s_%d_%"PRIx64,
244 prefix, getpid(), rte_rdtsc());
246 unlink(un.sun_path); /* May still exist since last run */
247 if (bind(mp_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
248 RTE_LOG(ERR, EAL, "failed to bind %s: %s\n",
249 un.sun_path, strerror(errno));
254 RTE_LOG(INFO, EAL, "Multi-process socket %s\n", un.sun_path);
259 unlink_sockets(const char *filter)
265 mp_dir = opendir(mp_dir_path);
267 RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path);
270 dir_fd = dirfd(mp_dir);
272 while ((ent = readdir(mp_dir))) {
273 if (fnmatch(filter, ent->d_name, 0) == 0)
274 unlinkat(dir_fd, ent->d_name, 0);
282 unlink_socket_by_path(const char *path)
285 char *fullpath = strdup(path);
289 filename = basename(fullpath);
290 unlink_sockets(filename);
292 RTE_LOG(INFO, EAL, "Remove socket %s\n", path);
296 rte_mp_channel_init(void)
298 char thread_name[RTE_MAX_THREAD_NAME_LEN];
302 snprintf(mp_filter, PATH_MAX, ".%s_unix_*",
303 internal_config.hugefile_prefix);
305 path = strdup(eal_mp_socket_path());
306 snprintf(mp_dir_path, PATH_MAX, "%s", dirname(path));
309 if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
310 unlink_sockets(mp_filter)) {
311 RTE_LOG(ERR, EAL, "failed to unlink mp sockets\n");
315 if (open_socket_fd() < 0)
318 if (pthread_create(&tid, NULL, mp_handle, NULL) < 0) {
319 RTE_LOG(ERR, EAL, "failed to create mp thead: %s\n",
326 /* try best to set thread name */
327 snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "rte_mp_handle");
328 rte_thread_setname(tid, thread_name);
333 * Return -1, as fail to send message and it's caused by the local side.
334 * Return 0, as fail to send message and it's caused by the remote side.
335 * Return 1, as succeed to send message.
339 send_msg(const char *dst_path, struct rte_mp_msg *msg)
344 struct cmsghdr *cmsg;
345 struct sockaddr_un dst;
346 int fd_size = msg->num_fds * sizeof(int);
347 char control[CMSG_SPACE(fd_size)];
349 memset(&dst, 0, sizeof(dst));
350 dst.sun_family = AF_UNIX;
351 snprintf(dst.sun_path, sizeof(dst.sun_path), "%s", dst_path);
353 memset(&msgh, 0, sizeof(msgh));
354 memset(control, 0, sizeof(control));
357 iov.iov_len = sizeof(*msg) - sizeof(msg->fds);
359 msgh.msg_name = &dst;
360 msgh.msg_namelen = sizeof(dst);
363 msgh.msg_control = control;
364 msgh.msg_controllen = sizeof(control);
366 cmsg = CMSG_FIRSTHDR(&msgh);
367 cmsg->cmsg_len = CMSG_LEN(fd_size);
368 cmsg->cmsg_level = SOL_SOCKET;
369 cmsg->cmsg_type = SCM_RIGHTS;
370 memcpy(CMSG_DATA(cmsg), msg->fds, fd_size);
373 snd = sendmsg(mp_fd, &msgh, 0);
374 } while (snd < 0 && errno == EINTR);
378 /* Check if it caused by peer process exits */
379 if (errno == -ECONNREFUSED) {
380 /* We don't unlink the primary's socket here */
381 if (rte_eal_process_type() == RTE_PROC_PRIMARY)
382 unlink_socket_by_path(dst_path);
385 if (errno == -ENOBUFS) {
386 RTE_LOG(ERR, EAL, "Peer cannot receive message %s\n",
390 RTE_LOG(ERR, EAL, "failed to send to (%s) due to %s\n",
391 dst_path, strerror(errno));
399 mp_send(struct rte_mp_msg *msg)
405 if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
406 if (send_msg(eal_mp_socket_path(), msg) < 0)
412 /* broadcast to all secondary processes */
413 mp_dir = opendir(mp_dir_path);
415 RTE_LOG(ERR, EAL, "Unable to open directory %s\n",
420 while ((ent = readdir(mp_dir))) {
421 if (fnmatch(mp_filter, ent->d_name, 0) != 0)
424 if (send_msg(ent->d_name, msg) < 0)
433 check_input(const struct rte_mp_msg *msg)
436 RTE_LOG(ERR, EAL, "Msg cannot be NULL\n");
441 if (validate_action_name(msg->name))
444 if (msg->len_param > RTE_MP_MAX_PARAM_LEN) {
445 RTE_LOG(ERR, EAL, "Message data is too long\n");
450 if (msg->num_fds > RTE_MP_MAX_FD_NUM) {
451 RTE_LOG(ERR, EAL, "Cannot send more than %d FDs\n",
460 int __rte_experimental
461 rte_mp_sendmsg(struct rte_mp_msg *msg)
463 if (!check_input(msg))
466 RTE_LOG(DEBUG, EAL, "sendmsg: %s\n", msg->name);