--- sys/compat/freebsd32/syscalls.master 2005/03/01 06:35:22 +++ sys/compat/freebsd32/syscalls.master 2005/03/18 19:16:50 @@ -620,3 +620,4 @@ 452 UNIMPL setaudit_addr 453 UNIMPL auditctl 454 UNIMPL _umtx_op +455 MNOPROTO { int killbid(uint64_t bid, int flags); } --- sys/kern/init_main.c 2005/02/17 10:01:14 +++ sys/kern/init_main.c 2005/03/18 01:54:12 @@ -351,6 +351,9 @@ /* * Create process 0 (the swapper). */ + sx_xlock(&allproc_lock); + pbidadd(p); + sx_xunlock(&allproc_lock); LIST_INSERT_HEAD(&allproc, p, p_list); LIST_INSERT_HEAD(PIDHASH(0), p, p_hash); mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); --- sys/kern/init_sysent.c 2005/03/01 17:45:20 +++ sys/kern/init_sysent.c 2005/03/18 19:16:50 @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/kern/init_sysent.c,v 1.186 2005/03/01 17:44:34 ps Exp $ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.186 2005/03/01 17:43:08 ps Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.187 2005/03/09 11:50:55 stefanf Exp */ #include "opt_compat.h" @@ -483,4 +483,5 @@ { SYF_MPSAFE | AS(setaudit_addr_args), (sy_call_t *)lkmressys }, /* 452 = setaudit_addr */ { SYF_MPSAFE | AS(auditctl_args), (sy_call_t *)lkmressys }, /* 453 = auditctl */ { SYF_MPSAFE | AS(_umtx_op_args), (sy_call_t *)_umtx_op }, /* 454 = _umtx_op */ + { SYF_MPSAFE | AS(killbid_args), (sy_call_t *)killbid }, /* 455 = killbid */ }; --- sys/kern/kern_exit.c 2005/03/13 11:50:48 +++ sys/kern/kern_exit.c 2005/03/18 11:11:02 @@ -644,6 +644,7 @@ * we have an exclusive reference. */ sx_xlock(&allproc_lock); + pbidremove(p); LIST_REMOVE(p, p_list); /* off zombproc */ sx_xunlock(&allproc_lock); LIST_REMOVE(p, p_sibling); --- sys/kern/kern_fork.c 2005/01/06 23:37:37 +++ sys/kern/kern_fork.c 2005/03/18 01:54:12 @@ -395,6 +395,7 @@ p2 = newproc; p2->p_state = PRS_NEW; /* protect against others */ p2->p_pid = trypid; + pbidadd(p2); LIST_INSERT_HEAD(&allproc, p2, p_list); LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); sx_xunlock(&allproc_lock); --- sys/kern/kern_proc.c 2005/03/17 08:45:41 +++ sys/kern/kern_proc.c 2005/03/18 11:11:02 @@ -82,6 +82,7 @@ /* * Other process lists */ +static RB_HEAD(procbid, proc) procbid_tree; struct pidhashhead *pidhashtbl; u_long pidhash; struct pgrphashhead *pgrphashtbl; @@ -113,6 +114,7 @@ mtx_init(&ppeers_lock, "p_peers", NULL, MTX_DEF); LIST_INIT(&allproc); LIST_INIT(&zombproc); + RB_INIT(&procbid_tree); pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash); proc_zone = uma_zcreate("PROC", sched_sizeof_proc(), @@ -853,6 +855,84 @@ return (p); } +static uint64_t procbid_next = 1; + +static int +procbid_compare(struct proc *a, struct proc *b) +{ + + if (a->p_bid > b->p_bid) + return (1); + else if (a->p_bid < b->p_bid) + return (-1); + return (0); +} +RB_PROTOTYPE(procbid, proc, p_bidrb, procbid_compare); +RB_GENERATE(procbid, proc, p_bidrb, procbid_compare); + +/* + * Locate a process by born ID; return only "live" processes -- i.e., neither + * zombies nor newly born but incompletely initialized processes. By not + * returning processes in the PRS_NEW state, we allow callers to avoid + * testing for that condition to avoid dereferencing p_ucred, et al. + */ +struct proc * +pbidfind(register uint64_t bid) +{ + register struct proc *p; + struct proc pcomp; + + pcomp.p_bid = bid; + sx_slock(&allproc_lock); + p = RB_FIND(procbid, &procbid_tree, &pcomp); + if (p != NULL && p->p_state != PRS_NEW && p->p_state != PRS_ZOMBIE) + PROC_LOCK(p); + else + p = NULL; + sx_sunlock(&allproc_lock); + return (p); +} + +/* + * Locate a zombie process by number + */ +struct proc * +zpbidfind(register uint64_t bid) +{ + register struct proc *p; + struct proc pcomp; + + pcomp.p_bid = bid; + sx_slock(&allproc_lock); + p = RB_FIND(procbid, &procbid_tree, &pcomp); + if (p != NULL && p->p_state == PRS_ZOMBIE) + PROC_LOCK(p); + else + p = NULL; + sx_sunlock(&allproc_lock); + return (p); +} + +void +pbidadd(struct proc *p) +{ + + sx_assert(&allproc_lock, SX_XLOCKED); + p->p_bid = procbid_next++; + RB_INSERT(procbid, &procbid_tree, p); +} + +void +pbidremove(struct proc *p) +{ + + sx_assert(&allproc_lock, SX_XLOCKED); + if (p->p_bid == 0) + return; + RB_REMOVE(procbid, &procbid_tree, p); + p->p_bid = 0; +} + #define KERN_PROC_ZOMBMASK 0x3 #define KERN_PROC_NOTHREADS 0x4 --- sys/kern/kern_sig.c 2005/03/04 22:50:30 +++ sys/kern/kern_sig.c 2005/03/18 11:28:30 @@ -1413,6 +1413,38 @@ /* NOTREACHED */ } +#ifndef _SYS_SYSPROTO_H_ +struct killbid_args { + uint64_t bid; + int signum; +}; +#endif +/* + * MPSAFE + */ +/* ARGSUSED */ +int +killbid(td, uap) + register struct thread *td; + register struct killbid_args *uap; +{ + register struct proc *p; + int error; + + if ((u_int)uap->signum > _SIG_MAXSIG) + return (EINVAL); + + if ((p = pbidfind(uap->bid)) == NULL) { + if ((p = zpbidfind(uap->bid)) == NULL) + return (ESRCH); + } + error = p_cansignal(td, p, uap->signum); + if (error == 0 && uap->signum) + psignal(p, uap->signum); + PROC_UNLOCK(p); + return (error); +} + #if defined(COMPAT_43) #ifndef _SYS_SYSPROTO_H_ struct okillpg_args { --- sys/kern/syscalls.c 2005/03/01 17:45:20 +++ sys/kern/syscalls.c 2005/03/18 19:16:50 @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/kern/syscalls.c,v 1.172 2005/03/01 17:44:34 ps Exp $ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.186 2005/03/01 17:43:08 ps Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.187 2005/03/09 11:50:55 stefanf Exp */ const char *syscallnames[] = { @@ -462,4 +462,5 @@ "setaudit_addr", /* 452 = setaudit_addr */ "auditctl", /* 453 = auditctl */ "_umtx_op", /* 454 = _umtx_op */ + "killbid", /* 455 = killbid */ }; --- sys/kern/syscalls.master 2005/03/09 11:55:18 +++ sys/kern/syscalls.master 2005/03/18 19:16:50 @@ -645,5 +645,6 @@ 453 MNOSTD { int auditctl(int cmd, char *path); } 454 MSTD { int _umtx_op(struct umtx *umtx, int op, long id, void *uaddr,\ void *uaddr2); } +455 MSTD { int killbid(uint64_t bid, int signum); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master --- sys/sys/proc.h 2005/03/17 08:45:41 +++ sys/sys/proc.h 2005/03/18 11:11:02 @@ -43,6 +43,7 @@ #ifndef _KERNEL #include #endif +#include #include #include #include @@ -533,6 +534,8 @@ PRS_ZOMBIE } p_state; /* (j/c) S* process status. */ + uint64_t p_bid; /* (b) Process born ID. */ + RB_ENTRY(proc) p_bidrb; /* (d) Red-black tree pointer. */ pid_t p_pid; /* (b) Process identifier. */ LIST_ENTRY(proc) p_hash; /* (d) Hash chain. */ LIST_ENTRY(proc) p_pglist; /* (g + e) List of processes in pgrp. */ @@ -825,6 +828,11 @@ struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */ +struct proc *pbidfind(uint64_t); /* Find process by bid. */ +struct proc *zpbidfind(uint64_t); /* Find zombie process by bid. */ +void pbidadd(struct proc *); /* Add process to the bid red-black tree. */ +void pbidremove(struct proc *); /* Remove process from the bid red-black tree. */ + void adjustrunqueue(struct thread *, int newpri); void ast(struct trapframe *framep); struct thread *choosethread(void); --- sys/sys/syscall.h 2005/03/01 17:45:20 +++ sys/sys/syscall.h 2005/03/18 19:16:50 @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/sys/syscall.h,v 1.169 2005/03/01 17:44:34 ps Exp $ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.186 2005/03/01 17:43:08 ps Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.187 2005/03/09 11:50:55 stefanf Exp */ #define SYS_syscall 0 @@ -368,4 +368,5 @@ #define SYS_setaudit_addr 452 #define SYS_auditctl 453 #define SYS__umtx_op 454 -#define SYS_MAXSYSCALL 455 +#define SYS_killbid 455 +#define SYS_MAXSYSCALL 456 --- sys/sys/syscall.mk 2005/03/01 17:45:20 +++ sys/sys/syscall.mk 2005/03/18 19:16:50 @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. -# $FreeBSD: src/sys/sys/syscall.mk,v 1.124 2005/03/01 17:44:34 ps Exp $ -# created from FreeBSD: src/sys/kern/syscalls.master,v 1.186 2005/03/01 17:43:08 ps Exp +# $FreeBSD$ +# created from FreeBSD: src/sys/kern/syscalls.master,v 1.187 2005/03/09 11:50:55 stefanf Exp MIASM = \ syscall.o \ exit.o \ @@ -309,4 +309,5 @@ getaudit_addr.o \ setaudit_addr.o \ auditctl.o \ - _umtx_op.o + _umtx_op.o \ + killbid.o --- sys/sys/sysproto.h 2005/03/01 17:45:20 +++ sys/sys/sysproto.h 2005/03/18 19:16:50 @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/sys/sysproto.h,v 1.168 2005/03/01 17:44:34 ps Exp $ - * created from FreeBSD: src/sys/kern/syscalls.master,v 1.186 2005/03/01 17:43:08 ps Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/kern/syscalls.master,v 1.187 2005/03/09 11:50:55 stefanf Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1349,6 +1349,10 @@ char uaddr_l_[PADL_(void *)]; void * uaddr; char uaddr_r_[PADR_(void *)]; char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)]; }; +struct killbid_args { + char bid_l_[PADL_(uint64_t)]; uint64_t bid; char bid_r_[PADR_(uint64_t)]; + char signum_l_[PADL_(int)]; int signum; char signum_r_[PADR_(int)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_exit(struct thread *, struct sys_exit_args *); int fork(struct thread *, struct fork_args *); @@ -1655,6 +1659,7 @@ int setaudit_addr(struct thread *, struct setaudit_addr_args *); int auditctl(struct thread *, struct auditctl_args *); int _umtx_op(struct thread *, struct _umtx_op_args *); +int killbid(struct thread *, struct killbid_args *); #ifdef COMPAT_43