2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-09-05 08:45:49 +00:00

restore: Block SIGCHLD during root_item initialization

(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@virtuozzo.com>
Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Kirill Tkhai
2017-04-07 11:52:33 +03:00
committed by Andrei Vagin
parent a877a89484
commit badf42caa4
2 changed files with 36 additions and 6 deletions

View File

@@ -346,4 +346,25 @@ extern int epoll_prepare(int nr_events, struct epoll_event **evs);
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__ */

View File

@@ -1682,11 +1682,15 @@ err_out:
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())
return -1;
@@ -1698,22 +1702,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)