Index: linux/fs/exec.c =================================================================== --- linux.orig/fs/exec.c 2003-09-03 17:52:00.000000000 -0400 +++ linux/fs/exec.c 2003-09-03 17:52:04.000000000 -0400 @@ -38,6 +38,7 @@ #include #define __NO_VERSION__ #include +#include #include #include @@ -953,9 +954,11 @@ xa_call_actions (XA_EXEC, XA_KOE, NULL); retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + if (retval >= 0) { /* execve success */ + bproc_hook_im(do_execve,()); return retval; + } out: /* Something went wrong, return the inode and free the argument pages*/ Index: linux/fs/binfmt_script.c =================================================================== --- linux.orig/fs/binfmt_script.c 2002-08-02 20:39:45.000000000 -0400 +++ linux/fs/binfmt_script.c 2003-09-03 17:52:04.000000000 -0400 @@ -13,6 +13,7 @@ #include #include #include +#include static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) { @@ -67,7 +68,7 @@ * user environment and arguments are stored. */ remove_arg_zero(bprm); - retval = copy_strings_kernel(1, &bprm->filename, bprm); + retval = copy_strings_kernel(1,bproc_hook_v(&bprm->filename,load_script,(&bprm->filename)), bprm); if (retval < 0) return retval; bprm->argc++; if (i_arg) { Index: linux/fs/binfmt_elf.c =================================================================== --- linux.orig/fs/binfmt_elf.c 2002-08-02 20:39:45.000000000 -0400 +++ linux/fs/binfmt_elf.c 2003-09-03 17:52:04.000000000 -0400 @@ -73,7 +73,7 @@ #define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1)) #define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1)) -static struct linux_binfmt elf_format = { +struct linux_binfmt elf_format = { NULL, THIS_MODULE, load_elf_binary, load_elf_library, elf_core_dump, ELF_EXEC_PAGESIZE }; Index: linux/fs/proc/base.c =================================================================== --- linux.orig/fs/proc/base.c 2003-09-03 17:52:00.000000000 -0400 +++ linux/fs/proc/base.c 2003-09-03 17:52:04.000000000 -0400 @@ -25,6 +25,7 @@ #include #include #include +#include /* * For hysterical raisins we keep the same inumbers as in the old procfs. @@ -304,6 +305,7 @@ if (!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; + if (bproc_isghost(task)) bproc_hook(refresh_status,(task)); length = inode->u.proc_i.op.proc_read(task, (char*)page); if (length < 0) { @@ -976,14 +978,14 @@ static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen) { char tmp[30]; - sprintf(tmp, "%d", current->pid); + sprintf(tmp, "%d", bproc_hook_imv(current->pid,proc3,())); return vfs_readlink(dentry,buffer,buflen,tmp); } static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) { char tmp[30]; - sprintf(tmp, "%d", current->pid); + sprintf(tmp, "%d", bproc_hook_imv(current->pid,proc3,())); return vfs_follow_link(nd,tmp); } @@ -1031,6 +1033,7 @@ goto out; } + pid = bproc_hook_imv(pid,proc2,(pid)); read_lock(&tasklist_lock); task = find_task_by_pid(pid); if (task) @@ -1082,7 +1085,7 @@ index--; read_lock(&tasklist_lock); for_each_task(p) { - int pid = p->pid; + int pid = bproc_hook_imv(p->pid,proc1,(p)); if (!pid) continue; if (--index >= 0) Index: linux/fs/proc/array.c =================================================================== --- linux.orig/fs/proc/array.c 2002-08-02 20:39:45.000000000 -0400 +++ linux/fs/proc/array.c 2003-09-03 17:52:04.000000000 -0400 @@ -70,6 +70,7 @@ #include #include #include +#include #include #include @@ -130,7 +131,8 @@ static inline const char * get_task_state(struct task_struct *tsk) { - unsigned int state = tsk->state & (TASK_RUNNING | + unsigned int state = (bproc_hook_v(tsk->state,get_task_state,(tsk))) + & (TASK_RUNNING | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE | TASK_ZOMBIE | @@ -158,7 +160,8 @@ "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), p->tgid, - p->pid, p->pid ? p->p_opptr->pid : 0, 0, + bproc_hook_imv(p->pid, proc_pid, (p)), + bproc_hook_imv(p->p_opptr->pid, proc_ppid, (p)), 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); read_unlock(&tasklist_lock); @@ -305,7 +308,7 @@ sigset_t sigign, sigcatch; char state; int res; - pid_t ppid; + pid_t pid, ppid; struct mm_struct *mm; state = *get_task_state(task); @@ -343,12 +346,14 @@ nice = task->nice; read_lock(&tasklist_lock); - ppid = task->pid ? task->p_opptr->pid : 0; + pid = bproc_hook_imv(task->pid, proc_pid, (task)), + ppid = bproc_hook_imv(task->pid ? task->p_opptr->pid : 0, + proc_ppid, (task)); read_unlock(&tasklist_lock); res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d\n", - task->pid, + pid, task->comm, state, ppid, Index: linux/kernel/timer.c =================================================================== --- linux.orig/kernel/timer.c 2003-09-03 17:51:01.000000000 -0400 +++ linux/kernel/timer.c 2003-09-03 17:52:04.000000000 -0400 @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -754,7 +755,7 @@ */ asmlinkage long sys_getpid(void) { - return current->tgid; + return bproc_hook_imv(current->tgid, sys_getpid, ()); } /* @@ -788,7 +789,7 @@ parent = me->p_opptr; for (;;) { - pid = parent->pid; + pid = bproc_hook_imv(parent->pid,sys_getppid,(parent)); #if CONFIG_SMP { struct task_struct *old = parent; Index: linux/kernel/signal.c =================================================================== --- linux.orig/kernel/signal.c 2003-09-03 17:51:01.000000000 -0400 +++ linux/kernel/signal.c 2003-09-03 17:52:04.000000000 -0400 @@ -16,6 +16,8 @@ #include +#include + /* * SLAB caches for signal bits. */ @@ -548,6 +550,9 @@ if (sig < SIGRTMIN && sigismember(&t->pending.signal, sig)) goto out; + if (bproc_hook_v(0, send_sig_info, (sig, info, t))) + goto out; + ret = deliver_signal(sig, info, t); out: spin_unlock_irqrestore(&t->sigmask_lock, flags); @@ -590,6 +595,9 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) { int retval = -EINVAL; + + if (bproc_hook_imv(0,kill_pg_info, (sig, info, &pgrp, &retval)) == 1) + return retval; if (pgrp > 0) { struct task_struct *p; @@ -617,6 +625,7 @@ kill_sl_info(int sig, struct siginfo *info, pid_t sess) { int retval = -EINVAL; + /* XXX bproc: Need ways to deal with session leaders...*/ if (sess > 0) { struct task_struct *p; @@ -640,6 +649,9 @@ int error; struct task_struct *p; + if (bproc_hook_imv(0, kill_proc_info,(sig, info, &pid, &error)) == 1) + return error; + read_lock(&tasklist_lock); p = find_task_by_pid(pid); error = -ESRCH; @@ -684,6 +696,7 @@ read_unlock(&tasklist_lock); return count ? retval : -ESRCH; } else if (pid < 0) { + /* XXX pid masq - do PG stuff. */ return kill_pg_info(sig, info, -pid); } else { return kill_proc_info(sig, info, pid); @@ -815,6 +828,7 @@ EXPORT_SYMBOL(recalc_sigpending); EXPORT_SYMBOL(send_sig); EXPORT_SYMBOL(send_sig_info); +EXPORT_SYMBOL(kill_something_info); EXPORT_SYMBOL(block_all_signals); EXPORT_SYMBOL(unblock_all_signals); Index: linux/kernel/sched.c =================================================================== --- linux.orig/kernel/sched.c 2003-09-03 17:51:05.000000000 -0400 +++ linux/kernel/sched.c 2003-09-03 17:52:04.000000000 -0400 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -370,6 +371,8 @@ inline int wake_up_process(struct task_struct * p) { + if (p->state == TASK_STOPPED && bproc_ismasq(p)) + bproc_hook(wake_up_process, (p)); return try_to_wake_up(p, 0); } Index: linux/kernel/ksyms.c =================================================================== --- linux.orig/kernel/ksyms.c 2003-09-03 17:52:02.000000000 -0400 +++ linux/kernel/ksyms.c 2003-09-03 17:52:04.000000000 -0400 @@ -68,6 +68,10 @@ extern void set_device_ro(kdev_t dev,int flag); extern void *sys_call_table; +extern struct task_struct *child_reaper; +#if defined(CONFIG_BINFMT_ELF) +extern struct linux_binfmt elf_format; +#endif extern struct timezone sys_tz; extern int request_dma(unsigned int dmanr, char * deviceID); @@ -104,9 +108,17 @@ EXPORT_SYMBOL(do_munmap); EXPORT_SYMBOL(do_brk); EXPORT_SYMBOL(exit_mm); +EXPORT_SYMBOL(do_exit); EXPORT_SYMBOL(exit_files); EXPORT_SYMBOL(exit_fs); EXPORT_SYMBOL(exit_sighand); +EXPORT_SYMBOL(is_orphaned_pgrp); +EXPORT_SYMBOL(child_reaper); +#if defined(CONFIG_BINFMT_ELF) +EXPORT_SYMBOL(elf_format); +#endif +EXPORT_SYMBOL(alloc_uid); +EXPORT_SYMBOL(free_uid); EXPORT_SYMBOL(copy_fs_struct); EXPORT_SYMBOL_GPL(make_pages_present); @@ -584,6 +596,7 @@ EXPORT_SYMBOL(read_ahead); EXPORT_SYMBOL(get_hash_table); EXPORT_SYMBOL(new_inode); +EXPORT_SYMBOL(get_empty_inode); EXPORT_SYMBOL(insert_inode_hash); EXPORT_SYMBOL(remove_inode_hash); EXPORT_SYMBOL(buffer_insert_inode_queue); Index: linux/kernel/fork.c =================================================================== --- linux.orig/kernel/fork.c 2003-09-03 17:52:00.000000000 -0400 +++ linux/kernel/fork.c 2003-09-03 17:52:04.000000000 -0400 @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -413,6 +415,7 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk) { + if (!current->fs) return 0; if (clone_flags & CLONE_FS) { atomic_inc(¤t->fs->count); return 0; @@ -781,7 +784,8 @@ * * Let it rip! */ - retval = p->pid; + if ((retval = bproc_hook_v(p->pid, do_fork, (p, clone_flags))) < 0) + goto bad_fork_cleanup_mm; p->tgid = retval; INIT_LIST_HEAD(&p->thread_group); @@ -805,6 +809,7 @@ SET_LINKS(p); hash_pid(p); nr_threads++; + bproc_hook(do_fork_2, (p)); write_unlock_irq(&tasklist_lock); if (p->ptrace & PT_PTRACED) @@ -816,6 +821,7 @@ wait_for_completion(&vfork); fork_out: + bproc_clear_kcall(); return retval; bad_fork_cleanup_namespace: Index: linux/kernel/exit.c =================================================================== --- linux.orig/kernel/exit.c 2003-09-03 17:52:00.000000000 -0400 +++ linux/kernel/exit.c 2003-09-03 17:52:04.000000000 -0400 @@ -22,6 +22,8 @@ #include #include +#include + extern void sem_exit (void); extern struct task_struct *child_reaper; @@ -47,6 +49,7 @@ } task_unlock(p); #endif + bproc_hook(release,(p)); atomic_dec(&p->user->processes); free_uid(p->user); unhash_process(p); @@ -130,7 +133,8 @@ int is_orphaned_pgrp(int pgrp) { - return will_become_orphaned_pgrp(pgrp, 0); + return bproc_hook_imv(will_become_orphaned_pgrp(pgrp, 0), + is_orphaned_pgrp,(pgrp)); } static inline int has_stopped_jobs(int pgrp) @@ -170,7 +174,7 @@ p->self_exec_id++; /* Make sure we're not reparenting to ourselves */ - p->p_opptr = child_reaper; + p->p_opptr = bproc_hook_v(child_reaper, child_reaper, (p)); if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0); } @@ -450,6 +454,7 @@ #endif __exit_mm(tsk); + bproc_hook(do_exit, (tsk,code)); lock_kernel(); sem_exit(); __exit_files(tsk); @@ -501,6 +506,7 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru) { int flag, retval; + pid_t orig_pid = pid; DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk; @@ -512,6 +518,9 @@ flag = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); + pid = orig_pid; + if (bproc_hook_imv(0, sys_wait4_1, (&pid, stat_addr, options, ru, &retval))) + goto end_wait4; /* handler will unlock tasklist_lock */ tsk = current; do { struct task_struct *p; @@ -535,7 +544,7 @@ && !(options & __WALL)) continue; flag = 1; - switch (p->state) { + switch (bproc_hook_v(p->state,sys_wait4_2,(p))) { case TASK_STOPPED: if (!p->exit_code) continue; @@ -547,7 +556,7 @@ retval = put_user((p->exit_code << 8) | 0x7f, stat_addr); if (!retval) { p->exit_code = 0; - retval = p->pid; + retval = bproc_hook_imv(p->pid, sys_wait4_3, (p)); } goto end_wait4; case TASK_ZOMBIE: @@ -559,7 +568,7 @@ retval = put_user(p->exit_code, stat_addr); if (retval) goto end_wait4; - retval = p->pid; + retval = bproc_hook_imv(p->pid, sys_wait4_3, (p)); if (p->p_opptr != p->p_pptr) { write_lock_irq(&tasklist_lock); REMOVE_LINKS(p); @@ -569,6 +578,7 @@ write_unlock_irq(&tasklist_lock); } else release_task(p); + bproc_hook_im(sys_wait4_4,(retval, options)); goto end_wait4; default: continue; @@ -593,6 +603,7 @@ end_wait4: current->state = TASK_RUNNING; remove_wait_queue(¤t->wait_chldexit,&wait); + bproc_clear_kcall(); return retval; } Index: linux/kernel/sys.c =================================================================== --- linux.orig/kernel/sys.c 2003-09-03 17:51:05.000000000 -0400 +++ linux/kernel/sys.c 2003-09-03 17:52:04.000000000 -0400 @@ -21,6 +21,8 @@ #include #include +#include + /* * this is where the system-wide overflow UID and GID are defined, for * architectures that now have 32-bit UID/GID but didn't in the past @@ -448,6 +450,7 @@ current->fsgid = new_egid; current->egid = new_egid; current->gid = new_rgid; + bproc_hook_im(set_creds, ()); return 0; } @@ -480,6 +483,7 @@ } else return -EPERM; + bproc_hook_im(set_creds, ()); return 0; } @@ -614,6 +618,7 @@ cap_emulate_setxuid(old_ruid, old_euid, old_suid); } + bproc_hook_im(set_creds, ()); return 0; } @@ -658,6 +663,8 @@ cap_emulate_setxuid(old_ruid, old_euid, old_suid); } + bproc_hook_im(set_creds, ()); + bproc_hook_im(set_creds, ()); return 0; } @@ -746,6 +753,7 @@ current->gid = rgid; if (sgid != (gid_t) -1) current->sgid = sgid; + bproc_hook_im(set_creds, ()); return 0; } @@ -803,6 +811,7 @@ } } + if (current->fsuid != old_fsuid) bproc_hook_im(set_creds, ()); return old_fsuid; } @@ -825,6 +834,8 @@ } current->fsgid = gid; } + + if (current->fsgid != old_fsgid) bproc_hook_im(set_creds, ()); return old_fsgid; } @@ -860,6 +871,8 @@ struct task_struct * p; int err = -EINVAL; + bproc_hook_imr(sys_setpgid1, (pid, pgid)); + if (!pid) pid = current->pid; if (!pgid) @@ -901,6 +914,7 @@ ok_pgid: p->pgrp = pgid; + if (bproc_isghost(p)) bproc_hook(sys_setpgid2, (p)); err = 0; out: /* All paths lead to here, thus we are safe. -DaveM */ @@ -910,6 +924,7 @@ asmlinkage long sys_getpgid(pid_t pid) { + bproc_hook_imr(sys_getpgid,(pid)); if (!pid) { return current->pgrp; } else { @@ -930,23 +945,25 @@ asmlinkage long sys_getpgrp(void) { /* SMP - assuming writes are word atomic this is fine */ - return current->pgrp; + return bproc_hook_imv(current->pgrp,sys_getpgrp,()); } asmlinkage long sys_getsid(pid_t pid) { if (!pid) { - return current->session; + return bproc_hook_imv(current->session,sys_getsid1,()); } else { int retval; struct task_struct *p; + if (bproc_hook_imv(0,sys_getsid2, (&pid, &retval))==1) + return retval; read_lock(&tasklist_lock); p = find_task_by_pid(pid); retval = -ESRCH; if(p) - retval = p->session; + retval = bproc_hook_imv(p->session,sys_getsid3,(p)); read_unlock(&tasklist_lock); return retval; } @@ -957,6 +974,8 @@ struct task_struct * p; int err = -EPERM; + bproc_hook_imr(sys_setsid,()); + read_lock(&tasklist_lock); for_each_task(p) { if (p->pgrp == current->pid) @@ -1011,6 +1030,7 @@ if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t))) return -EFAULT; current->ngroups = gidsetsize; + bproc_hook_im(set_creds, ()); return 0; } Index: linux/kernel/ptrace.c =================================================================== --- linux.orig/kernel/ptrace.c 2003-09-03 17:51:04.000000000 -0400 +++ linux/kernel/ptrace.c 2003-09-03 17:52:04.000000000 -0400 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -25,8 +26,13 @@ if (!(child->ptrace & PT_PTRACED)) return -ESRCH; - if (child->p_pptr != current) - return -ESRCH; + if (child->p_pptr != current && + !bproc_hook_v(0,ptrace_slave_call, + (PTRACE_DETACH, child, current->bproc.arg))) + return -ESRCH; + + if (bproc_isghost(child)) + return 0; if (!kill) { if (child->state != TASK_STOPPED) @@ -55,6 +61,7 @@ int ptrace_attach(struct task_struct *task) { + long ret; task_lock(task); if (task->pid <= 1) goto bad; @@ -83,16 +90,22 @@ task->ptrace |= PT_PTRACE_CAP; task_unlock(task); + ret = 0; write_lock_irq(&tasklist_lock); if (task->p_pptr != current) { + if (bproc_isghost(current) && !bproc_isghost(task)) ret = 1; REMOVE_LINKS(task); task->p_pptr = current; SET_LINKS(task); } + if (bproc_ismasq(task)) + bproc_hook(ptrace_attach, (task, current->bproc.arg, &ret)); write_unlock_irq(&tasklist_lock); - - send_sig(SIGSTOP, task, 1); - return 0; + if (bproc_isghost(task)) + bproc_hook(ptraceg,(PTRACE_ATTACH, task, 0, 0, &ret, 0)); + else + send_sig(SIGSTOP, task, 1); + return ret; bad: task_unlock(task); @@ -101,6 +114,7 @@ int ptrace_detach(struct task_struct *child, unsigned int data) { + long ret = 0; if ((unsigned long) data > _NSIG) return -EIO; @@ -111,14 +125,19 @@ child->ptrace = 0; child->exit_code = data; write_lock_irq(&tasklist_lock); + if (bproc_isghost(current) && !bproc_isghost(child) && + child->p_pptr != child->p_opptr) + ret = 1; REMOVE_LINKS(child); + if (bproc_ismasq(child)) + bproc_hook(ptrace_detach,(child,(long*)&ret)); child->p_pptr = child->p_opptr; SET_LINKS(child); write_unlock_irq(&tasklist_lock); /* .. and wake it up. */ wake_up_process(child); - return 0; + return ret; } /* Index: linux/kernel/Makefile =================================================================== --- linux.orig/kernel/Makefile 2003-09-03 17:51:06.000000000 -0400 +++ linux/kernel/Makefile 2003-09-03 17:52:04.000000000 -0400 @@ -9,7 +9,7 @@ O_TARGET := kernel.o -export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o +export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o bproc_hook.o obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ @@ -24,6 +24,7 @@ obj-$(CONFIG_MODULES) += ksyms.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_KALLSYMS) += kallsyms.o +obj-$(CONFIG_BPROC) += bproc_hook.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra , the -fno-omit-frame-pointer is Index: linux/kernel/bproc_hook.c =================================================================== --- linux.orig/kernel/bproc_hook.c 2003-09-03 17:52:04.000000000 -0400 +++ linux/kernel/bproc_hook.c 2003-09-03 17:52:04.000000000 -0400 @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * bproc_hook.c: Beowulf distributed PID space (bproc) definitions + * + * Copyright (C) 2000 by Erik Hendriks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Id: bproc-patch-2.4.20,v 1.8 2004/04/12 21:44:45 nic Exp $ + *-----------------------------------------------------------------------*/ +#include +#include +#include + +#define bprocdeclhook(ret,func,args) \ + ret (* bproc_hook_ ## func ## _hook) args = 0;\ + EXPORT_SYMBOL( bproc_hook_ ## func ## _hook ) + +#include + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ Index: linux/include/linux/sched.h =================================================================== --- linux.orig/include/linux/sched.h 2003-09-03 17:51:06.000000000 -0400 +++ linux/include/linux/sched.h 2003-09-03 17:52:04.000000000 -0400 @@ -430,6 +430,14 @@ /* journalling filesystem info */ void *journal_info; + +/* bproc */ + struct { + long flag; + long arg; + struct bproc_masq_proc_t *masq; + struct bproc_ghost_proc_t *ghost; + } bproc; }; /* @@ -526,6 +534,7 @@ alloc_lock: SPIN_LOCK_UNLOCKED, \ exit_actions: NULL, \ journal_info: NULL, \ + bproc: {0, 0, 0, 0} \ } Index: linux/include/linux/bproc.h =================================================================== --- linux.orig/include/linux/bproc.h 2003-09-03 17:52:04.000000000 -0400 +++ linux/include/linux/bproc.h 2003-09-03 17:52:04.000000000 -0400 @@ -0,0 +1,155 @@ +/*------------------------------------------------------------------------- + * bproc.h: Beowulf distributed PID space (bproc) definitions + * + * Copyright (C) 1999-2001 by Erik Hendriks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Id: bproc-patch-2.4.20,v 1.8 2004/04/12 21:44:45 nic Exp $ + *-----------------------------------------------------------------------*/ +#ifndef _LINUX_BPROC_H +#define _LINUX_BPROC_H + +#include +#include + +#ifdef CONFIG_BPROC + +#ifndef bprocdeclhook +/* Function pointers for bproc hooks. */ +#define bprocdeclhook(ret,func,args) extern ret (* bproc_hook_ ## func ## _hook) args +#endif + +struct bproc_ghost_proc_t; +struct task_struct; +struct rusage; +struct siginfo; + +/*----- fs/exec.c -------------------------------------------------------*/ +bprocdeclhook(void, do_execve, (void)); +/*----- fs/binfmt_script.c ----------------------------------------------*/ +bprocdeclhook(char**,load_script, (char **)); +/*----- fs/proc/array.c ----------------------------------------------------*/ +bprocdeclhook(void, refresh_status, (struct task_struct *)); +bprocdeclhook(int, get_task_state, (struct task_struct *)); +bprocdeclhook(int, proc_pid, (struct task_struct *)); +bprocdeclhook(int, proc_ppid, (struct task_struct *)); +bprocdeclhook(int, proc1, (struct task_struct *)); +bprocdeclhook(int, proc2, (int)); +bprocdeclhook(int, proc3, (void)); +/*----- kernel/timer.c --------------------------------------------------*/ +bprocdeclhook(int, sys_getpid, (void)); +bprocdeclhook(int, sys_getppid, (struct task_struct *)); +/*----- kernel/sched.c --------------------------------------------------*/ +bprocdeclhook(void, wake_up_process, (struct task_struct *)); +/*----- kernel/exit.c ---------------------------------------------------*/ +bprocdeclhook(void, release, (struct task_struct *)); +bprocdeclhook(int, is_orphaned_pgrp,(int)); +bprocdeclhook(struct task_struct *,child_reaper,(struct task_struct *)); +bprocdeclhook(void, do_exit, (struct task_struct *, long code)); +bprocdeclhook(int, sys_wait4_1, (pid_t *, unsigned int *, int, + struct rusage *, int *)); +bprocdeclhook(long, sys_wait4_2, (struct task_struct *)); +bprocdeclhook(int, sys_wait4_3, (struct task_struct *)); +bprocdeclhook(void, sys_wait4_4, (pid_t, int options)); +/*----- kernel/fork.c ---------------------------------------------------*/ +bprocdeclhook(int, do_fork, (struct task_struct *, unsigned long)); +bprocdeclhook(void, do_fork_2, (struct task_struct *)); +/*----- kernel/signal.c -------------------------------------------------*/ +bprocdeclhook(int, send_sig_info, (int, struct siginfo *, + struct task_struct *)); +bprocdeclhook(int, kill_pg_info, (int, struct siginfo *, pid_t *, int *)); +bprocdeclhook(int, kill_proc_info, (int, struct siginfo *, pid_t *, int *)); +/*----- kernel/sys.c ----------------------------------------------------*/ +bprocdeclhook(int, sys_setpgid1, (pid_t, pid_t)); +bprocdeclhook(void, sys_setpgid2, (struct task_struct *p)); +bprocdeclhook(int, sys_getpgid, (pid_t pid)); +bprocdeclhook(int, sys_getpgrp, (void)); +bprocdeclhook(int, sys_getsid1, (void)); +bprocdeclhook(int, sys_getsid2, (pid_t *pid, int *error)); +bprocdeclhook(int, sys_getsid3, (struct task_struct *p)); +bprocdeclhook(int, sys_setsid, (void)); +bprocdeclhook(void, set_creds, (void)); +/*----- arch/???/kernel/ptrace.c,signal.c -------------------------------*/ +bprocdeclhook(void, stop_notify, (int)); +bprocdeclhook(int, ptracem, (long, long *, long, long, + long *, long *)); +bprocdeclhook(void, ptrace_attach, (struct task_struct *, long, long *)); +bprocdeclhook(void, ptraceg, (long, struct task_struct *, long, + long, long *, long *)); +bprocdeclhook(int, ptrace_slave_call,(long, struct task_struct *, long)); +bprocdeclhook(void, ptrace_detach, (struct task_struct *, long *)); +bprocdeclhook(int, sys_execve, (struct pt_regs *, char *, + char **, char **)); + +/* Macro suffixes: + * (none) = execute this hook if it's present. + * im = if masq'ed + * nkc = no kernel call (kcall must be 0 to call hook) + * r = return the value of this hook + * v = hook returns a value. + */ +#define hookname(func) bproc_hook_ ## func ## _hook +#define bproc_hook(func,args) do{if(hookname(func))hookname(func)args;}while(0) +#define bproc_hook_im(func,args) do{if(hookname(func)&¤t->bproc.masq)hookname(func)args;}while(0) +#define bproc_hook_imr(func,args) do{if(hookname(func)&¤t->bproc.masq)return hookname(func)args;}while(0) +#define bproc_hook_v(defl,func,args) ( hookname(func) ?hookname(func)args:defl) +#define bproc_hook_imv(defl,func,args) ((hookname(func)&¤t->bproc.masq)?hookname(func)args:defl) + +#define bproc_isghost(tsk) ((tsk)->bproc.ghost != 0) +#define bproc_ismasq(tsk) ((tsk)->bproc.masq != 0) +#define bproc_set_arg(x) do{current->bproc.arg=(x);}while(0) + +/* Kernel call weirdness... a kernel call is a call made from the + * kernel which we do not want to be subject to the usual rules for + * PID masquerading. This is mostly used for drivers which create and + * possibly wait for kernel threads which they create. These + * functions are called from the relevant places within the kernel + * (like within kernel_thread) to set a flag so that things will be + * handled correctly later on. */ +static inline void bproc_no_kcall(void) { + current->bproc.flag = (current->bproc.flag & ~3) | 2; +} +static inline void bproc_clear_kcall(void) { + current->bproc.flag &= ~3; +} +static inline void bproc_kcall(void) { + if (current->bproc.flag & 2) + bproc_clear_kcall(); + else + current->bproc.flag |= 1; /* set kernel call flag */ +} + +#else +/* Stubs for when hooks are not compiled in */ +#define bproc_hook(func,args) do{}while(0) +#define bproc_hook_im(func,args) do{}while(0) +#define bproc_hook_imr(func,args) do{}while(0) +#define bproc_hook_v(defl,func,args) (defl) +#define bproc_hook_imv(defl,func,args) (defl) +#define bproc_isghost(tsk) (0) +#define bproc_ismasq(tsk) (0) +#define bproc_set_arg(x) do{}while(0) +#define bproc_no_kcall() do{}while(0) +#define bproc_clear_kcall() do{}while(0) +#define bproc_kcall() do{}while(0) +#endif +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * End: + */ Index: linux/include/asm-i386/unistd.h =================================================================== --- linux.orig/include/asm-i386/unistd.h 2002-11-28 18:53:15.000000000 -0500 +++ linux/include/asm-i386/unistd.h 2003-09-03 17:52:04.000000000 -0400 @@ -349,6 +349,7 @@ #ifdef __KERNEL_SYSCALLS__ +#include /* * we need this inline - forking from kernel space will result * in NO COPY ON WRITE (!!!), until an execve is executed. This @@ -373,7 +374,16 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode) static inline _syscall1(int,close,int,fd) static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +static inline pid_t waitpid(pid_t pid, int *wait_stat, int options) { + long __res; + bproc_kcall(); + __asm__ volatile ("int $0x80" + : "=a" (__res) + : "0" (__NR_waitpid),"b" ((long)(pid)),"c" ((long)(wait_stat)), + "d" ((long)(options))); + __syscall_return(pid_t,__res); +} + static inline _syscall1(int,delete_module,const char *,name) static inline pid_t wait(int * wait_stat) Index: linux/include/asm-alpha/unistd.h =================================================================== --- linux.orig/include/asm-alpha/unistd.h 2002-08-02 20:39:45.000000000 -0400 +++ linux/include/asm-alpha/unistd.h 2003-09-03 17:52:04.000000000 -0400 @@ -519,6 +519,7 @@ #include #include +#include extern void sys_idle(void); static inline void idle(void) @@ -591,11 +592,13 @@ static inline pid_t waitpid(int pid, int * wait_stat, int flags) { + bproc_kcall(); return sys_wait4(pid, wait_stat, flags, NULL); } static inline pid_t wait(int * wait_stat) { + bproc_kcall(); return waitpid(-1,wait_stat,0); } Index: linux/net/socket.c =================================================================== --- linux.orig/net/socket.c 2003-09-03 17:51:05.000000000 -0400 +++ linux/net/socket.c 2003-09-03 17:52:04.000000000 -0400 @@ -111,7 +111,7 @@ * in the operation structures but are done directly via the socketcall() multiplexor. */ -static struct file_operations socket_file_ops = { +struct file_operations socket_file_ops = { llseek: no_llseek, read: sock_read, write: sock_write, @@ -298,13 +298,13 @@ return sb; } -static struct vfsmount *sock_mnt; +struct vfsmount *sock_mnt; static DECLARE_FSTYPE(sock_fs_type, "sockfs", sockfs_read_super, FS_NOMOUNT); static int sockfs_delete_dentry(struct dentry *dentry) { return 1; } -static struct dentry_operations sockfs_dentry_operations = { +struct dentry_operations sockfs_dentry_operations = { d_delete: sockfs_delete_dentry, }; Index: linux/net/netsyms.c =================================================================== --- linux.orig/net/netsyms.c 2003-09-03 17:52:04.000000000 -0400 +++ linux/net/netsyms.c 2003-09-03 17:52:04.000000000 -0400 @@ -599,4 +599,11 @@ EXPORT_SYMBOL(wireless_send_event); #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ +extern struct vfsmount *sock_mnt; +extern struct dentry_operations sockfs_dentry_operations; +extern struct file_operations socket_file_ops; +EXPORT_SYMBOL(sock_mnt); +EXPORT_SYMBOL(sockfs_dentry_operations); +EXPORT_SYMBOL(socket_file_ops); + #endif /* CONFIG_NET */ Index: linux/arch/i386/config.in =================================================================== --- linux.orig/arch/i386/config.in 2003-09-03 17:51:06.000000000 -0400 +++ linux/arch/i386/config.in 2003-09-03 17:52:04.000000000 -0400 @@ -285,6 +285,7 @@ bool 'System V IPC' CONFIG_SYSVIPC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT +bool 'Beowulf Distributed Process Space' CONFIG_BPROC bool 'Sysctl support' CONFIG_SYSCTL if [ "$CONFIG_PROC_FS" = "y" ]; then choice 'Kernel core (/proc/kcore) format' \ Index: linux/arch/i386/kernel/signal.c =================================================================== --- linux.orig/arch/i386/kernel/signal.c 2002-08-02 20:39:42.000000000 -0400 +++ linux/arch/i386/kernel/signal.c 2003-09-03 17:52:04.000000000 -0400 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -612,6 +613,7 @@ /* Let the debugger run. */ current->exit_code = signr; current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(signr)); notify_parent(current, SIGCHLD); schedule(); @@ -670,6 +672,7 @@ struct signal_struct *sig; current->state = TASK_STOPPED; current->exit_code = signr; + bproc_hook_im(stop_notify,(signr)); sig = current->p_pptr->sig; if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); Index: linux/arch/i386/kernel/ptrace.c =================================================================== --- linux.orig/arch/i386/kernel/ptrace.c 2002-08-02 20:39:42.000000000 -0400 +++ linux/arch/i386/kernel/ptrace.c 2003-09-03 17:52:04.000000000 -0400 @@ -21,6 +21,8 @@ #include #include +#include + /* * does not yet catch signals sent when the child dies. * in exit.c or in signal.c. @@ -152,6 +154,15 @@ struct task_struct *child; struct user * dummy = NULL; int i, ret; + long orig_pid; + + orig_pid = pid; + retry_ptrace: + pid = orig_pid; + if (bproc_hook_imv(0, ptracem, (request,&pid,addr,data,(long*)&ret,0))) { + if (ret == -ELOOP) goto retry_ptrace; + return ret; + } lock_kernel(); ret = -EPERM; @@ -178,14 +189,21 @@ goto out_tsk; if (request == PTRACE_ATTACH) { + bproc_set_arg(addr); ret = ptrace_attach(child); goto out_tsk; } + bproc_set_arg(request == PTRACE_DETACH ? addr : 0); ret = ptrace_check_attach(child, request == PTRACE_KILL); if (ret < 0) goto out_tsk; + if (bproc_isghost(child)) { + bproc_hook(ptraceg, (request,child,addr,data,(long*)&ret,0)); + goto out_tsk; + } + switch (request) { /* when I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -427,6 +445,7 @@ free_task_struct(child); out: unlock_kernel(); + if (ret == -ELOOP) goto retry_ptrace; return ret; } @@ -440,6 +459,7 @@ current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0); current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(SIGTRAP)); notify_parent(current, SIGCHLD); schedule(); /* Index: linux/arch/i386/kernel/process.c =================================================================== --- linux.orig/arch/i386/kernel/process.c 2003-09-03 17:51:02.000000000 -0400 +++ linux/arch/i386/kernel/process.c 2003-09-03 17:52:04.000000000 -0400 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -489,6 +490,7 @@ { long retval, d0; + bproc_kcall(); __asm__ __volatile__( "movl %%esp,%%esi\n\t" "int $0x80\n\t" /* Linux/i386 system call */ @@ -789,6 +791,11 @@ current->ptrace &= ~PT_DTRACE; putname(filename); out: + if (error == -ENOENT) + error = bproc_hook_imv(error, sys_execve, + (®s,(char *)regs.ebx, + (char **)regs.ecx, (char **)regs.edx)); + return error; } Index: linux/arch/i386/kernel/i386_ksyms.c =================================================================== --- linux.orig/arch/i386/kernel/i386_ksyms.c 2003-09-03 17:51:04.000000000 -0400 +++ linux/arch/i386/kernel/i386_ksyms.c 2003-09-03 17:52:04.000000000 -0400 @@ -107,6 +107,11 @@ EXPORT_SYMBOL(__generic_copy_to_user); EXPORT_SYMBOL(strnlen_user); +asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); +EXPORT_SYMBOL_NOVERS(ret_from_sys_call); +asmlinkage void syscall_trace(void); +EXPORT_SYMBOL(syscall_trace); + EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); Index: linux/arch/alpha/config.in =================================================================== --- linux.orig/arch/alpha/config.in 2003-09-03 17:51:04.000000000 -0400 +++ linux/arch/alpha/config.in 2003-09-03 17:52:04.000000000 -0400 @@ -271,6 +271,7 @@ bool 'Networking support' CONFIG_NET bool 'System V IPC' CONFIG_SYSVIPC +bool 'Beowulf Distributed Process Space' CONFIG_BPROC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT bool 'Sysctl support' CONFIG_SYSCTL if [ "$CONFIG_PROC_FS" = "y" ]; then Index: linux/arch/alpha/kernel/signal.c =================================================================== --- linux.orig/arch/alpha/kernel/signal.c 2002-08-02 20:39:42.000000000 -0400 +++ linux/arch/alpha/kernel/signal.c 2003-09-03 17:52:04.000000000 -0400 @@ -23,6 +23,7 @@ #include #include #include +#include #include "proto.h" @@ -643,6 +644,7 @@ /* Let the debugger run. */ current->exit_code = signr; current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(signr)); notify_parent(current, SIGCHLD); schedule(); single_stepping |= ptrace_cancel_bpt(current); @@ -701,6 +703,7 @@ case SIGSTOP: current->state = TASK_STOPPED; current->exit_code = signr; + bproc_hook_im(stop_notify,(signr)); if (!(current->p_pptr->sig->action[SIGCHLD-1] .sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); Index: linux/arch/alpha/kernel/osf_sys.c =================================================================== --- linux.orig/arch/alpha/kernel/osf_sys.c 2002-08-02 20:39:42.000000000 -0400 +++ linux/arch/alpha/kernel/osf_sys.c 2003-09-03 17:52:04.000000000 -0400 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -219,8 +220,8 @@ * isn't actually going to matter, as if the parent happens * to change we can happily return either of the pids. */ - (®s)->r20 = tsk->p_opptr->tgid; - return tsk->tgid; + (®s)->r20 = bproc_hook_imv(tsk->p_opptr->tgid,sys_getppid,(tsk->p_opptr)); + return bproc_hook_imv(tsk->tgid,sys_getpid,()); } asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len, Index: linux/arch/alpha/kernel/entry.S =================================================================== --- linux.orig/arch/alpha/kernel/entry.S 2003-09-03 17:52:01.000000000 -0400 +++ linux/arch/alpha/kernel/entry.S 2003-09-03 17:52:04.000000000 -0400 @@ -212,8 +212,10 @@ * stack buildup, as we can't do system calls from kernel space. */ .align 3 +.globl kernel_clone .ent kernel_clone kernel_clone: + ldgp $29,0($27) /* we can be called from a module */ .frame $30, 0, $26 .prologue 0 subq $30,6*8,$30 @@ -230,6 +232,23 @@ br ret_from_sys_call .end kernel_clone +.align 3 +.globl ret_to_user_space +.ent ret_to_user_space +ret_to_user_space: + ldgp $29, 0($27) /* We can jump here from a module */ + bsr $1, undo_switch_stack + lda $1, 8($31) /* Set ps = 8 */ + stq $1, 0xB8($30) + + /* This tidbit ripped from entSys. Is this appropriate here ? */ + blt $0,syscall_error /* the call failed */ + stq $0,0($30) + stq $31,72($30) /* a3=0 => no error */ + + br ret_from_sys_call +.end ret_to_user_space + /* * arch_kernel_thread(fn, arg, clone_flags) */ @@ -240,19 +259,24 @@ ldgp $29,0($27) /* we can be called from a module */ .frame $30, 4*8, $26 subq $30,4*8,$30 + stq $11,24($30) stq $10,16($30) stq $9,8($30) - lda $0,CLONE_VM stq $26,0($30) .prologue 1 mov $16,$9 /* save fn */ mov $17,$10 /* save arg */ - or $18,$0,$16 /* shuffle flags to front; add CLONE_VM. */ - bsr $26,kernel_clone + mov $18,$11 /* save flags */ + bsr $26,bproc_kcall_ + lda $0,CLONE_VM + or $11,$0,$16 /* shuffle flags to front; add CLONE_VM. */ + jsr $26,kernel_clone + ldgp $29,0($26) bne $20,1f /* $20 is non-zero in child */ ldq $26,0($30) ldq $9,8($30) ldq $10,16($30) + ldq $11,24($30) addq $30,4*8,$30 ret $31,($26),1 /* this is in child: look out as we don't have any stack here.. */ @@ -290,6 +314,7 @@ .end __kernel_execve .align 3 +.globl do_switch_stack .ent do_switch_stack do_switch_stack: lda $30,-SWITCH_STACK_SIZE($30) @@ -339,6 +364,7 @@ .end do_switch_stack .align 3 +.globl undo_switch_stack .ent undo_switch_stack undo_switch_stack: ldq $9,0($30) @@ -1062,7 +1088,7 @@ .quad alpha_ni_syscall .quad alpha_ni_syscall .quad alpha_ni_syscall /* 290 */ - .quad alpha_ni_syscall + .quad sys_ni_syscall /* bproc: please shut up... */ .quad alpha_ni_syscall .quad alpha_ni_syscall .quad alpha_ni_syscall Index: linux/arch/alpha/kernel/alpha_ksyms.c =================================================================== --- linux.orig/arch/alpha/kernel/alpha_ksyms.c 2002-08-02 20:39:42.000000000 -0400 +++ linux/arch/alpha/kernel/alpha_ksyms.c 2003-09-03 17:52:04.000000000 -0400 @@ -164,6 +164,17 @@ EXPORT_SYMBOL(sys_sync); EXPORT_SYMBOL(sys_wait4); +extern void kernel_clone(void); +extern void ret_to_user_space(void); +extern void do_switch_stack(void); +extern void undo_switch_stack(void); +asmlinkage void syscall_trace(void); +EXPORT_SYMBOL_NOVERS(kernel_clone); +EXPORT_SYMBOL_NOVERS(ret_to_user_space); +EXPORT_SYMBOL_NOVERS(do_switch_stack); +EXPORT_SYMBOL_NOVERS(undo_switch_stack); +EXPORT_SYMBOL(syscall_trace); + /* Networking helper routines. */ EXPORT_SYMBOL(csum_tcpudp_magic); EXPORT_SYMBOL(ip_compute_csum); Index: linux/arch/alpha/kernel/process.c =================================================================== --- linux.orig/arch/alpha/kernel/process.c 2001-09-30 15:26:08.000000000 -0400 +++ linux/arch/alpha/kernel/process.c 2003-09-03 17:52:04.000000000 -0400 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -430,6 +431,9 @@ error = do_execve(filename, argv, envp, ®s); putname(filename); out: + if (error == -ENOENT) + error = bproc_hook_imv(error, sys_execve, + (®s,ufilename,argv,envp)); return error; } @@ -465,3 +469,10 @@ } return pc; } + +/* This is usually inlined. It's packaged in a function here so that + * we can call it from ASM code on this architecture. */ +void bproc_kcall_(void) +{ + bproc_kcall(); +} Index: linux/arch/alpha/kernel/ptrace.c =================================================================== --- linux.orig/arch/alpha/kernel/ptrace.c 2001-09-18 20:03:51.000000000 -0400 +++ linux/arch/alpha/kernel/ptrace.c 2003-09-03 17:52:04.000000000 -0400 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -248,7 +249,15 @@ int a4, int a5, struct pt_regs regs) { struct task_struct *child; - long ret; + long ret, orig_pid; + + orig_pid = pid; + retry_ptrace: + pid = orig_pid; + if (bproc_hook_imv(0, ptracem, (request,&pid,addr,data,&ret,®s.r0))) { + if (ret == -ELOOP && regs.r0) goto retry_ptrace; + return ret; + } lock_kernel(); DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n", @@ -274,6 +283,7 @@ if (!child) goto out_notsk; if (request == PTRACE_ATTACH) { + bproc_set_arg(addr); ret = ptrace_attach(child); goto out; } @@ -282,15 +292,20 @@ DBG(DBG_MEM, ("child not traced\n")); goto out; } + if (child->p_pptr != current && + !bproc_hook_v(0,ptrace_slave_call,(request,child,addr))) { + DBG(DBG_MEM, ("child not parent of this process\n")); + goto out; + } + if (bproc_isghost(child)) { + bproc_hook(ptraceg,(request,child,addr,data,&ret,®s.r0)); + goto out; + } if (child->state != TASK_STOPPED) { DBG(DBG_MEM, ("child process not stopped\n")); if (request != PTRACE_KILL) goto out; } - if (child->p_pptr != current) { - DBG(DBG_MEM, ("child not parent of this process\n")); - goto out; - } switch (request) { /* When I and D space are separate, these will need to be fixed. */ @@ -384,6 +399,7 @@ free_task_struct(child); out_notsk: unlock_kernel(); + if (ret == -ELOOP && regs.r0) goto retry_ptrace; return ret; } @@ -395,6 +411,7 @@ return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(SIGTRAP)); notify_parent(current, SIGCHLD); schedule(); /* Index: linux/arch/ppc/config.in =================================================================== --- linux.orig/arch/ppc/config.in 2002-11-28 18:53:11.000000000 -0500 +++ linux/arch/ppc/config.in 2003-09-03 17:52:04.000000000 -0400 @@ -162,6 +162,7 @@ bool 'Networking support' CONFIG_NET bool 'Sysctl support' CONFIG_SYSCTL bool 'System V IPC' CONFIG_SYSVIPC +bool 'Beowulf Distributed Process Space' CONFIG_BPROC bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT # only elf supported, a.out is not -- Cort Index: linux/arch/ppc/kernel/signal.c =================================================================== --- linux.orig/arch/ppc/kernel/signal.c 2002-11-28 18:53:11.000000000 -0500 +++ linux/arch/ppc/kernel/signal.c 2003-09-03 17:52:04.000000000 -0400 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -579,6 +580,7 @@ /* Let the debugger run. */ current->exit_code = signr; current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(signr)); notify_parent(current, SIGCHLD); schedule(); @@ -636,6 +638,7 @@ case SIGSTOP: current->state = TASK_STOPPED; current->exit_code = signr; + bproc_hook_im(stop_notify,(signr)); if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) notify_parent(current, SIGCHLD); schedule(); Index: linux/arch/ppc/kernel/ptrace.c =================================================================== --- linux.orig/arch/ppc/kernel/ptrace.c 2002-11-28 18:53:11.000000000 -0500 +++ linux/arch/ppc/kernel/ptrace.c 2003-09-03 17:52:04.000000000 -0400 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -161,6 +162,15 @@ { struct task_struct *child; int ret = -EPERM; + long orig_pid; + + orig_pid = pid; + retry_ptrace: + pid = orig_pid; + if (bproc_hook_imv(0, ptracem,(request,&pid,addr,data,(long*)&ret,0))){ + if (ret == -ELOOP) goto retry_ptrace; + return ret; + } lock_kernel(); if (request == PTRACE_TRACEME) { @@ -186,14 +196,21 @@ goto out_tsk; if (request == PTRACE_ATTACH) { + bproc_set_arg(addr); ret = ptrace_attach(child); goto out_tsk; } + bproc_set_arg(request == PTRACE_DETACH ? addr : 0); ret = ptrace_check_attach(child, request == PTRACE_KILL); if (ret < 0) goto out_tsk; + if (bproc_isghost(child)) { + bproc_hook(ptraceg, (request,child,addr,data,(long*)&ret,0)); + goto out_tsk; + } + switch (request) { /* when I and D space are separate, these will need to be fixed. */ case PTRACE_PEEKTEXT: /* read word at location addr. */ @@ -342,6 +359,7 @@ free_task_struct(child); out: unlock_kernel(); + if (ret == -ELOOP) goto retry_ptrace; return ret; } @@ -352,6 +370,7 @@ return; current->exit_code = SIGTRAP; current->state = TASK_STOPPED; + bproc_hook_im(stop_notify,(SIGTRAP)); notify_parent(current, SIGCHLD); schedule(); /* Index: linux/arch/ppc/kernel/ppc_ksyms.c =================================================================== --- linux.orig/arch/ppc/kernel/ppc_ksyms.c 2002-11-28 18:53:11.000000000 -0500 +++ linux/arch/ppc/kernel/ppc_ksyms.c 2003-09-03 17:52:04.000000000 -0400 @@ -366,3 +366,5 @@ EXPORT_SYMBOL_NOVERS(agp_special_page); #endif /* defined(CONFIG_ALL_PPC) */ +asmlinkage void ret_from_syscall_1(void) __asm__("ret_from_syscall_1"); +EXPORT_SYMBOL_NOVERS(ret_from_syscall_1); Index: linux/arch/ppc/kernel/misc.S =================================================================== --- linux.orig/arch/ppc/kernel/misc.S 2003-09-03 17:51:02.000000000 -0400 +++ linux/arch/ppc/kernel/misc.S 2003-09-03 17:52:04.000000000 -0400 @@ -901,6 +901,20 @@ * arch_kernel_thread(fn, arg, flags) */ _GLOBAL(arch_kernel_thread) + stwu r1,-28(r1) /* Setup stack frame to save args */ + mflr r0 + stw r3, 16(r1) + stw r4, 20(r1) + stw r5, 24(r1) + stw r0, 32(r1) + bl bproc_kcall_ /* Call bproc_kcall_ hook */ + lwz r0, 32(r1) /* Restore stack + arguments */ + lwz r5, 24(r1) + lwz r4, 20(r1) + lwz r3, 16(r1) + mtlr r0 + addi r1,r1,28 + mr r6,r3 /* function */ ori r3,r5,CLONE_VM /* flags */ li r0,__NR_clone @@ -941,7 +955,29 @@ SYSCALL(execve) SYSCALL(open) SYSCALL(close) -SYSCALL(waitpid) +_GLOBAL(waitpid) + stwu r1,-28(r1) /* Setup stack frame to save args */ + mflr r0 + stw r3, 16(r1) + stw r4, 20(r1) + stw r5, 24(r1) + stw r0, 32(r1) + bl bproc_kcall_ /* Call bproc_kcall_ hook */ + lwz r0, 32(r1) /* Restore stack + arguments */ + lwz r5, 24(r1) + lwz r4, 20(r1) + lwz r3, 16(r1) + mtlr r0 + addi r1,r1,28 + + li r0,__NR_waitpid + sc + bnslr + lis r4,errno@ha + stw r3,errno@l(r4) + li r3,-1 + blr + SYSCALL(fork) SYSCALL(delete_module) SYSCALL(_exit) Index: linux/arch/ppc/kernel/process.c =================================================================== --- linux.orig/arch/ppc/kernel/process.c 2001-11-26 08:29:17.000000000 -0500 +++ linux/arch/ppc/kernel/process.c 2003-09-03 17:52:04.000000000 -0400 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -443,6 +444,10 @@ current->ptrace &= ~PT_DTRACE; putname(filename); out: + if (error == -ENOENT) + error = bproc_hook_imv(error, sys_execve, + (regs,(char*)a0,(char**)a1,(char**)a2)); + return error; } @@ -605,3 +610,10 @@ } while (count++ < 16); return 0; } + +/* This is usually inlined. It's packaged in a function here so that + * we can call it from ASM code on this architecture. */ +void bproc_kcall_(void) +{ + bproc_kcall(); +} Index: linux/fs/inode.c =================================================================== --- linux.orig/fs/inode.c 2003-09-03 17:52:00.000000000 -0400 +++ linux/fs/inode.c 2003-09-03 17:52:04.000000000 -0400 @@ -816,6 +816,76 @@ return inode; } +/* + * This just initializes the inode fields + * to known values before returning the inode.. + * + * i_sb, i_ino, i_count, i_state and the lists have + * been initialized elsewhere.. + */ +static void clean_inode(struct inode *inode) +{ + static struct address_space_operations empty_aops; + static struct inode_operations empty_iops; + static struct file_operations empty_fops; + memset(&inode->u, 0, sizeof(inode->u)); + inode->i_sock = 0; + inode->i_op = &empty_iops; + inode->i_fop = &empty_fops; + inode->i_nlink = 1; + atomic_set(&inode->i_writecount, 0); + inode->i_size = 0; + inode->i_blocks = 0; + inode->i_generation = 0; + memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); + inode->i_pipe = NULL; + inode->i_bdev = NULL; + inode->i_cdev = NULL; + inode->i_data.a_ops = &empty_aops; + inode->i_data.host = inode; + inode->i_data.gfp_mask = GFP_HIGHUSER; + inode->i_mapping = &inode->i_data; +} + +/** + * get_empty_inode - obtain an inode + * + * This is called by things like the networking layer + * etc that want to get an inode without any inode + * number, or filesystems that allocate new inodes with + * no pre-existing information. + * + * On a successful return the inode pointer is returned. On a failure + * a %NULL pointer is returned. The returned inode is not on any superblock + * lists. + */ + +struct inode * get_empty_inode(void) +{ + static unsigned long last_ino; + struct inode * inode; + + spin_lock_prefetch(&inode_lock); + + inode = (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL); + if (inode) + { + spin_lock(&inode_lock); + inodes_stat.nr_inodes++; + list_add(&inode->i_list, &inode_in_use); + inode->i_sb = NULL; + inode->i_dev = 0; + inode->i_blkbits = 0; + inode->i_ino = ++last_ino; + inode->i_flags = 0; + atomic_set(&inode->i_count, 1); + inode->i_state = 0; + spin_unlock(&inode_lock); + clean_inode(inode); + } + return inode; +} + /** * new_inode - obtain an inode * @sb: superblock Index: linux/include/linux/fs.h =================================================================== --- linux.orig/include/linux/fs.h 2003-09-03 17:52:02.000000000 -0400 +++ linux/include/linux/fs.h 2003-09-03 17:52:04.000000000 -0400 @@ -1440,6 +1440,7 @@ extern void clear_inode(struct inode *); extern struct inode *new_inode(struct super_block *sb); +extern struct inode * get_empty_inode(void); extern void remove_suid(struct inode *inode); extern void insert_inode_hash(struct inode *); Index: linux/arch/i386/kernel/setup.c =================================================================== --- linux.orig/arch/i386/kernel/setup.c 2003-09-03 17:51:01.000000000 -0400 +++ linux/arch/i386/kernel/setup.c 2003-09-03 17:53:05.000000000 -0400 @@ -172,6 +172,8 @@ static u32 disabled_x86_caps[NCAPINTS] __initdata = { 0 }; extern int blk_nohighio; +int enable_acpi_smp_table; + /* * This is set up by the setup-routine at boot-time */