[CRIU] [PATCH RFC 04/30] pie: Allow to transfer pointers on struct fdinfo_list_entry together with fds
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Nov 1 07:31:00 PDT 2016
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/include/util-pie.h | 11 ++++++----
criu/parasite-syscall.c | 2 +-
criu/pie/parasite.c | 2 +-
criu/pie/util-fd.c | 51 ++++++++++++++++++++++++++++++++++++-----------
4 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/criu/include/util-pie.h b/criu/include/util-pie.h
index a1435336..f7f3cff 100644
--- a/criu/include/util-pie.h
+++ b/criu/include/util-pie.h
@@ -34,25 +34,26 @@ struct fd_opts {
struct scm_fdset {
struct msghdr hdr;
- struct iovec iov;
+ struct iovec iov[2];
char msg_buf[CR_SCM_MSG_SIZE];
struct fd_opts opts[CR_SCM_MAX_FD];
+ unsigned long fles[CR_SCM_MAX_FD];
};
extern int send_fds(int sock, struct sockaddr_un *saddr, int saddr_len,
- int *fds, int nr_fds, bool with_flags);
-extern int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts);
+ int *fds, int nr_fds, bool with_flags, unsigned long *fles);
+extern int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts, unsigned long *fles);
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, false, NULL);
}
static inline int recv_fd(int sock)
{
int fd, ret;
- ret = recv_fds(sock, &fd, 1, NULL);
+ ret = recv_fds(sock, &fd, 1, NULL, NULL);
if (ret)
return -1;
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 2fe6e87..3786fba 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -916,7 +916,7 @@ int parasite_drain_fds_seized(struct parasite_ctl *ctl,
goto err;
}
- ret = recv_fds(ctl->tsock, lfds, nr_fds, opts);
+ ret = recv_fds(ctl->tsock, lfds, nr_fds, opts, NULL);
if (ret)
pr_err("Can't retrieve FDs from socket\n");
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index 665f62b..2b00240 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -286,7 +286,7 @@ static int drain_fds(struct parasite_drain_fd *args)
int ret;
ret = send_fds(tsock, NULL, 0,
- args->fds, args->nr_fds, true);
+ args->fds, args->nr_fds, true, NULL);
if (ret)
pr_err("send_fds failed (%d)\n", ret);
diff --git a/criu/pie/util-fd.c b/criu/pie/util-fd.c
index f3f9c2e..47a4619 100644
--- a/criu/pie/util-fd.c
+++ b/criu/pie/util-fd.c
@@ -21,29 +21,51 @@
#include "common/bug.h"
-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, bool with_flags, bool with_fle)
{
struct cmsghdr *cmsg;
+ int nr = 0;
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 = with_flags ? (sizeof(struct fd_opts) * nr_fds) : 1;
+ if (with_flags) {
+ fdset->iov[nr].iov_len = sizeof(fdset->opts[0]) * nr_fds;
+ nr++;
+ }
+
+ if (with_fle) {
+ fdset->iov[nr].iov_len = sizeof(fdset->fles[0]) * nr_fds;
+ nr++;
+ }
}
static int *scm_fdset_init(struct scm_fdset *fdset, struct sockaddr_un *saddr,
- int saddr_len, bool with_flags)
+ int saddr_len, bool with_flags, bool with_fle)
{
struct cmsghdr *cmsg;
+ int nr = 0;
BUILD_BUG_ON(sizeof(fdset->msg_buf) < (CMSG_SPACE(sizeof(int) * CR_SCM_MAX_FD)));
- fdset->iov.iov_base = fdset->opts;
+ if (with_flags) {
+ fdset->iov[nr].iov_base = fdset->opts;
+ nr++;
+ }
+ if (with_fle) {
+ fdset->iov[nr].iov_base = fdset->fles;
+ nr++;
+ }
+ if (!nr) {
+ fdset->iov[nr].iov_base = fdset->opts;
+ fdset->iov[nr].iov_len = 1;
+ nr = 1;
+ }
- fdset->hdr.msg_iov = &fdset->iov;
- fdset->hdr.msg_iovlen = 1;
+ fdset->hdr.msg_iov = fdset->iov;
+ fdset->hdr.msg_iovlen = nr;
fdset->hdr.msg_name = (struct sockaddr *)saddr;
fdset->hdr.msg_namelen = saddr_len;
@@ -59,16 +81,16 @@ 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, bool with_flags, unsigned long *fles)
{
struct scm_fdset fdset;
int *cmsg_data;
int i, min_fd, ret;
- cmsg_data = scm_fdset_init(&fdset, saddr, len, with_flags);
+ cmsg_data = scm_fdset_init(&fdset, saddr, len, with_flags, fles != NULL);
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, with_flags, fles != NULL);
builtin_memcpy(cmsg_data, &fds[i], sizeof(int) * min_fd);
if (with_flags) {
@@ -115,6 +137,9 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
}
}
+ if (fles != NULL)
+ builtin_memcpy(fdset.fles, fles + i, sizeof(unsigned long) * min_fd);
+
ret = __sys(sendmsg)(sock, &fdset.hdr, 0);
if (ret <= 0)
return ret ? : -1;
@@ -123,7 +148,7 @@ int send_fds(int sock, struct sockaddr_un *saddr, int len,
return 0;
}
-int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
+int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts, unsigned long *fles)
{
struct scm_fdset fdset;
struct cmsghdr *cmsg;
@@ -131,10 +156,10 @@ int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
int ret;
int i, min_fd;
- cmsg_data = scm_fdset_init(&fdset, NULL, 0, opts != NULL);
+ cmsg_data = scm_fdset_init(&fdset, NULL, 0, opts != NULL, fles != NULL);
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, opts != NULL, fles != NULL);
ret = __sys(recvmsg)(sock, &fdset.hdr, 0);
if (ret <= 0)
@@ -163,6 +188,8 @@ int recv_fds(int sock, int *fds, int nr_fds, struct fd_opts *opts)
builtin_memcpy(&fds[i], cmsg_data, sizeof(int) * min_fd);
if (opts)
builtin_memcpy(opts + i, fdset.opts, sizeof(struct fd_opts) * min_fd);
+ if (fles)
+ builtin_memcpy(fles + i, fdset.fles, sizeof(unsigned long) * min_fd);
}
return 0;
More information about the CRIU
mailing list