[CRIU] [PATCH] pipe: don't reopen pipes via /proc, if it's not required

Andrey Vagin avagin at openvz.org
Mon Mar 18 14:10:01 EDT 2013


The system call open can add O_LARGEFILE.

Alexsander, could you test this patch.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 pipes.c                           | 55 ++++++++++++++++++++++++++++++++++-----
 test/zdtm/live/static/file_fown.c | 10 -------
 2 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/pipes.c b/pipes.c
index bd2a365..7bf1b59 100644
--- a/pipes.c
+++ b/pipes.c
@@ -28,7 +28,8 @@ struct pipe_info {
 						 * This is pure circular list without head */
 	struct list_head	list;		/* list head for fdinfo_list_entry-s */
 	struct file_desc	d;
-	int			create;
+	unsigned int		create : 1,
+				reopen : 1;
 };
 
 static LIST_HEAD(pipes);
@@ -117,6 +118,7 @@ void mark_pipe_master(void)
 	while (1) {
 		struct fdinfo_list_entry *fle;
 		struct pipe_info *pi, *pic, *p;
+		struct pipe_info *pr = NULL, *pw = NULL;
 
 		if (list_empty(&pipes))
 			break;
@@ -129,6 +131,15 @@ void mark_pipe_master(void)
 
 		fle = file_master(&pi->d);
 		p = pi;
+		if (!(pi->pe->flags & O_LARGEFILE)) {
+			if (pi->pe->flags & O_WRONLY) {
+				if (pw == NULL)
+					pw = pi;
+			} else {
+				if (pr == NULL)
+					pr = pi;
+			}
+		}
 
 		list_for_each_entry(pic, &pi->pipe_list, pipe_list) {
 			struct fdinfo_list_entry *f;
@@ -140,9 +151,23 @@ void mark_pipe_master(void)
 				fle = f;
 			}
 
+			if (!(pic->pe->flags & O_LARGEFILE)) {
+				if (pic->pe->flags & O_WRONLY) {
+					if (pw == NULL)
+						pw = pic;
+				} else {
+					if (pr == NULL)
+						pr = pic;
+				}
+			}
+
 			show_saved_pipe_fds(pic);
 		}
 		p->create = 1;
+		if (pr)
+			pr->reopen = 0;
+		if (pw)
+			pw->reopen = 0;
 		pr_info("    by %#x\n", p->pe->id);
 	}
 
@@ -222,10 +247,22 @@ err:
 	return ret;
 }
 
+static int reopen_pipe(int fd, int flags, struct pipe_info *pi)
+{
+	int ret;
+	char path[32];
+
+	pr_err("%s %p %d\n", __func__, pi, fd);
+	snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
+	ret = open(path, flags);
+	close(fd);
+
+	return ret;
+}
+
 static int recv_pipe_fd(struct pipe_info *pi)
 {
 	struct fdinfo_list_entry *fle;
-	char path[32];
 	int tmp, fd;
 
 	fle = file_master(&pi->d);
@@ -240,12 +277,12 @@ static int recv_pipe_fd(struct pipe_info *pi)
 	}
 	close(fd);
 
-	snprintf(path, sizeof(path), "/proc/self/fd/%d", tmp);
-	fd = open(path, pi->pe->flags);
-	close(tmp);
-
+	if (pi->reopen)
+		fd = reopen_pipe(tmp, pi->pe->flags, pi);
+	else
+		fd = tmp;
 	if (fd >= 0) {
-		if (restore_fown(fd, pi->pe->fown)) {
+		if (rst_file_params(fd, pi->pe->fown, pi->pe->flags)) {
 			close(fd);
 			return -1;
 		}
@@ -302,6 +339,9 @@ static int open_pipe(struct file_desc *d)
 	close(pfd[!(pi->pe->flags & O_WRONLY)]);
 	tmp = pfd[pi->pe->flags & O_WRONLY];
 
+	if (pi->reopen)
+		tmp = reopen_pipe(tmp, pi->pe->flags, pi);
+
 	if (rst_file_params(tmp, pi->pe->fown, pi->pe->flags))
 		return -1;
 
@@ -329,6 +369,7 @@ static int collect_one_pipe(void *o, ProtobufCMessage *base)
 	pi->pe = pb_msg(base, PipeEntry);
 
 	pi->create = 0;
+	pi->reopen = 1;
 	pr_info("Collected pipe entry ID %#x PIPE ID %#x\n",
 			pi->pe->id, pi->pe->pipe_id);
 
diff --git a/test/zdtm/live/static/file_fown.c b/test/zdtm/live/static/file_fown.c
index 4756fa9..0dfe47c 100644
--- a/test/zdtm/live/static/file_fown.c
+++ b/test/zdtm/live/static/file_fown.c
@@ -40,16 +40,6 @@ static void fill_pipe_params(struct params *p, int *pipes)
 	p->pipe_flags[0] = fcntl(pipes[0], F_GETFL);
 	p->pipe_flags[1] = fcntl(pipes[1], F_GETFL);
 
-	/*
-	 * The kernel's O_LARGEFILE set automatically
-	 * on open() in x86-64, so unmask it explicitly
-	 * we restore pipes via open call while the former
-	 * pipes are created with pipe() and have no O_LARGEFILE
-	 * set.
-	 */
-	p->pipe_flags[0] &= ~00100000;
-	p->pipe_flags[1] &= ~00100000;
-
 	test_msg("pipe_flags0 %08o\n", p->pipe_flags[0]);
 	test_msg("pipe_flags1 %08o\n", p->pipe_flags[1]);
 
-- 
1.7.11.7



More information about the CRIU mailing list