Commit badf42ca authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Andrei Vagin

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: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent a877a894
...@@ -346,4 +346,25 @@ extern int epoll_prepare(int nr_events, struct epoll_event **evs); ...@@ -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); 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__ */ #endif /* __CR_UTIL_H__ */
...@@ -1682,11 +1682,15 @@ err_out: ...@@ -1682,11 +1682,15 @@ err_out:
int prepare_namespace(struct pstree_item *item, unsigned long clone_flags) int prepare_namespace(struct pstree_item *item, unsigned long clone_flags)
{ {
pid_t pid = vpid(item); pid_t pid = vpid(item);
int id; sigset_t sig_mask;
int id, ret = -1;
pr_info("Restoring namespaces %d flags 0x%lx\n", pr_info("Restoring namespaces %d flags 0x%lx\n",
vpid(item), clone_flags); vpid(item), clone_flags);
if (block_sigmask(&sig_mask, SIGCHLD) < 0)
return -1;
if ((clone_flags & CLONE_NEWUSER) && prepare_userns_creds()) if ((clone_flags & CLONE_NEWUSER) && prepare_userns_creds())
return -1; return -1;
...@@ -1698,22 +1702,27 @@ int prepare_namespace(struct pstree_item *item, unsigned long clone_flags) ...@@ -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; id = ns_per_id ? item->ids->uts_ns_id : pid;
if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(id)) if ((clone_flags & CLONE_NEWUTS) && prepare_utsns(id))
return -1; goto out;
id = ns_per_id ? item->ids->ipc_ns_id : pid; id = ns_per_id ? item->ids->ipc_ns_id : pid;
if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(id)) if ((clone_flags & CLONE_NEWIPC) && prepare_ipc_ns(id))
return -1; goto out;
if (prepare_net_namespaces()) if (prepare_net_namespaces())
return -1; goto out;
/* /*
* This one is special -- there can be several mount * This one is special -- there can be several mount
* namespaces and prepare_mnt_ns handles them itself. * namespaces and prepare_mnt_ns handles them itself.
*/ */
if (prepare_mnt_ns()) 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) int prepare_namespace_before_tasks(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment