Author: kib Date: Fri Nov 16 08:25:06 2012 New Revision: 243142 URL: http://svnweb.freebsd.org/changeset/base/243142
Log: In pget(9), if PGET_NOTWEXIT flag is not specified, also search the zombie list for the pid. This allows several kern.proc sysctls to report useful information for zombies. Hold the allproc_lock around all searches instead of relocking it. Remove private pfind_locked() from the new nfs client code. Requested and reviewed by: pjd Tested by: pho MFC after: 3 weeks Modified: head/sys/fs/nfsclient/nfs_clport.c head/sys/kern/kern_proc.c head/sys/sys/proc.h Modified: head/sys/fs/nfsclient/nfs_clport.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clport.c Fri Nov 16 07:30:38 2012 (r243141) +++ head/sys/fs/nfsclient/nfs_clport.c Fri Nov 16 08:25:06 2012 (r243142) @@ -1150,31 +1150,6 @@ nfscl_maperr(struct thread *td, int erro } /* - * Locate a process by number; 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. - * Identical to pfind() in kern_proc.c, except it assume the list is - * already locked. - */ -static struct proc * -pfind_locked(pid_t pid) -{ - struct proc *p; - - LIST_FOREACH(p, PIDHASH(pid), p_hash) - if (p->p_pid == pid) { - PROC_LOCK(p); - if (p->p_state == PRS_NEW) { - PROC_UNLOCK(p); - p = NULL; - } - break; - } - return (p); -} - -/* * Check to see if the process for this owner exists. Return 1 if it doesn't * and 0 otherwise. */ Modified: head/sys/kern/kern_proc.c ============================================================================== --- head/sys/kern/kern_proc.c Fri Nov 16 07:30:38 2012 (r243141) +++ head/sys/kern/kern_proc.c Fri Nov 16 08:25:06 2012 (r243142) @@ -137,6 +137,7 @@ static void proc_dtor(void *mem, int siz static int proc_init(void *mem, int size, int flags); static void proc_fini(void *mem, int size); static void pargs_free(struct pargs *pa); +static struct proc *zpfind_locked(pid_t pid); /* * Other process lists @@ -284,20 +285,13 @@ inferior(p) return (1); } -/* - * Locate a process by number; 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 * -pfind(pid) - register pid_t pid; +pfind_locked(pid_t pid) { - register struct proc *p; + struct proc *p; - sx_slock(&allproc_lock); - LIST_FOREACH(p, PIDHASH(pid), p_hash) + sx_assert(&allproc_lock, SX_LOCKED); + LIST_FOREACH(p, PIDHASH(pid), p_hash) { if (p->p_pid == pid) { PROC_LOCK(p); if (p->p_state == PRS_NEW) { @@ -306,17 +300,34 @@ pfind(pid) } break; } + } + return (p); +} + +/* + * Locate a process by number; 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 * +pfind(pid_t pid) +{ + struct proc *p; + + sx_slock(&allproc_lock); + p = pfind_locked(pid); sx_sunlock(&allproc_lock); return (p); } static struct proc * -pfind_tid(pid_t tid) +pfind_tid_locked(pid_t tid) { struct proc *p; struct thread *td; - sx_slock(&allproc_lock); + sx_assert(&allproc_lock, SX_LOCKED); FOREACH_PROC_IN_SYSTEM(p) { PROC_LOCK(p); if (p->p_state == PRS_NEW) { @@ -330,7 +341,6 @@ pfind_tid(pid_t tid) PROC_UNLOCK(p); } found: - sx_sunlock(&allproc_lock); return (p); } @@ -364,12 +374,16 @@ pget(pid_t pid, int flags, struct proc * struct proc *p; int error; + sx_slock(&allproc_lock); if (pid <= PID_MAX) - p = pfind(pid); + p = pfind_locked(pid); else if ((flags & PGET_NOTID) == 0) - p = pfind_tid(pid); + p = pfind_tid_locked(pid); else p = NULL; + if (p == NULL && (flags & PGET_NOTWEXIT) == 0) + p = zpfind_locked(pid); + sx_sunlock(&allproc_lock); if (p == NULL) return (ESRCH); if ((flags & PGET_CANSEE) != 0) { @@ -1044,6 +1058,21 @@ pstats_free(struct pstats *ps) free(ps, M_SUBPROC); } +static struct proc * +zpfind_locked(pid_t pid) +{ + struct proc *p; + + sx_assert(&allproc_lock, SX_LOCKED); + LIST_FOREACH(p, &zombproc, p_list) { + if (p->p_pid == pid) { + PROC_LOCK(p); + break; + } + } + return (p); +} + /* * Locate a zombie process by number */ @@ -1053,11 +1082,7 @@ zpfind(pid_t pid) struct proc *p; sx_slock(&allproc_lock); - LIST_FOREACH(p, &zombproc, p_list) - if (p->p_pid == pid) { - PROC_LOCK(p); - break; - } + p = zpfind_locked(pid); sx_sunlock(&allproc_lock); return (p); } Modified: head/sys/sys/proc.h ============================================================================== --- head/sys/sys/proc.h Fri Nov 16 07:30:38 2012 (r243141) +++ head/sys/sys/proc.h Fri Nov 16 08:25:06 2012 (r243142) @@ -835,6 +835,7 @@ extern struct proc *initproc, *pageproc; extern struct uma_zone *proc_zone; struct proc *pfind(pid_t); /* Find process by id. */ +struct proc *pfind_locked(pid_t pid); struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */ _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"