[CRIU] [PATCH RFC v2 08/14] files: Make sending fds to peers async

Kirill Tkhai ktkhai at virtuozzo.com
Fri Oct 28 14:06:58 PDT 2016


Don't wait for "prepare" stage of every peer's fd. Just
send everything to peer's global transport_fd, and peer
will find appropriate fd, it needs at the moment.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/autofs.c        |    1 -
 criu/files.c         |   87 +++++---------------------------------------------
 criu/include/files.h |    1 -
 3 files changed, 8 insertions(+), 81 deletions(-)

diff --git a/criu/autofs.c b/criu/autofs.c
index 467ed16..113b5ca 100644
--- a/criu/autofs.c
+++ b/criu/autofs.c
@@ -876,7 +876,6 @@ static int autofs_create_fle(struct pstree_item *task, FdinfoEntry *fe,
 		return -1;
 	le = (void *)ALIGN((long)le, sizeof(int));
 
-	futex_init(&le->real_pid);
 	le->pid = task->pid.virt;
 	le->fe = fe;
 	le->received = false;
diff --git a/criu/files.c b/criu/files.c
index 1961ae6..da0456c 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -694,7 +694,6 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info)
 	if (!new_le)
 		return -1;
 
-	futex_init(&new_le->real_pid);
 	new_le->pid = pid;
 	new_le->fe = e;
 	new_le->received = false;
@@ -872,20 +871,17 @@ struct fd_open_state {
 	bool required;
 };
 
-static int open_transport_fd(int pid, struct fdinfo_list_entry *fle);
 static int open_fd(int pid, struct fdinfo_list_entry *fle);
 static int receive_fd(int pid, struct fdinfo_list_entry *fle);
 static int post_open_fd(int pid, struct fdinfo_list_entry *fle);
 
 static struct fd_open_state states[] = {
-	{ "prepare",		open_transport_fd,	true,},
 	{ "create",		open_fd,		true,},
-	{ "receive",		receive_fd,		false,},
+	{ "receive",		receive_fd,		true,},
 	{ "post_create",	post_open_fd,		false,},
 };
 
-#define want_recv_stage()	do { states[2].required = true; } while (0)
-#define want_post_open_stage()	do { states[3].required = true; } while (0)
+#define want_post_open_stage()	do { states[2].required = true; } while (0)
 
 static void transport_name_gen(struct sockaddr_un *addr, int *len,
 		int pid, int fd)
@@ -896,68 +892,6 @@ static void transport_name_gen(struct sockaddr_un *addr, int *len,
 	*addr->sun_path = '\0';
 }
 
-static int should_open_transport(FdinfoEntry *fe, struct file_desc *fd)
-{
-	if (fd->ops->want_transport)
-		return fd->ops->want_transport(fe, fd);
-	else
-		return 0;
-}
-
-static int open_transport_fd(int pid, struct fdinfo_list_entry *fle)
-{
-	struct fdinfo_list_entry *flem;
-	struct sockaddr_un saddr;
-	int sock;
-	int ret, sun_len;
-
-	flem = file_master(fle->desc);
-
-	if (flem->pid == pid) {
-		if (flem->fe->fd != fle->fe->fd)
-			/* dup-ed file. Will be opened in the open_fd */
-			return 0;
-
-		if (!should_open_transport(fle->fe, fle->desc))
-			/* pure master file */
-			return 0;
-
-		/*
-		 * some master file, that wants a transport, e.g.
-		 * a pipe or unix socket pair 'slave' end
-		 */
-	}
-
-	transport_name_gen(&saddr, &sun_len, getpid(), fle->fe->fd);
-
-	pr_info("\t\tCreate transport fd %s\n", saddr.sun_path + 1);
-
-
-	sock = socket(PF_UNIX, SOCK_DGRAM, 0);
-	if (sock < 0) {
-		pr_perror("Can't create socket");
-		return -1;
-	}
-	ret = bind(sock, (struct sockaddr *)&saddr, sun_len);
-	if (ret < 0) {
-		pr_perror("Can't bind unix socket %s", saddr.sun_path + 1);
-		goto err;
-	}
-
-	ret = reopen_fd_as(fle->fe->fd, sock);
-	if (ret < 0)
-		goto err;
-
-	pr_info("\t\tWake up fdinfo pid=%d fd=%d\n", fle->pid, fle->fe->fd);
-	futex_set_and_wake(&fle->real_pid, getpid());
-	want_recv_stage();
-
-	return 0;
-err:
-	close(sock);
-	return -1;
-}
-
 static bool insane_fle(struct fdinfo_list_entry *alien_fle)
 {
 	struct fdinfo_list_entry *fle;
@@ -973,22 +907,20 @@ 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;
+	int fd, ret, tsock;
 
 	if (fle->received)
 		return fle->fe->fd;
+
+	tsock = get_service_fd(TRANSPORT_FD_OFF);
 again:
-	ret = recv_fds(fle->fe->fd, &fd, 1, NULL, (unsigned long *)&tmp);
+	ret = recv_fds(tsock, &fd, 1, NULL, (unsigned long *)&tmp);
 	if (ret)
 		return -1;
 
@@ -1000,7 +932,6 @@ int recv_fd_from_peer(struct fdinfo_list_entry *fle)
 			return -1;
 		goto again;
 	}
-	close(fle->fe->fd);
 	BUG_ON(fle->received);
 	fle->received = true;
 
@@ -1014,11 +945,9 @@ int send_fd_to_peer(int fd, struct fdinfo_list_entry *fle)
 
 	sock = get_service_fd(TRANSPORT_FD_OFF);
 
-	pr_info("\t\tWait fdinfo pid=%d fd=%d\n", fle->pid, fle->fe->fd);
-	futex_wait_while(&fle->real_pid, 0);
+	pr_info("\t\tWait fdinfo pid=%d\n", fle->pid);
 	futex_wait_while(&pstree_item_by_virt(fle->pid)->transport_fd, 0);
-	transport_name_gen(&saddr, &len,
-			futex_get(&fle->real_pid), fle->fe->fd);
+	transport_name_gen(&saddr, &len, fle->pid, -1);
 	pr_info("\t\tSend fd %d to %s\n", fd, saddr.sun_path + 1);
 	return send_fds(sock, &saddr, len, &fd, 1, false, (unsigned long *)&fle);
 }
diff --git a/criu/include/files.h b/criu/include/files.h
index 41790ad..c5cde9e 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -70,7 +70,6 @@ struct fdinfo_list_entry {
 	struct list_head	ps_list;	/* To chain  per-task files */
 	struct list_head	used_list;	/* To chain per-task used fds */
 	int			pid;
-	futex_t			real_pid;
 	FdinfoEntry		*fe;
 	bool			received;
 };



More information about the CRIU mailing list