aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
authorSukadev Bhattiprolu <sukadev@us.ibm.com>2006-12-08 05:38:01 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:52 -0500
commit84d737866e2babdeab0c6b18ea155c6a649663b8 (patch)
treee504da826174c2804d8c680828800aa680090686 /kernel/exit.c
parent6cc1b22a4acef3816eaa5f8c227d93d749b23195 (diff)
[PATCH] add child reaper to pid_namespace
Add a per pid_namespace child-reaper. This is needed so processes are reaped within the same pid space and do not spill over to the parent pid space. Its also needed so containers preserve existing semantic that pid == 1 would reap orphaned children. This is based on Eric Biederman's patch: http://lkml.org/lkml/2006/2/6/285 Signed-off-by: Sukadev Bhattiprolu <sukadev@us.ibm.com> Signed-off-by: Cedric Le Goater <clg@fr.ibm.com> Cc: Kirill Korotaev <dev@openvz.org> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Herbert Poetzl <herbert@13thfloor.at> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 28d9feedfd2..fd0e067952a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -22,6 +22,7 @@
22#include <linux/file.h> 22#include <linux/file.h>
23#include <linux/binfmts.h> 23#include <linux/binfmts.h>
24#include <linux/nsproxy.h> 24#include <linux/nsproxy.h>
25#include <linux/pid_namespace.h>
25#include <linux/ptrace.h> 26#include <linux/ptrace.h>
26#include <linux/profile.h> 27#include <linux/profile.h>
27#include <linux/mount.h> 28#include <linux/mount.h>
@@ -48,7 +49,6 @@
48#include <asm/mmu_context.h> 49#include <asm/mmu_context.h>
49 50
50extern void sem_exit (void); 51extern void sem_exit (void);
51extern struct task_struct *child_reaper;
52 52
53static void exit_mm(struct task_struct * tsk); 53static void exit_mm(struct task_struct * tsk);
54 54
@@ -260,7 +260,8 @@ static int has_stopped_jobs(int pgrp)
260} 260}
261 261
262/** 262/**
263 * reparent_to_init - Reparent the calling kernel thread to the init task. 263 * reparent_to_init - Reparent the calling kernel thread to the init task
264 * of the pid space that the thread belongs to.
264 * 265 *
265 * If a kernel thread is launched as a result of a system call, or if 266 * If a kernel thread is launched as a result of a system call, or if
266 * it ever exits, it should generally reparent itself to init so that 267 * it ever exits, it should generally reparent itself to init so that
@@ -278,8 +279,8 @@ static void reparent_to_init(void)
278 ptrace_unlink(current); 279 ptrace_unlink(current);
279 /* Reparent to init */ 280 /* Reparent to init */
280 remove_parent(current); 281 remove_parent(current);
281 current->parent = child_reaper; 282 current->parent = child_reaper(current);
282 current->real_parent = child_reaper; 283 current->real_parent = child_reaper(current);
283 add_parent(current); 284 add_parent(current);
284 285
285 /* Set the exit signal to SIGCHLD so we signal init on exit */ 286 /* Set the exit signal to SIGCHLD so we signal init on exit */
@@ -662,7 +663,8 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
662 * When we die, we re-parent all our children. 663 * When we die, we re-parent all our children.
663 * Try to give them to another thread in our thread 664 * Try to give them to another thread in our thread
664 * group, and if no such member exists, give it to 665 * group, and if no such member exists, give it to
665 * the global child reaper process (ie "init") 666 * the child reaper process (ie "init") in our pid
667 * space.
666 */ 668 */
667static void 669static void
668forget_original_parent(struct task_struct *father, struct list_head *to_release) 670forget_original_parent(struct task_struct *father, struct list_head *to_release)
@@ -673,7 +675,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
673 do { 675 do {
674 reaper = next_thread(reaper); 676 reaper = next_thread(reaper);
675 if (reaper == father) { 677 if (reaper == father) {
676 reaper = child_reaper; 678 reaper = child_reaper(father);
677 break; 679 break;
678 } 680 }
679 } while (reaper->exit_state); 681 } while (reaper->exit_state);
@@ -859,8 +861,13 @@ fastcall NORET_TYPE void do_exit(long code)
859 panic("Aiee, killing interrupt handler!"); 861 panic("Aiee, killing interrupt handler!");
860 if (unlikely(!tsk->pid)) 862 if (unlikely(!tsk->pid))
861 panic("Attempted to kill the idle task!"); 863 panic("Attempted to kill the idle task!");
862 if (unlikely(tsk == child_reaper)) 864 if (unlikely(tsk == child_reaper(tsk))) {
863 panic("Attempted to kill init!"); 865 if (tsk->nsproxy->pid_ns != &init_pid_ns)
866 tsk->nsproxy->pid_ns->child_reaper = init_pid_ns.child_reaper;
867 else
868 panic("Attempted to kill init!");
869 }
870
864 871
865 if (unlikely(current->ptrace & PT_TRACE_EXIT)) { 872 if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
866 current->ptrace_message = code; 873 current->ptrace_message = code;