[CRIU] [PATCH v4] restore: Block SIGCHLD during root_item initialization
Kirill Tkhai
ktkhai at virtuozzo.com
Fri Apr 7 01:52:33 PDT 2017
(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