Commit fd8e5884 authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

restore: block SIGCHILD for sub-processes (v2)

Otherwise sigchld_handler() will call waitpid()
and worries about unknown process.

(00.333012)      1: kernel/hostname nr 15
(00.333120)      1: kernel/domainname nr 6
(00.335243)      1: Error (cr-restore.c:1225): BUG at cr-restore.c:1225

v2: don't use unitialized oldmask

Cc: Tycho Andersen <tycho.andersen@canonical.com>
Reported-by: Mr Jenkins
Signed-off-by: 's avatarAndrew Vagin <avagin@openvz.org>
Acked-by: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 6a51c7ec
......@@ -196,6 +196,7 @@ static int __userns_sysctl_op(void *arg, int unused, pid_t pid)
struct sysctl_userns_req *userns_req = arg;
int op = userns_req->op;
struct sysctl_req *req, **reqs = NULL;
sigset_t blockmask, oldmask;
pid_t worker;
// fix up the pointer
......@@ -266,6 +267,16 @@ static int __userns_sysctl_op(void *arg, int unused, pid_t pid)
req = (struct sysctl_req *) (((char *) req) + total_len);
}
/*
* Don't let the sigchld_handler() mess with us
* calling waitpid() on the exited worker. The
* same is done in cr_system().
*/
sigemptyset(&blockmask);
sigaddset(&blockmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &blockmask, &oldmask);
worker = fork();
if (worker < 0)
goto out;
......@@ -297,10 +308,11 @@ static int __userns_sysctl_op(void *arg, int unused, pid_t pid)
}
if (waitpid(worker, &status, 0) != worker) {
pr_err("worker didn't die?");
pr_perror("worker didn't die?");
kill(worker, SIGKILL);
goto out;
}
sigprocmask(SIG_BLOCK, &oldmask, NULL);
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
pr_err("worker failed: %d\n", status);
......
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