[CRIU] [PATCH] restore: Defer new net-namespace creation until forked

Cyrill Gorcunov gorcunov at gmail.com
Mon Oct 27 13:24:10 PDT 2014


On Mon, Oct 27, 2014 at 11:02:04PM +0300, Andrew Vagin wrote:
> On Mon, Oct 27, 2014 at 07:19:03PM +0300, Cyrill Gorcunov wrote:
> > Some kernel modules such as pktgen runs kthred upon
> > new-net creation taking last_pid we were requested.
> > Lets workaround this problem using clone + unshare
> > bundle.
> > 
> > Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> > ---
> >  cr-restore.c | 18 +++++++++++++++++-
> >  1 file changed, 17 insertions(+), 1 deletion(-)
> > 
> > diff --git a/cr-restore.c b/cr-restore.c
> > index d046f4bd0921..d3811cb7b5d7 100644
> > --- a/cr-restore.c
> > +++ b/cr-restore.c
> > @@ -1086,8 +1086,16 @@ static inline int fork_with_pid(struct pstree_item *item)
> >  		if (netns_pre_create())
> >  			goto err_unlock;
> >  
> > +	/*
> > +	 * Some kernel modules, such as netwrok packet generator
> > +	 * run kernel thread upon net-namespace creattion taking
> > +	 * the @pid we've been requeting via LAST_PID_PATH interface
> > +	 * so that we can't restore a take with pid needed.
> > +	 *
> > +	 * Here is an idea -- unhare net namespace in callee instead.
> > +	 */
> >  	ret = clone(restore_task_with_children, ca.stack_ptr,
> > -			ca.clone_flags | SIGCHLD, &ca);
> > +		    (ca.clone_flags & ~CLONE_NEWNET) | SIGCHLD, &ca);
> >  
> >  	if (ret < 0) {
> >  		pr_perror("Can't fork for %d", pid);
> > @@ -1395,6 +1403,14 @@ static int restore_task_with_children(void *_arg)
> >  	if ( !(ca->clone_flags & CLONE_FILES))
> >  		close_safe(&ca->fd);
> >  
> > +	if (ca->clone_flags & CLONE_NEWNET) {
> > +		ret = unshare(CLONE_NEWNET);
> > +		if (ret) {
> > +			pr_perror("Can't unshare net-namespace");
> > +			goto err;
> > +		}
> > +	}
> 
> I would prefer to move this code after:
>         if (current->pid.virt != pid) {
>                 pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
>                 goto err;
>         }
> 
> And now we doesn't support nested net namespaces, so we can have it in
> the "Restore root task" blob.

But we're supposed to support them in future, right? So lets this hunk
after pid check.
-------------- next part --------------
>From f1588f840dd0b5049504dd33ba8937d36e5bd77e Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Mon, 27 Oct 2014 18:31:11 +0300
Subject: [PATCH] restore: Defer new net-namespace creation until forked

Some kernel modules such as pktgen runs kthred upon
new-net creation taking last_pid we were requested.
Lets workaround this problem using clone + unshare
bundle.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-restore.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/cr-restore.c b/cr-restore.c
index d046f4bd0921..05296f885764 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1086,8 +1086,16 @@ static inline int fork_with_pid(struct pstree_item *item)
 		if (netns_pre_create())
 			goto err_unlock;
 
+	/*
+	 * Some kernel modules, such as netwrok packet generator
+	 * run kernel thread upon net-namespace creattion taking
+	 * the @pid we've been requeting via LAST_PID_PATH interface
+	 * so that we can't restore a take with pid needed.
+	 *
+	 * Here is an idea -- unhare net namespace in callee instead.
+	 */
 	ret = clone(restore_task_with_children, ca.stack_ptr,
-			ca.clone_flags | SIGCHLD, &ca);
+		    (ca.clone_flags & ~CLONE_NEWNET) | SIGCHLD, &ca);
 
 	if (ret < 0) {
 		pr_perror("Can't fork for %d", pid);
@@ -1411,6 +1419,14 @@ static int restore_task_with_children(void *_arg)
 	if (ret < 0)
 		goto err;
 
+	if (ca->clone_flags & CLONE_NEWNET) {
+		ret = unshare(CLONE_NEWNET);
+		if (ret) {
+			pr_perror("Can't unshare net-namespace");
+			goto err;
+		}
+	}
+
 	/* Restore root task */
 	if (current->parent == NULL) {
 		if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
-- 
1.9.3



More information about the CRIU mailing list