diff -NurpP linux-2.6.16-rc4-vs2.1.1-rc9/kernel/exit.c linux-2.6.16-rc4-vs2.1.1-rc9.1/kernel/exit.c --- linux-2.6.16-rc4-vs2.1.1-rc9/kernel/exit.c 2006-02-24 16:28:25 +0100 +++ linux-2.6.16-rc4-vs2.1.1-rc9.1/kernel/exit.c 2006-02-27 13:15:21 +0100 @@ -610,24 +615,23 @@ static void reparent_thread(task_t *p, t } } -static inline -struct task_struct *vchild_reaper(struct task_struct *father) +static inline +struct task_struct *vchild_reaper(struct task_struct *task) { struct vx_info *vxi; struct task_struct *reaper, *init; reaper = child_reaper; - vxi = task_get_vx_info(father); + vxi = task_get_vx_info(task); if (!vxi) goto out; - if (!vxi->vx_initpid) + if (!vxi->vx_initpid) goto out_put; init = find_task_by_real_pid(vxi->vx_initpid); - if (init && (init != father)) - reaper = init; - + if (init && (init != task)) + reaper = init; out_put: put_vx_info(vxi); out: @@ -669,12 +677,15 @@ static void forget_original_parent(struc ptrace = p->ptrace; + /* check for reaper context */ + BUG_ON(p->xid != reaper->xid); + /* if father isn't the real parent, then ptrace must be enabled */ BUG_ON(father != p->real_parent && !ptrace); if (father == p->real_parent) { /* reparent with a reaper, real father it's us */ - choose_new_parent(p, reaper); + choose_new_parent(p, (p == reaper) ? child_reaper : reaper); reparent_thread(p, father, 0); } else { /* reparent ptraced task to its real parent */ @@ -695,6 +706,10 @@ static void forget_original_parent(struc } list_for_each_safe(_p, _n, &father->ptrace_children) { p = list_entry(_p,struct task_struct,ptrace_list); + + /* check for reaper context */ + BUG_ON(p->xid != reaper->xid); + choose_new_parent(p, reaper); reparent_thread(p, father, 1); }