aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 16b07bfac224..456329fd4ea3 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -687,11 +687,11 @@ static void exit_mm(struct task_struct * tsk)
687} 687}
688 688
689/* 689/*
690 * When we die, we re-parent all our children. 690 * When we die, we re-parent all our children, and try to:
691 * Try to give them to another thread in our thread 691 * 1. give them to another thread in our thread group, if such a member exists
692 * group, and if no such member exists, give it to 692 * 2. give it to the first ancestor process which prctl'd itself as a
693 * the child reaper process (ie "init") in our pid 693 * child_subreaper for its children (like a service manager)
694 * space. 694 * 3. give it to the init process (PID 1) in our pid namespace
695 */ 695 */
696static struct task_struct *find_new_reaper(struct task_struct *father) 696static struct task_struct *find_new_reaper(struct task_struct *father)
697 __releases(&tasklist_lock) 697 __releases(&tasklist_lock)
@@ -722,6 +722,29 @@ static struct task_struct *find_new_reaper(struct task_struct *father)
722 * forget_original_parent() must move them somewhere. 722 * forget_original_parent() must move them somewhere.
723 */ 723 */
724 pid_ns->child_reaper = init_pid_ns.child_reaper; 724 pid_ns->child_reaper = init_pid_ns.child_reaper;
725 } else if (father->signal->has_child_subreaper) {
726 struct task_struct *reaper;
727
728 /*
729 * Find the first ancestor marked as child_subreaper.
730 * Note that the code below checks same_thread_group(reaper,
731 * pid_ns->child_reaper). This is what we need to DTRT in a
732 * PID namespace. However we still need the check above, see
733 * http://marc.info/?l=linux-kernel&m=131385460420380
734 */
735 for (reaper = father->real_parent;
736 reaper != &init_task;
737 reaper = reaper->real_parent) {
738 if (same_thread_group(reaper, pid_ns->child_reaper))
739 break;
740 if (!reaper->signal->is_child_subreaper)
741 continue;
742 thread = reaper;
743 do {
744 if (!(thread->flags & PF_EXITING))
745 return reaper;
746 } while_each_thread(reaper, thread);
747 }
725 } 748 }
726 749
727 return pid_ns->child_reaper; 750 return pid_ns->child_reaper;