diff -NurpP --minimal linux-3.5.7-vs2.3.4.3/kernel/exit.c linux-3.5.7-vs2.3.4.3.2/kernel/exit.c --- linux-3.5.7-vs2.3.4.3/kernel/exit.c 2012-08-11 15:15:02.000000000 +0200 +++ linux-3.5.7-vs2.3.4.3.2/kernel/exit.c 2012-11-30 09:05:07.000000000 +0100 @@ -717,15 +717,25 @@ static struct task_struct *find_new_reap __acquires(&tasklist_lock) { struct pid_namespace *pid_ns = task_active_pid_ns(father); - struct task_struct *thread; + struct vx_info *vxi = task_get_vx_info(father); + struct task_struct *thread = father; + struct task_struct *reaper; - thread = father; while_each_thread(father, thread) { if (thread->flags & PF_EXITING) continue; if (unlikely(pid_ns->child_reaper == father)) pid_ns->child_reaper = thread; - return thread; + reaper = thread; + goto out_put; + } + + reaper = pid_ns->child_reaper; + if (vxi) { + BUG_ON(!vxi->vx_reaper); + if (vxi->vx_reaper != init_pid_ns.child_reaper && + vxi->vx_reaper != father) + reaper = vxi->vx_reaper; } if (unlikely(pid_ns->child_reaper == father)) { @@ -763,7 +773,9 @@ static struct task_struct *find_new_reap } } - return pid_ns->child_reaper; +out_put: + put_vx_info(vxi); + return reaper; } /* @@ -814,10 +826,15 @@ static void forget_original_parent(struc list_for_each_entry_safe(p, n, &father->children, sibling) { struct task_struct *t = p; do { - t->real_parent = reaper; + struct task_struct *new_parent = reaper; + + if (unlikely(p == reaper)) + new_parent = task_active_pid_ns(p)->child_reaper; + + t->real_parent = new_parent; if (t->parent == father) { BUG_ON(t->ptrace); - t->parent = t->real_parent; + t->parent = new_parent; } if (t->pdeath_signal) group_send_sig_info(t->pdeath_signal,