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:
committed by
Andrei Vagin
parent
5af3ca59eb
commit
cd738b8b01
@@ -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
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user