[CRIU] [PATCH RFC 09/30] files: Allow to receive further fds
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Nov 1 07:31:47 PDT 2016
Allow to be received more sockets, than expected,
by this transport socket.
This will be used in next patch.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/files.c | 37 +++++++++++++++++++++++++++++++++++--
criu/include/files.h | 2 ++
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/criu/files.c b/criu/files.c
index a7c5bbe..8ecc253 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -956,20 +956,51 @@ static int open_transport_fd(int pid, struct fdinfo_list_entry *fle)
return -1;
}
+static bool insane_fle(struct fdinfo_list_entry *alien_fle)
+{
+ struct fdinfo_list_entry *fle;
+
+ list_for_each_entry(fle, &rsti(current)->used, used_list)
+ if (alien_fle == fle)
+ return false;
+ pr_err("Insane fle=%p, pid=%d\n", alien_fle, current->pid.virt);
+ return true;
+}
+
+static int recv_further_fle(struct fdinfo_list_entry *fle, int fd)
+{
+ BUG_ON(fle->received);
+ fle->received = 1;
+ if (close(fle->fe->fd) < 0) {
+ pr_perror("Can't close transport fd\n");
+ return -1;
+ }
+ return reopen_fd_as(fle->fe->fd, fd);
+}
+
int recv_fd_from_peer(struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
int fd, ret;
+ if (fle->received)
+ return fle->fe->fd;
+again:
ret = recv_fds(fle->fe->fd, &fd, 1, NULL, (unsigned long *)&tmp);
if (ret)
return -1;
if (tmp != fle) {
- pr_err("Received wrong fle\n");
- return -1;
+ pr_info("Further fle=%p, pid=%d\n", tmp, fle->pid);
+ if (insane_fle(fle))
+ return -1;
+ if (recv_further_fle(tmp, fd))
+ return -1;
+ goto again;
}
close(fle->fe->fd);
+ BUG_ON(fle->received);
+ fle->received = 1;
return fd;
}
@@ -1014,6 +1045,8 @@ static int send_fd_to_self(int fd, struct fdinfo_list_entry *fle)
return -1;
}
+ fle->received = 1;
+
return 0;
}
diff --git a/criu/include/files.h b/criu/include/files.h
index 26d971e..631895c 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -72,12 +72,14 @@ struct fdinfo_list_entry {
int pid;
futex_t real_pid;
FdinfoEntry *fe;
+ u8 received:1;
};
static inline void fle_init(struct fdinfo_list_entry *fle, int pid, FdinfoEntry *fe)
{
fle->pid = pid;
fle->fe = fe;
+ fle->received = 0;
}
/* reports whether fd_a takes prio over fd_b */
More information about the CRIU
mailing list