Add pfind_any

It looks for both regular and zombie processes. This avoids allproc relocking
previously seen with pfind -> zpfind calls.
This commit is contained in:
Mateusz Guzik 2017-11-11 18:04:39 +00:00
parent 272640b7fc
commit 6e1619dae3
4 changed files with 27 additions and 12 deletions

View File

@ -406,16 +406,15 @@ filt_procattach(struct knote *kn)
bool exiting, immediate; bool exiting, immediate;
exiting = immediate = false; exiting = immediate = false;
p = pfind(kn->kn_id); if (kn->kn_sfflags & NOTE_EXIT)
if (p == NULL && (kn->kn_sfflags & NOTE_EXIT)) { p = pfind_any(kn->kn_id);
p = zpfind(kn->kn_id); else
exiting = true; p = pfind(kn->kn_id);
} else if (p != NULL && (p->p_flag & P_WEXIT)) {
exiting = true;
}
if (p == NULL) if (p == NULL)
return (ESRCH); return (ESRCH);
if (p->p_flag & P_WEXIT)
exiting = true;
if ((error = p_cansee(curthread, p))) { if ((error = p_cansee(curthread, p))) {
PROC_UNLOCK(p); PROC_UNLOCK(p);
return (error); return (error);

View File

@ -353,6 +353,23 @@ pfind(pid_t pid)
return (p); return (p);
} }
/*
* Same as pfind but allow zombies.
*/
struct proc *
pfind_any(pid_t pid)
{
struct proc *p;
sx_slock(&allproc_lock);
p = pfind_locked(pid);
if (p == NULL)
p = zpfind_locked(pid);
sx_sunlock(&allproc_lock);
return (p);
}
static struct proc * static struct proc *
pfind_tid_locked(pid_t tid) pfind_tid_locked(pid_t tid)
{ {

View File

@ -1765,10 +1765,8 @@ sys_kill(struct thread *td, struct kill_args *uap)
if (uap->pid > 0) { if (uap->pid > 0) {
/* kill single process */ /* kill single process */
if ((p = pfind(uap->pid)) == NULL) { if ((p = pfind_any(uap->pid)) == NULL)
if ((p = zpfind(uap->pid)) == NULL) return (ESRCH);
return (ESRCH);
}
AUDIT_ARG_PROCESS(p); AUDIT_ARG_PROCESS(p);
error = p_cansignal(td, p, uap->signum); error = p_cansignal(td, p, uap->signum);
if (error == 0 && uap->signum) if (error == 0 && uap->signum)

View File

@ -954,6 +954,7 @@ extern struct proc *initproc, *pageproc; /* Process slots for init, pager. */
extern struct uma_zone *proc_zone; extern struct uma_zone *proc_zone;
struct proc *pfind(pid_t); /* Find process by id. */ struct proc *pfind(pid_t); /* Find process by id. */
struct proc *pfind_any(pid_t); /* Find (zombie) process by id. */
struct proc *pfind_locked(pid_t pid); struct proc *pfind_locked(pid_t pid);
struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct pgrp *pgfind(pid_t); /* Find process group by id. */
struct proc *zpfind(pid_t); /* Find zombie process by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */