[CRIU] [PATCH v4] restore: Block SIGCHLD during root_item initialization

Andrei Vagin avagin at virtuozzo.com
Fri Apr 7 14:37:12 PDT 2017


Applied
On Fri, Apr 07, 2017 at 11:52:33AM +0300, Kirill Tkhai wrote:
> (Was "user_ns: Block SIGCHLD during namespaces generation")
> 
> We don't want asynchronous signal handler during creation
> of namespaces (for example, in create_user_ns_hierarhy())
> as we do wait() synchronous. So we need to block the signal.
> Do this once globally.
> 
> v2: Set initial ret = 0
> v3: Block signal globally in root_item before its children
> are created.
> v4: Move block to prepare_namespace()
> 
> Suggested-by: Andrew Vagin <avagin at virtuozzo.com>
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
>  criu/include/util.h |   21 +++++++++++++++++++++
>  criu/namespaces.c   |   23 ++++++++++++++++-------
>  2 files changed, 37 insertions(+), 7 deletions(-)
> 
> diff --git a/criu/include/util.h b/criu/include/util.h
> index 0428490bd..91587ef1c 100644
> --- a/criu/include/util.h
> +++ b/criu/include/util.h
> @@ -311,4 +311,25 @@ extern int open_fd_of_real_pid(pid_t pid, int fd, int flags);
>  
>  extern int call_in_child_process(int (*fn)(void *), void *arg);
>  
> +#define block_sigmask(saved_mask, sig_mask)	({					\
> +		sigset_t ___blocked_mask;						\
> +		int ___ret = 0;								\
> +		sigemptyset(&___blocked_mask);						\
> +		sigaddset(&___blocked_mask, sig_mask);					\
> +		if (sigprocmask(SIG_BLOCK, &___blocked_mask, saved_mask) == -1) {	\
> +			pr_perror("Can not set mask of blocked signals");		\
> +			___ret = -1;							\
> +		}									\
> +		___ret;									\
> +	})
> +
> +#define restore_sigmask(saved_mask)	({						\
> +		int ___ret = 0;								\
> +		if (sigprocmask(SIG_SETMASK, saved_mask, NULL) == -1) {			\
> +			pr_perror("Can not unset mask of blocked signals");		\
> +			___ret = -1;							\
> +		}									\
> +		___ret;									\
> +	})
> +
>  #endif /* __CR_UTIL_H__ */
> diff --git a/criu/namespaces.c b/criu/namespaces.c
> index 59047b42b..910fc0e0a 100644
> --- a/criu/namespaces.c
> +++ b/criu/namespaces.c
> @@ -2292,14 +2292,18 @@ static int create_user_ns_hierarhy(void)
>  int prepare_namespace(struct pstree_item *item, unsigned long clone_flags)
>  {
>  	pid_t pid = vpid(item);
> -	int id;
> +	sigset_t sig_mask;
> +	int id, ret = -1;
>  
>  	pr_info("Restoring namespaces %d flags 0x%lx\n",
>  			vpid(item), clone_flags);
>  
> +	if (block_sigmask(&sig_mask, SIGCHLD) < 0)
> +		return -1;
> +
>  	if ((clone_flags & CLONE_NEWUSER) && (prepare_userns_creds() ||
>  					      create_user_ns_hierarhy()))
> -		return -1;
> +		goto out;
>  
>  	/*
>  	 * On netns restore we launch an IP tool, thus we
> @@ -2309,22 +2313,27 @@ int prepare_namespace(struct pstree_item *item, unsigned long clone_flags)
>  
>  	id = ns_per_id ? item->ids->uts_ns_id : pid;
>  	if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(id))
> -		return -1;
> +		goto out;
>  	id = ns_per_id ? item->ids->ipc_ns_id : pid;
>  	if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(id))
> -		return -1;
> +		goto out;
>  
>  	if (prepare_net_namespaces())
> -		return -1;
> +		goto out;
>  
>  	/*
>  	 * This one is special -- there can be several mount
>  	 * namespaces and prepare_mnt_ns handles them itself.
>  	 */
>  	if (prepare_mnt_ns())
> -		return -1;
> +		goto out;
>  
> -	return 0;
> +	ret = 0;
> +out:
> +	if (restore_sigmask(&sig_mask) < 0)
> +		ret = -1;
> +
> +	return ret;
>  }
>  
>  int prepare_namespace_before_tasks(void)
> 


More information about the CRIU mailing list