2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

ns: Make pid_ns helpers as children of criu main process

If a task, holding userns_sync_lock unexpectedly exits,
criu will hang on error path in restore_root_task(),
because it can't use usernsd to destroy them.

Lets remove the intermediary: we'll create pid_ns helpers
as children of criu main task, and criu main task will
be able to use simple kill() to stop them.

v2: Make code more compact, add a comment.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Kirill Tkhai
2017-07-14 15:40:32 +03:00
committed by Andrei Vagin
parent 5af3ca59eb
commit cd738b8b01
2 changed files with 7 additions and 29 deletions

View File

@@ -1536,6 +1536,10 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
break;
}
/* criu destroys pid_ns helpers under blocked SIGCHLD, we mustn't catch them here */
if (!current)
warn_if_pid_ns_helper_exited(pid);
if (exit)
pr_err("%d exited, status=%d\n", pid, status);
else

View File

@@ -1604,23 +1604,6 @@ void warn_if_pid_ns_helper_exited(pid_t real_pid)
pr_err("Spurious pid ns helper: pid=%d\n", real_pid);
}
static void usernsd_handler(int signal, siginfo_t *siginfo, void *data)
{
pid_t pid = siginfo->si_pid;
int status;
while (pid) {
pid = waitpid(-1, &status, WNOHANG);
if (pid <= 0)
return;
warn_if_pid_ns_helper_exited(pid);
pr_err("%d finished unexpected: status=%d\n", pid, status);
futex_abort_and_wake(&task_entries->nr_in_progress);
}
}
static int usernsd_recv_transport(void *arg, int fd, pid_t pid)
{
if (install_service_fd(TRANSPORT_FD_OFF, fd) < 0) {
@@ -1664,11 +1647,6 @@ static int usernsd(int sk)
{
pr_info("uns: Daemon started\n");
if (criu_signals_setup(usernsd_handler) < 0) {
pr_err("Can't setup handler\n");
return -1;
}
while (1) {
struct unsc_msg um;
static char msg[MAX_UNSFD_MSG_SIZE];
@@ -2713,7 +2691,7 @@ static int do_create_pid_ns_helper(void *arg, int sk, pid_t unused_pid)
unlock_last_pid();
goto restore_ns;
}
child = fork();
child = sys_clone_unified(CLONE_PARENT|SIGCHLD, NULL, NULL, NULL, 0);
if (!child)
exit(pid_ns_helper(ns, sk));
saved_errno = errno;
@@ -2775,7 +2753,7 @@ int create_pid_ns_helper(struct ns_id *ns)
return 0;
}
static int do_destroy_pid_ns_helpers(void *arg, int fd, pid_t unused)
static int do_destroy_pid_ns_helpers(void)
{
int status, sig_blocked = true, ret = 0;
sigset_t sig_mask;
@@ -2824,11 +2802,7 @@ int destroy_pid_ns_helpers(void)
if (!(root_ns_mask & CLONE_NEWPID))
return 0;
if (userns_call(do_destroy_pid_ns_helpers, 0, NULL, 0, -1) < 0) {
pr_err("Can't create pid_ns helper\n");
return -1;
}
return 0;
return do_destroy_pid_ns_helpers();
}
int __setns_from_fdstore(int fd_id, int nstype, const char *file, int line)