diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 28d9feedfd27..fd0e067952ab 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 | ||
50 | extern void sem_exit (void); | 51 | extern void sem_exit (void); |
51 | extern struct task_struct *child_reaper; | ||
52 | 52 | ||
53 | static void exit_mm(struct task_struct * tsk); | 53 | static 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 | */ |
667 | static void | 669 | static void |
668 | forget_original_parent(struct task_struct *father, struct list_head *to_release) | 670 | forget_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; |