mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-03 15:55:53 +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;
|
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)
|
if (exit)
|
||||||
pr_err("%d exited, status=%d\n", pid, status);
|
pr_err("%d exited, status=%d\n", pid, status);
|
||||||
else
|
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);
|
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)
|
static int usernsd_recv_transport(void *arg, int fd, pid_t pid)
|
||||||
{
|
{
|
||||||
if (install_service_fd(TRANSPORT_FD_OFF, fd) < 0) {
|
if (install_service_fd(TRANSPORT_FD_OFF, fd) < 0) {
|
||||||
@@ -1664,11 +1647,6 @@ static int usernsd(int sk)
|
|||||||
{
|
{
|
||||||
pr_info("uns: Daemon started\n");
|
pr_info("uns: Daemon started\n");
|
||||||
|
|
||||||
if (criu_signals_setup(usernsd_handler) < 0) {
|
|
||||||
pr_err("Can't setup handler\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
struct unsc_msg um;
|
struct unsc_msg um;
|
||||||
static char msg[MAX_UNSFD_MSG_SIZE];
|
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();
|
unlock_last_pid();
|
||||||
goto restore_ns;
|
goto restore_ns;
|
||||||
}
|
}
|
||||||
child = fork();
|
child = sys_clone_unified(CLONE_PARENT|SIGCHLD, NULL, NULL, NULL, 0);
|
||||||
if (!child)
|
if (!child)
|
||||||
exit(pid_ns_helper(ns, sk));
|
exit(pid_ns_helper(ns, sk));
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
@@ -2775,7 +2753,7 @@ int create_pid_ns_helper(struct ns_id *ns)
|
|||||||
return 0;
|
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;
|
int status, sig_blocked = true, ret = 0;
|
||||||
sigset_t sig_mask;
|
sigset_t sig_mask;
|
||||||
@@ -2824,11 +2802,7 @@ int destroy_pid_ns_helpers(void)
|
|||||||
if (!(root_ns_mask & CLONE_NEWPID))
|
if (!(root_ns_mask & CLONE_NEWPID))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (userns_call(do_destroy_pid_ns_helpers, 0, NULL, 0, -1) < 0) {
|
return do_destroy_pid_ns_helpers();
|
||||||
pr_err("Can't create pid_ns helper\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __setns_from_fdstore(int fd_id, int nstype, const char *file, int line)
|
int __setns_from_fdstore(int fd_id, int nstype, const char *file, int line)
|
||||||
|
Reference in New Issue
Block a user