diff -NurpP linux-2.6.16-rc4-vs2.1.1-rc7/kernel/exit.c linux-2.6.16-rc4-vs2.1.1-rc7.1/kernel/exit.c --- linux-2.6.16-rc4-vs2.1.1-rc7/kernel/exit.c 2006-02-18 18:06:47 +0100 +++ linux-2.6.16-rc4-vs2.1.1-rc7.1/kernel/exit.c 2006-02-20 21:57:58 +0100 @@ -542,7 +542,7 @@ static void exit_mm(struct task_struct * mmput(mm); } -static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_reaper) +static inline void choose_new_parent(task_t *p, task_t *reaper) { /* * Make sure we're not reparenting to ourselves and that @@ -610,6 +610,29 @@ static void reparent_thread(task_t *p, t } } +static inline +struct task_struct *vchild_reaper(struct task_struct *father) +{ + struct vx_info *vxi; + struct task_struct *reaper, *init; + + reaper = child_reaper; + vxi = task_get_vx_info(father); + if (!vxi) + goto out; + + if (!vxi->vx_initpid) + goto out_put; + + init = find_task_by_real_pid(vxi->vx_initpid); + if (init) + reaper = init; +out_put: + put_vx_info(vxi); +out: + return reaper; +} + /* * When we die, we re-parent all our children. * Try to give them to another thread in our thread @@ -626,7 +649,7 @@ static void forget_original_parent(struc do { reaper = next_thread(reaper); if (reaper == father) { - reaper = child_reaper; + reaper = vchild_reaper(father); break; } } while (reaper->exit_state); @@ -650,7 +673,7 @@ static void forget_original_parent(struc if (father == p->real_parent) { /* reparent with a reaper, real father it's us */ - choose_new_parent(p, reaper, child_reaper); + choose_new_parent(p, reaper); reparent_thread(p, father, 0); } else { /* reparent ptraced task to its real parent */ @@ -671,7 +694,7 @@ static void forget_original_parent(struc } list_for_each_safe(_p, _n, &father->ptrace_children) { p = list_entry(_p,struct task_struct,ptrace_list); - choose_new_parent(p, reaper, child_reaper); + choose_new_parent(p, reaper); reparent_thread(p, father, 1); } }