[CRIU] failure dumping nginx in docker container

Andrew Vagin avagin at odin.com
Tue Jun 30 08:29:28 PDT 2015


Hi Boucher,

Could you try out the attached patch?

On Tue, Jun 30, 2015 at 05:00:36PM +0300, Andrew Vagin wrote:
> On Wed, Jun 24, 2015 at 12:34:51PM -0700, Ross Boucher wrote:
> > Here's the output same procedure without the restore-sibling option:
> > https://gist.githubusercontent.com/boucher/b18593b9da2782d17e95/raw/strace.txt
> > 
> > It's rather long. I'm not really sure how to read the strace output.
> 
> Thank you.
> 
> 16272 write(1023, "(00.139818)      1: \t\tCreate transport fd /crtools-fd-1-5\n", 58) = 58
> 16272 socket(PF_LOCAL, SOCK_DGRAM, 0)   = 0
> 16272 bind(0, {sa_family=AF_LOCAL, sun_path=@"/crtools-fd-1-5"}, 18) = 0
> 16272 fcntl(5, F_GETFD)                 = -1 EBADF (Bad file descriptor)
> 16272 dup2(0, 5)                        = 5
> 
> 16272 write(1023, "(00.142054)      1: Found id pipe:[122747] (fd 8) in inherit fd list\n", 69) = 69
> 16272 dup(8)                            = 9
> 16272 write(1023, "(00.142074)      1: File pipe:[122747] will be restored from fd 9 duped from inherit fd 8\n", 90) = 90
> 16272 fcntl(5, F_GETFD)                 = 0
> 16272 write(1023, "(00.142095)      1: Error (util.c:131): fd 5 already in use (called at files.c:872)\n", 84) = 84
> 
> Looks like we meet both ends of an inhereted pipe.
> 
> The same problem can be reproduced by the pipes test with the following
> path:
> 
> diff --git a/test/pipes/pipe.c b/test/pipes/pipe.c
> index cb34703..03efccc 100644
> --- a/test/pipes/pipe.c
> +++ b/test/pipes/pipe.c
> @@ -232,7 +232,7 @@ int main(int argc, char *argv[])
>  
>                 child_pid = getpid();
>  
> -               close_safe(pipefd[READ_FD]);
> +//             close_safe(pipefd[READ_FD]);
>                 setsid();
>                 logfd = open_safe(OLD_LOG_FILE, O_WRONLY | O_APPEND | O_CREAT);
>                 dup2_safe(logfd, 1);
> 
> > 
> > On Tue, Jun 23, 2015 at 11:39 PM, Pavel Emelyanov <xemul at parallels.com> wrote:
> > 
> >     On 06/24/2015 01:42 AM, Ross Boucher wrote:
> >     > If I run strace on the docker daemon, criu fails to restore with a
> >     different error:
> >     >
> >     > https://gist.github.com/boucher/bef6e944ae700526a979
> >     > (I included both the restore log and the strace)
> >     >
> >     > Without strace, I get the same fd already in use error.
> > 
> >     Hm... The new error is because criu tries to PTRACE_SEIZE the init to do
> >     the
> >     --restore-sibling restore and can't do it since strace is already there.
> > 
> >     Can you (for experiment only) patch out the --restore-sibling option from
> >     the
> >     code that calls criu? Or (!) call criu restore manually on the existing
> >     images
> >     with all the options being "correct" by yet again w/o the
> >     --restore-sibling?
> >    
> >     -- Pavel
> > 
> > 
> > 
> 
> > _______________________________________________
> > CRIU mailing list
> > CRIU at openvz.org
> > https://lists.openvz.org/mailman/listinfo/criu
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
-------------- next part --------------
>From 968e8d77fe70651f744f1f095f4b0fd05f937ad4 Mon Sep 17 00:00:00 2001
From: Andrey Vagin <avagin at openvz.org>
Date: Tue, 30 Jun 2015 18:15:35 +0300
Subject: [PATCH] pipe: add ability to restore both ends of inhereted pipes

When we restore an inhereted pipe, we have only one end and we don't
know whether it's write or read one. So we need to call reopen_pipe each
time.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 files.c |  3 +++
 pipes.c | 30 +++++++++++++++++++-----------
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/files.c b/files.c
index 4eeb988..3e69be7 100644
--- a/files.c
+++ b/files.c
@@ -1394,6 +1394,9 @@ bool inherited_fd(struct file_desc *d, int *fd_p)
 	if (i_fd < 0)
 		return false;
 
+	if (fd_p == NULL)
+		return true;
+
 	*fd_p = dup(i_fd);
 	if (*fd_p < 0)
 		pr_perror("Inherit fd DUP failed");
diff --git a/pipes.c b/pipes.c
index 7590472..82be088 100644
--- a/pipes.c
+++ b/pipes.c
@@ -314,11 +314,14 @@ static int open_pipe(struct file_desc *d)
 	int pfd[2];
 	int sock;
 
-	if (inherited_fd(d, &tmp))
-		return tmp;
-
 	pi = container_of(d, struct pipe_info, d);
 	pr_info("\t\tCreating pipe pipe_id=%#x id=%#x\n", pi->pe->pipe_id, pi->pe->id);
+	if (inherited_fd(d, &tmp)) {
+		if (tmp < 0)
+			return tmp;
+
+		goto out;
+	}
 
 	if (!pi->create)
 		return recv_pipe_fd(pi);
@@ -357,6 +360,7 @@ static int open_pipe(struct file_desc *d)
 	close(pfd[!(pi->pe->flags & O_WRONLY)]);
 	tmp = pfd[pi->pe->flags & O_WRONLY];
 
+out:
 	if (pi->reopen)
 		tmp = reopen_pipe(tmp, pi->pe->flags);
 
@@ -393,18 +397,22 @@ static int collect_one_pipe(void *o, ProtobufCMessage *base)
 	pr_info("Collected pipe entry ID %#x PIPE ID %#x\n",
 			pi->pe->id, pi->pe->pipe_id);
 
-	list_for_each_entry(tmp, &pipes, list)
-		if (pi->pe->pipe_id == tmp->pe->pipe_id)
-			break;
+	if (file_desc_add(&pi->d, pi->pe->id, &pipe_desc_ops))
+		return -1;
 
-	if (&tmp->list == &pipes)
-		INIT_LIST_HEAD(&pi->pipe_list);
-	else
-		list_add(&pi->pipe_list, &tmp->pipe_list);
+	INIT_LIST_HEAD(&pi->pipe_list);
+	if (!inherited_fd(&pi->d, NULL)) {
+		list_for_each_entry(tmp, &pipes, list)
+			if (pi->pe->pipe_id == tmp->pe->pipe_id)
+				break;
+
+		if (&tmp->list != &pipes)
+			list_add(&pi->pipe_list, &tmp->pipe_list);
+	}
 
 	list_add_tail(&pi->list, &pipes);
-	return file_desc_add(&pi->d, pi->pe->id, &pipe_desc_ops);
 
+	return 0;
 }
 
 struct collect_image_info pipe_cinfo = {
-- 
2.1.0



More information about the CRIU mailing list