--- ../linux-2.6.19.3//kernel/exit.c 2007-02-06 02:42:30 +0100 +++ ./kernel/exit.c 2007-02-06 02:34:11 +0100 @@ -41,6 +41,10 @@ #include /* for audit_free() */ #include #include +#include +#include +#include +#include #include #include @@ -400,7 +404,7 @@ void daemonize(const char *name, ...) current->fs = fs; atomic_inc(&fs->count); - exit_task_namespaces(current); + put_and_finalize_nsproxy(current->nsproxy); current->nsproxy = init_task.nsproxy; get_task_namespaces(current); @@ -437,9 +441,11 @@ static void close_files(struct files_str struct file * file = xchg(&fdt->fd[i], NULL); if (file) filp_close(file, files); + vx_openfd_dec(i); } i++; set >>= 1; + cond_resched(); } } } @@ -521,6 +527,7 @@ static inline void __put_fs_struct(struc dput(fs->altroot); mntput(fs->altrootmnt); } + atomic_dec(&vs_global_fs); kmem_cache_free(fs_cachep, fs); } } @@ -592,6 +599,11 @@ static void exit_mm(struct task_struct * static inline void choose_new_parent(struct task_struct *p, struct task_struct *reaper) { + /* check for reaper context */ + vxwprintk((p->xid != reaper->xid) && (reaper != child_reaper), + "rogue reaper: %p[%d,#%u] <> %p[%d,#%u]", + p, p->pid, p->xid, reaper, reaper->pid, reaper->xid); + /* * Make sure we're not reparenting to ourselves and that * the parent is not a zombie. @@ -681,7 +693,7 @@ forget_original_parent(struct task_struc do { reaper = next_thread(reaper); if (reaper == father) { - reaper = child_reaper; + reaper = vx_child_reaper(father); break; } } while (reaper->exit_state); @@ -705,7 +717,7 @@ forget_original_parent(struct task_struc if (father == p->real_parent) { /* reparent with a reaper, real father it's us */ - choose_new_parent(p, reaper); + choose_new_parent(p, vx_child_reaper(p)); reparent_thread(p, father, 0); } else { /* reparent ptraced task to its real parent */ @@ -858,6 +870,7 @@ fastcall NORET_TYPE void do_exit(long co { struct task_struct *tsk = current; struct taskstats *tidstats; + struct nsproxy *ns; int group_dead; unsigned int mycpu; @@ -941,8 +954,11 @@ fastcall NORET_TYPE void do_exit(long co tsk->exit_code = code; proc_exit_connector(tsk); + /* needs to stay before exit_notify() */ + ns = exit_task_namespaces_early(tsk); + exit_vx_info_early(tsk, code); exit_notify(tsk); - exit_task_namespaces(tsk); + exit_task_namespaces(tsk, ns); #ifdef CONFIG_NUMA mpol_free(tsk->mempolicy); tsk->mempolicy = NULL; @@ -966,6 +982,10 @@ fastcall NORET_TYPE void do_exit(long co if (tsk->splice_pipe) __free_pipe_info(tsk->splice_pipe); + /* needs to stay after exit_notify() */ + exit_vx_info(tsk, code); + exit_nx_info(tsk); + preempt_disable(); /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD;