From: Sukadev Bhattiprolu <[EMAIL PROTECTED]> Terminate all processes in a namespace when the reaper of the namespace is exiting. We do this by walking the pidmap of the namespace and sending SIGKILL to all processes.
Signed-off-by: Sukadev Bhattiprolu <[EMAIL PROTECTED]> Acked-by: Pavel Emelyanov <[EMAIL PROTECTED]> --- include/linux/pid.h | 1 + include/linux/wait.h | 4 ++++ kernel/exit.c | 10 ++++++---- kernel/pid.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) diff -upr linux-2.6.23-rc1-mm1.orig/include/linux/pid.h linux-2.6.23-rc1-mm1-7/include/linux/pid.h --- linux-2.6.23-rc1-mm1.orig/include/linux/pid.h 2007-07-26 16:34:45.000000000 +0400 +++ linux-2.6.23-rc1-mm1-7/include/linux/pid.h 2007-07-26 16:36:37.000000000 +0400 @@ -83,6 +92,7 @@ extern void FASTCALL(detach_pid(struct t extern struct pid *alloc_pid(struct pid_namespace *ns); extern void FASTCALL(free_pid(struct pid *pid)); +extern void zap_pid_ns_processes(struct pid_namespace *pid_ns); /* * the helpers to get the pid's id seen from different namespaces diff -upr linux-2.6.23-rc1-mm1.orig/include/linux/wait.h linux-2.6.23-rc1-mm1-7/include/linux/wait.h --- linux-2.6.23-rc1-mm1.orig/include/linux/wait.h 2007-07-26 16:34:45.000000000 +0400 +++ linux-2.6.23-rc1-mm1-7/include/linux/wait.h 2007-07-26 16:36:36.000000000 +0400 @@ -22,9 +22,13 @@ #include <linux/list.h> #include <linux/stddef.h> #include <linux/spinlock.h> +#include <linux/resource.h> +#include <asm/siginfo.h> #include <asm/system.h> #include <asm/current.h> +long do_wait(pid_t pid, int options, struct siginfo __user *infop, + int __user *stat_addr, struct rusage __user *ru); typedef struct __wait_queue wait_queue_t; typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key); int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); diff -upr linux-2.6.23-rc1-mm1.orig/kernel/exit.c linux-2.6.23-rc1-mm1-7/kernel/exit.c --- linux-2.6.23-rc1-mm1.orig/kernel/exit.c 2007-07-26 16:34:45.000000000 +0400 +++ linux-2.6.23-rc1-mm1-7/kernel/exit.c 2007-07-26 16:36:37.000000000 +0400 @@ -895,6 +915,7 @@ fastcall NORET_TYPE void do_exit(long co { struct task_struct *tsk = current; int group_dead; + struct pid_namespace *pid_ns = tsk->nsproxy->pid_ns; profile_task_exit(tsk); @@ -905,9 +926,10 @@ fastcall NORET_TYPE void do_exit(long co if (unlikely(!tsk->pid)) panic("Attempted to kill the idle task!"); if (unlikely(tsk == task_child_reaper(tsk))) { - if (task_active_pid_ns(tsk) != &init_pid_ns) - task_active_pid_ns(tsk)->child_reaper = - init_pid_ns.child_reaper; + if (pid_ns != &init_pid_ns) { + zap_pid_ns_processes(pid_ns); + pid_ns->child_reaper = init_pid_ns.child_reaper; + } else panic("Attempted to kill init!"); } @@ -1518,7 +1548,7 @@ static inline int my_ptrace_child(struct return (p->parent != p->real_parent); } -static long do_wait(pid_t pid, int options, struct siginfo __user *infop, +long do_wait(pid_t pid, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { DECLARE_WAITQUEUE(wait, current); diff -upr linux-2.6.23-rc1-mm1.orig/kernel/pid.c linux-2.6.23-rc1-mm1-7/kernel/pid.c --- linux-2.6.23-rc1-mm1.orig/kernel/pid.c 2007-07-26 16:34:45.000000000 +0400 +++ linux-2.6.23-rc1-mm1-7/kernel/pid.c 2007-07-26 16:36:37.000000000 +0400 @@ -428,6 +520,44 @@ err_alloc: return new_ns; } +void zap_pid_ns_processes(struct pid_namespace *pid_ns) +{ + int i; + int nr; + int nfree; + int options = WNOHANG|WEXITED|__WALL; + +repeat: + /* + * We know pid == 1 is terminating. Find remaining pid_ts + * in the namespace, signal them and then wait for them + * exit. + */ + nr = next_pidmap(pid_ns, 1); + while (nr > 0) { + kill_proc_info(SIGKILL, SEND_SIG_PRIV, nr); + nr = next_pidmap(pid_ns, nr); + } + + nr = next_pidmap(pid_ns, 1); + while (nr > 0) { + do_wait(nr, options, NULL, NULL, NULL); + nr = next_pidmap(pid_ns, nr); + } + + nfree = 0; + for (i = 0; i < PIDMAP_ENTRIES; i++) + nfree += atomic_read(&pid_ns->pidmap[i].nr_free); + + /* + * If pidmap has entries for processes other than 0 and 1, retry. + */ + if (nfree < (BITS_PER_PAGE * PIDMAP_ENTRIES - 2)) + goto repeat; + + return; +} + static void do_free_pid_ns(struct work_struct *w) { struct pid_namespace *ns, *parent; _______________________________________________ Devel mailing list Devel@openvz.org https://openvz.org/mailman/listinfo/devel