[CRIU] [PATCH RFC v2 07/14] files: Allow to receive further fds

Kirill Tkhai ktkhai at virtuozzo.com
Fri Oct 28 14:06:49 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/autofs.c        |    1 +
 criu/files.c         |   38 ++++++++++++++++++++++++++++++++++++--
 criu/include/files.h |    1 +
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/criu/autofs.c b/criu/autofs.c
index 345a703..467ed16 100644
--- a/criu/autofs.c
+++ b/criu/autofs.c
@@ -879,6 +879,7 @@ static int autofs_create_fle(struct pstree_item *task, FdinfoEntry *fe,
 	futex_init(&le->real_pid);
 	le->pid = task->pid.virt;
 	le->fe = fe;
+	le->received = false;
 
 	collect_gen_fd(le, rst_info);
 
diff --git a/criu/files.c b/criu/files.c
index e4c2ab7..1961ae6 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -697,6 +697,7 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info)
 	futex_init(&new_le->real_pid);
 	new_le->pid = pid;
 	new_le->fe = e;
+	new_le->received = false;
 
 	fdesc = find_file_desc(e);
 	if (fdesc == NULL) {
@@ -957,20 +958,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 = true;
+	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 = true;
 
 	return fd;
 }
@@ -1015,6 +1047,8 @@ static int send_fd_to_self(int fd, struct fdinfo_list_entry *fle)
 		return -1;
 	}
 
+	fle->received = true;
+
 	return 0;
 }
 
diff --git a/criu/include/files.h b/criu/include/files.h
index 9388a8a..41790ad 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;
+	bool			received;
 };
 
 /* reports whether fd_a takes prio over fd_b */



More information about the CRIU mailing list