[CRIU] [PATCH] restore: Set CLONE_PARENT iif pdeath_sig is present

Andrew Vagin avagin at parallels.com
Thu Aug 14 08:42:11 PDT 2014


On Thu, Aug 14, 2014 at 07:38:22PM +0400, Pavel Emelyanov wrote:
> On 08/14/2014 07:35 PM, Cyrill Gorcunov wrote:
> > It's been discovered that on 3.11 we might fail on restore
> > if pass @CLONE_PARENT flag into clone() call due to kernel
> > limitations.
> > 
> > Because we're treating 3.11 as a base working kernel lets
> > do a trick instead
> > 
> >  - setup this flag iif pdeath_sig is present
> >  - if CLONE_NEWPID is passed warn a user about
> >    potential consequences.
> > 
> > CC: Tycho Andersen <tycho.andersen at canonical.com>
> > CC: Andrey Vagin <avagin at openvz.org>
> > CC: Pavel Emelyanov <xemul at parallels.com>
> > Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> > ---
> > 
> > Guys, what do you think?
> > 
> >  cr-restore.c | 46 +++++++++++++++++++++++++++++++++-------------
> >  1 file changed, 33 insertions(+), 13 deletions(-)
> > 
> > diff --git a/cr-restore.c b/cr-restore.c
> > index bd16b1d81ca7..ea6437d6d503 100644
> > --- a/cr-restore.c
> > +++ b/cr-restore.c
> > @@ -922,6 +922,37 @@ struct cr_clone_arg {
> >  	CoreEntry *core;
> >  };
> >  
> > +static void maybe_clone_parent(struct pstree_item *item,
> > +			      struct cr_clone_arg *ca)
> > +{
> > +	if (likely(item->pid.virt != INIT_PID))
> > +		return;
> > +
> > +	if (opts.swrk_restore || opts.restore_detach) {
> > +		/*
> > +		 * This means we're called from lib's criu_restore_child().
> > +		 * In that case create the root task as the child one to+
> > +		 * the caller. This is the only way to correctly restore the
> > +		 * pdeath_sig of the root task. But also looks nice.
> > +		 *
> > +		 * Alternatively, if we are --restore-detached, a similar trick is
> > +		 * needed to correctly restore pdeath_sig and prevent processes from
> > +		 * dying once restored.
> > +		 *
> > +		 * There were a problem in kernel 3.11 -- CLONE_PARENT can't be
> > +		 * set together with CLONE_NEWPID, which has been solved in further
> > +		 * versions of the kernels, but we treat 3.11 as a base, so at
> > +		 * least warn a user about potential problems.
> > +		 */
> > +		if (ca->core->thread_core->pdeath_sig) {
> > +			item->rst->clone_flags |= CLONE_PARENT;
> > +			if (item->rst->clone_flags & CLONE_NEWPID)
> > +				pr_warn("Set CLONE_PARENT | CLONE_NEWPID but it might cause restore problem,"
> > +					"because not all kernels support such clone flags combinations!\n");
> > +		}
> > +	}
> > +}
> > +
> >  static inline int fork_with_pid(struct pstree_item *item)
> >  {
> >  	int ret = -1, fd;
> > @@ -951,6 +982,8 @@ static inline int fork_with_pid(struct pstree_item *item)
> >  			pr_err("Unknown task state %d\n", item->state);
> >  			return -1;
> >  		}
> > +
> > +		maybe_clone_parent(item, &ca);
> >  	} else {
> >  		/*
> >  		 * Helper entry will not get moved around and thus
> > @@ -1587,19 +1620,6 @@ static int restore_root_task(struct pstree_item *init)
> >  	futex_set(&task_entries->nr_in_progress,
> >  			stage_participants(CR_STATE_RESTORE_NS));
> >  
> > -	/*
> > -	 * This means we're called from lib's criu_restore_child().
> > -	 * In that case create the root task as the child one to+
> > -	 * the caller. This is the only way to correctly restore the
> > -	 * pdeath_sig of the root task. But also looks nice.
> > -	 *
> > -	 * Alternatively, if we are --restore-detached, a similar trick is
> > -	 * needed to correctly restore pdeath_sig and prevent processes from
> > -	 * dying once restored.
> > -	 */
> > -	if (opts.swrk_restore || opts.restore_detach)
> > -		init->rst->clone_flags |= CLONE_PARENT;
> 
> There are 2 more places that check for swrk_restore || restore_detach.
> We need to fix them too, since CLONE_PARENT and these other two do things,
> that depend on each-other.

And one more place where is only swrk_restore:
ret = attach_to_tasks(opts.swrk_restore)

> 
> > -
> >  	ret = fork_with_pid(init);
> >  	if (ret < 0)
> >  		return -1;
> > 
> 


More information about the CRIU mailing list