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
This commit is contained in:
parent
1fc2a61440
commit
134eb42e24
@ -1149,31 +1149,6 @@ nfscl_maperr(struct thread *td, int error, uid_t uid, gid_t gid)
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
|
@ -137,6 +137,7 @@ static void proc_dtor(void *mem, int size, void *arg);
|
||||
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 **pp)
|
||||
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);
|
||||
}
|
||||
|
@ -835,6 +835,7 @@ extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */
|
||||
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. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user