Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@virtuozzo.com>2016-11-22 20:03:00 +0300
committerPavel Emelyanov <xemul@virtuozzo.com>2016-12-12 16:22:19 +0300
commit60738eaa7861004f00552f8b29bf3652d5f96adf (patch)
treef4b4e2f5b4ec2be6783e719b9b9068554ff16935 /include
parented4a4b75078aa89be77aad43948e310c6329fc5e (diff)
files: Rework send/recv-fds to be more generic
Remove getting opts from descriptors out from scm engine, this stuff is pure criu thing, so make it collect the data. The tricky change here is that parasite code needs memory to keep fd_opts on. The memory is taken from parasite args region, which is now bigger than it used to be. But that's not a big deal, as previously this space was allocated on the parasite stack (!, but with smaller chunks). On the other hand, now we have one memcpy less, as opts are put directly into the destination buffer. travis-ci: success for files: Rework send/recv-fds to be more generic Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
Diffstat (limited to 'include')
-rw-r--r--include/common/scm-code.c90
-rw-r--r--include/common/scm.h32
2 files changed, 26 insertions, 96 deletions
diff --git a/include/common/scm-code.c b/include/common/scm-code.c
index 59a330a63..504c97212 100644
--- a/include/common/scm-code.c
+++ b/include/common/scm-code.c
@@ -6,24 +6,24 @@
#error "The __memcpy macro is required"
#endif
-#ifdef SCM_FDSET_HAS_OPTS
-#define OPTS_LEN(_flags, _nr) (_flags ? sizeof(struct fd_opts) * (_nr) : 1)
-#define OPTS_BUF(_fdset) ((_fdset)->opts)
-#else
-#define OPTS_LEN(_flags, _nr) (1)
-#define OPTS_BUF(_fdset) (&(_fdset)->dummy)
-#endif
-
-static void scm_fdset_init_chunk(struct scm_fdset *fdset, int nr_fds, bool with_flags)
+static void scm_fdset_init_chunk(struct scm_fdset *fdset, int nr_fds,
+ void *data, unsigned ch_size)
{
struct cmsghdr *cmsg;
+ static char dummy;
fdset->hdr.msg_controllen = CMSG_LEN(sizeof(int) * nr_fds);
cmsg = CMSG_FIRSTHDR(&fdset->hdr);
cmsg->cmsg_len = fdset->hdr.msg_controllen;
- fdset->iov.iov_len = OPTS_LEN(with_flags, nr_fds);
+ if (data) {
+ fdset->iov.iov_base = data;
+ fdset->iov.iov_len = nr_fds * ch_size;
+ } else {
+ fdset->iov.iov_base = &dummy;
+ fdset->iov.iov_len = 1;
+ }
}
static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
@@ -33,7 +33,7 @@ static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD)));
- fdset->iov.iov_base = OPTS_BUF(fdset);
+ fdset->iov.iov_base = (void *)0xdeadbeef;
fdset->hdr.msg_iov = &fdset->iov;
fdset->hdr.msg_iovlen = 1;
@@ -52,7 +52,7 @@ static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
}
int send_fds(int sock, struct sockaddr_un *saddr, int len,
- int *fds, int nr_fds, bool with_flags)
+ int *fds, int nr_fds, void *data, unsigned ch_size)
{
struct scm_fdset fdset;
int *cmsg_data;
@@ -61,68 +61,21 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
cmsg_data = scm_fdset_init(&fdset, saddr, len);
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, with_flags);
+ scm_fdset_init_chunk(&fdset, min_fd, data, ch_size);
__memcpy(cmsg_data, &fds[i], sizeof(int) * min_fd);
-#ifdef SCM_FDSET_HAS_OPTS
- if (with_flags) {
- int j;
-
- for (j = 0; j < min_fd; j++) {
- int flags, fd = fds[i + j];
- struct fd_opts *p = fdset.opts + j;
- struct f_owner_ex owner_ex;
- uint32_t v[2];
-
- flags = __sys(fcntl)(fd, F_GETFD, 0);
- if (flags < 0) {
- pr_err("fcntl(%d, F_GETFD) -> %d\n", fd, flags);
- return -1;
- }
-
- p->flags = (char)flags;
-
- ret = __sys(fcntl)(fd, F_GETOWN_EX, (long)&owner_ex);
- if (ret) {
- pr_err("fcntl(%d, F_GETOWN_EX) -> %d\n", fd, ret);
- return -1;
- }
-
- /*
- * Simple case -- nothing is changed.
- */
- if (owner_ex.pid == 0) {
- p->fown.pid = 0;
- continue;
- }
-
- ret = __sys(fcntl)(fd, F_GETOWNER_UIDS, (long)&v);
- if (ret) {
- pr_err("fcntl(%d, F_GETOWNER_UIDS) -> %d\n", fd, ret);
- return -1;
- }
-
- p->fown.uid = v[0];
- p->fown.euid = v[1];
- p->fown.pid_type = owner_ex.type;
- p->fown.pid = owner_ex.pid;
- }
- }
-#endif
-
ret = __sys(sendmsg)(sock, &fdset.hdr, 0);
if (ret <= 0)
return ret ? : -1;
+
+ if (data)
+ data += min_fd * ch_size;
}
return 0;
}
-#ifdef SCM_FDSET_HAS_OPTS
-int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
-#else
-int recv_fds(int sock, int *fds, int nr_fds, char *opts)
-#endif
+int recv_fds(int sock, int *fds, int nr_fds, void *data, unsigned ch_size)
{
struct scm_fdset fdset;
struct cmsghdr *cmsg;
@@ -133,7 +86,7 @@ int recv_fds(int sock, int *fds, int nr_fds, char *opts)
cmsg_data = scm_fdset_init(&fdset, NULL, 0);
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, opts != NULL);
+ scm_fdset_init_chunk(&fdset, min_fd, data, ch_size);
ret = __sys(recvmsg)(sock, &fdset.hdr, 0);
if (ret <= 0)
@@ -159,11 +112,10 @@ int recv_fds(int sock, int *fds, int nr_fds, char *opts)
if (unlikely(min_fd <= 0))
return -1;
+
__memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd);
-#ifdef SCM_FDSET_HAS_OPTS
- if (opts)
- __memcpy(opts + i, fdset.opts, sizeof(struct fd_opts) * min_fd);
-#endif
+ if (data)
+ data += ch_size * min_fd;
}
return 0;
diff --git a/include/common/scm.h b/include/common/scm.h
index f7bc5e6f3..3874d1c8e 100644
--- a/include/common/scm.h
+++ b/include/common/scm.h
@@ -15,28 +15,10 @@
#define CR_SCM_MSG_SIZE (1024)
#define CR_SCM_MAX_FD (252)
-#ifdef SCM_FDSET_HAS_OPTS
-struct fd_opts {
- char flags;
- struct {
- uint32_t uid;
- uint32_t euid;
- uint32_t signum;
- uint32_t pid_type;
- uint32_t pid;
- } fown;
-};
-#endif
-
struct scm_fdset {
struct msghdr hdr;
struct iovec iov;
char msg_buf[CR_SCM_MSG_SIZE];
-#ifdef SCM_FDSET_HAS_OPTS
- struct fd_opts opts[CR_SCM_MAX_FD];
-#else
- char dummy;
-#endif
};
#ifndef F_GETOWNER_UIDS
@@ -44,24 +26,20 @@ struct scm_fdset {
#endif
extern int send_fds(int sock, struct sockaddr_un *saddr, int len,
- int *fds, int nr_fds, bool with_flags);
-
-#ifdef SCM_FDSET_HAS_OPTS
-extern int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts);
-#else
-extern int recv_fds(int sock, int *fds, int nr_fds, char *opts);
-#endif
+ int *fds, int nr_fds, void *data, unsigned ch_size);
+extern int recv_fds(int sock, int *fds, int nr_fds,
+ void *data, unsigned ch_size);
static inline int send_fd(int sock, struct sockaddr_un *saddr, int saddr_len, int fd)
{
- return send_fds(sock, saddr, saddr_len, &fd, 1, false);
+ return send_fds(sock, saddr, saddr_len, &fd, 1, NULL, 0);
}
static inline int recv_fd(int sock)
{
int fd, ret;
- ret = recv_fds(sock, &fd, 1, NULL);
+ ret = recv_fds(sock, &fd, 1, NULL, 0);
if (ret)
return -1;