From 6606dc722c67da3e62a2eb578fea1d70ae3ee51c Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 2 Nov 2016 03:41:57 +0300 Subject: [PATCH] scm: Switch compel fd plugin onto common Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- compel/plugins/fds/fds.c | 18 ++-- compel/plugins/include/uapi/plugin-fds.h | 18 +--- compel/src/shared/fds.c | 113 ----------------------- 3 files changed, 9 insertions(+), 140 deletions(-) delete mode 100644 compel/src/shared/fds.c diff --git a/compel/plugins/fds/fds.c b/compel/plugins/fds/fds.c index a7966e5de..a19c66287 100644 --- a/compel/plugins/fds/fds.c +++ b/compel/plugins/fds/fds.c @@ -1,3 +1,5 @@ +#include + #include "uapi/plugins.h" #include "uapi/std/syscall.h" @@ -5,22 +7,14 @@ #include "uapi/plugin-fds.h" #include "std-priv.h" +#include "log.h" #include "common/compiler.h" +#include "common/bug.h" #define __sys(foo) sys_##foo -#define __std(foo) std_##foo +#define __memcpy std_memcpy -#include "../../src/shared/fds.c" - -int fds_send(int *fds, int nr_fds) -{ - return fds_send_via(std_ctl_sock(), fds, nr_fds); -} - -int fds_recv(int *fds, int nr_fds) -{ - return fds_recv_via(std_ctl_sock(), fds, nr_fds); -} +#include "common/scm-code.c" PLUGIN_REGISTER_DUMMY(fds) diff --git a/compel/plugins/include/uapi/plugin-fds.h b/compel/plugins/include/uapi/plugin-fds.h index 96991eaa4..0ce83afbd 100644 --- a/compel/plugins/include/uapi/plugin-fds.h +++ b/compel/plugins/include/uapi/plugin-fds.h @@ -5,23 +5,11 @@ #ifndef __COMPEL_PLUGIN_FDS_H__ #define __COMPEL_PLUGIN_FDS_H__ -extern int fds_send(int *fds, int nr_fds); -extern int fds_recv(int *fds, int nr_fds); +#include "common/scm.h" -static inline int fds_send_one(int fd) +static inline int send_fd(int sock, struct sockaddr_un *saddr, int saddr_len, int fd) { - return fds_send(&fd, 1); -} - -static inline int fds_recv_one(void) -{ - int fd, ret; - - ret = fds_recv(&fd, 1); - if (ret) - fd = -1; - - return fd; + return send_fds(sock, saddr, saddr_len, &fd, 1, false); } #endif /* __COMPEL_PLUGIN_FDS_H__ */ diff --git a/compel/src/shared/fds.c b/compel/src/shared/fds.c deleted file mode 100644 index 9bf49cbdd..000000000 --- a/compel/src/shared/fds.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include - -/* - * Because of kernel doing kmalloc for user data passed - * in SCM messages, and there is kernel's SCM_MAX_FD as a limit - * for descriptors passed at once we're trying to reduce - * the pressue on kernel memory manager and use predefined - * known to work well size of the message buffer. - */ -#define CR_SCM_MSG_SIZE (1024) -#define CR_SCM_MAX_FD (252) - -struct scm_fdset { - struct msghdr hdr; - struct iovec iov; - char msg_buf[CR_SCM_MSG_SIZE]; - char f; -}; - -static void scm_fdset_init_chunk(struct scm_fdset *fdset, int nr_fds) -{ - struct cmsghdr *cmsg; - - fdset->hdr.msg_controllen = CMSG_LEN(sizeof(int) * nr_fds); - - cmsg = CMSG_FIRSTHDR(&fdset->hdr); - cmsg->cmsg_len = fdset->hdr.msg_controllen; -} - -static int *scm_fdset_init(struct scm_fdset *fdset) -{ - struct cmsghdr *cmsg; - - BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD))); - - fdset->iov.iov_base = &fdset->f; - fdset->iov.iov_len = 1; - - fdset->hdr.msg_iov = &fdset->iov; - fdset->hdr.msg_iovlen = 1; - fdset->hdr.msg_name = NULL; - fdset->hdr.msg_namelen = 0; - - fdset->hdr.msg_control = &fdset->msg_buf; - fdset->hdr.msg_controllen = CMSG_LEN(sizeof(int) * CR_SCM_MAX_FD); - - cmsg = CMSG_FIRSTHDR(&fdset->hdr); - cmsg->cmsg_len = fdset->hdr.msg_controllen; - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - return (int *)CMSG_DATA(cmsg); -} - -int fds_send_via(int sock, int *fds, int nr_fds) -{ - struct scm_fdset fdset; - int i, min_fd, ret; - int *cmsg_data; - - cmsg_data = scm_fdset_init(&fdset); - - for (i = 0; i < nr_fds; i += min_fd) { - min_fd = min(CR_SCM_MAX_FD, nr_fds - i); - scm_fdset_init_chunk(&fdset, min_fd); - __std(memcpy(cmsg_data, &fds[i], sizeof(int) * min_fd)); - ret = __sys(sendmsg(sock, &fdset.hdr, 0)); - if (ret <= 0) - return ret ? : -1; - } - - return 0; -} - -int fds_recv_via(int sock, int *fds, int nr_fds) -{ - struct scm_fdset fdset; - struct cmsghdr *cmsg; - int *cmsg_data; - int ret; - int i, min_fd; - - cmsg_data = scm_fdset_init(&fdset); - for (i = 0; i < nr_fds; i += min_fd) { - min_fd = min(CR_SCM_MAX_FD, nr_fds - i); - scm_fdset_init_chunk(&fdset, min_fd); - - ret = __sys(recvmsg(sock, &fdset.hdr, 0)); - if (ret <= 0) - return ret ? : -1; - - cmsg = CMSG_FIRSTHDR(&fdset.hdr); - if (!cmsg || cmsg->cmsg_type != SCM_RIGHTS) - return -1; - if (fdset.hdr.msg_flags & MSG_CTRUNC) - return -2; - - min_fd = (cmsg->cmsg_len - sizeof(struct cmsghdr)) / sizeof(int); - /* - * In case if kernel screwed the recepient, most probably - * the caller stack frame will be overwriten, just scream - * and exit. - */ - if (unlikely(min_fd > CR_SCM_MAX_FD)) - *(volatile unsigned long *)NULL = 0xdead0000 + __LINE__; - if (unlikely(min_fd <= 0)) - return -1; - __std(memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd)); - } - - return 0; -}