[CRIU] [PATCH v5 06/33] files: Allow to receive further fds
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Dec 26 06:25:33 PST 2016
For moving to a single transport socket scheme, we should be able
to receive a fd, which is not need at the moment, but it will
be used in the future. So, we receive a further fd, and then
continue to wait the fd, we really need now.
v3: Delete excess BUG_ON().
Rename main patch funtion to keep_fd_for_future().
Rename second funtion to task_fle(), and make it
have "task" argument.
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 7ccf235d7..a952a33f7 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -955,20 +955,51 @@ static int open_transport_fd(int pid, struct fdinfo_list_entry *fle)
return -1;
}
+static bool task_fle(struct pstree_item *task, struct fdinfo_list_entry *fle)
+{
+ struct fdinfo_list_entry *tmp;
+
+ list_for_each_entry(tmp, &rsti(task)->used, used_list)
+ if (fle == tmp)
+ return true;
+ return false;
+}
+
+static int keep_fd_for_future(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, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
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 (!task_fle(current, fle)) {
+ pr_err("Unexpected fle %p, pid=%d\n", fle, current->pid.virt);
+ return -1;
+ }
+ if (keep_fd_for_future(tmp, fd))
+ return -1;
+ goto again;
}
close(fle->fe->fd);
+ fle->received = 1;
return fd;
}
@@ -1012,6 +1043,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 1275a2be1..8c86eb24b 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -72,6 +72,7 @@ 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)
@@ -79,6 +80,7 @@ static inline void fle_init(struct fdinfo_list_entry *fle, int pid, FdinfoEntry
futex_init(&fle->real_pid);
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