Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F163548893
D58264.id182162.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D58264.id182162.diff
View Options
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -982,13 +982,16 @@
* lock as part of its work.
*/
void
-proc_reap(struct thread *td, struct proc *p, int *status, int options)
+proc_reap(struct thread *td, struct proc *p, int *status, int options,
+ int zombieref)
{
struct proc *q, *t;
sx_assert(&proctree_lock, SA_XLOCKED);
PROC_LOCK_ASSERT(p, MA_OWNED);
KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
+ MPASS(zombieref == P2_ZOMBIEREF_PARENT ||
+ zombieref == P2_ZOMBIEREF_PROCDESC);
mtx_spin_wait_unlocked(&p->p_slock);
@@ -1006,6 +1009,14 @@
return;
}
+ p->p_flag2 &= ~zombieref;
+ if ((p->p_flag2 & (P2_ZOMBIEREF_PROCDESC | P2_ZOMBIEREF_PARENT)) !=
+ 0) {
+ PROC_UNLOCK(p);
+ sx_xunlock(&proctree_lock);
+ return;
+ }
+
PROC_LOCK(q);
sigqueue_take(p->p_ksi);
PROC_UNLOCK(q);
@@ -1187,7 +1198,7 @@
switch (idtype) {
case P_ALL:
- if (p->p_procdesc == NULL ||
+ if ((p->p_flag2 & P2_ZOMBIEREF_PARENT) != 0 ||
(p->p_pptr == td->td_proc &&
(p->p_flag & P_TRACED) != 0)) {
break;
@@ -1241,12 +1252,9 @@
return (0);
}
- if (p_canwait(td, p)) {
- PROC_UNLOCK(p);
- return (0);
- }
-
- if ((options & WEXITED) == 0 && p->p_state == PRS_ZOMBIE) {
+ if (p_canwait(td, p) != 0 ||
+ ((options & WEXITED) == 0 && p->p_state == PRS_ZOMBIE) ||
+ (p->p_flag2 & P2_ZOMBIEREF_PARENT) == 0) {
PROC_UNLOCK(p);
return (0);
}
@@ -1275,7 +1283,7 @@
wait_fill_wrusage(p, wrusage);
if (p->p_state == PRS_ZOMBIE && !check_only) {
- proc_reap(td, p, status, options);
+ proc_reap(td, p, status, options, P2_ZOMBIEREF_PARENT);
return (-1);
}
return (1);
@@ -1583,7 +1591,8 @@
error = p_canwait(td, p);
if (error != 0)
break;
- if ((options & WEXITED) == 0 && p->p_state == PRS_ZOMBIE) {
+ if (((options & WEXITED) == 0 && p->p_state == PRS_ZOMBIE) ||
+ (p->p_flag2 & P2_ZOMBIEREF_PROCDESC) == 0) {
error = ESRCH;
break;
}
@@ -1592,7 +1601,7 @@
wait_fill_wrusage(p, wrusage);
if (p->p_state == PRS_ZOMBIE) {
- proc_reap(td, p, status, options);
+ proc_reap(td, p, status, options, P2_ZOMBIEREF_PROCDESC);
goto exit_unlocked;
}
@@ -1665,6 +1674,14 @@
child->p_pptr = parent;
if (set_oppid)
child->p_oppid = parent->p_pid;
+
+ /*
+ * When reparenting the child to the reaper, re-enable
+ * waitpid(2) for it, so that the zombie can be collected.
+ */
+ if ((child->p_flag & P_TRACED) == 0 && child->p_reaper == parent &&
+ (child->p_flag2 & P2_ZOMBIEREF_PARENT) == 0)
+ child->p_flag2 |= P2_ZOMBIEREF_PARENT;
}
static void
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -547,6 +547,8 @@
P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_NO_NEW_PRIVS |
P2_WXORX_DISABLE | P2_WXORX_ENABLE_EXEC | P2_LOGSIGEXIT_CTL |
P2_LOGSIGEXIT_ENABLE);
+ p2->p_flag2 |= (fr->fr_flags & RFPROCDESC) != 0 ?
+ P2_ZOMBIEREF_PROCDESC : P2_ZOMBIEREF_PARENT;
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
diff --git a/sys/kern/sys_procdesc.c b/sys/kern/sys_procdesc.c
--- a/sys/kern/sys_procdesc.c
+++ b/sys/kern/sys_procdesc.c
@@ -307,6 +307,7 @@
PROCDESC_UNLOCK(pd);
pd->pd_proc = NULL;
p->p_procdesc = NULL;
+ p->p_flag2 &= ~P2_ZOMBIEREF_PROCDESC;
procdesc_free(pd);
return (true);
}
@@ -316,7 +317,7 @@
/* Wakeup all waiters for this procdesc' process exit. */
wakeup(&p->p_procdesc);
- return (false);
+ return ((p->p_flag2 & P2_ZOMBIEREF_PARENT) != 0);
}
void
@@ -418,7 +419,7 @@
* process's reference to the process descriptor when it
* calls back into procdesc_reap().
*/
- proc_reap(curthread, p, NULL, 0);
+ proc_reap(curthread, p, NULL, 0, P2_ZOMBIEREF_PROCDESC);
} else if (pd->pd_fpcount == 0) /* last procdesc */ {
/*
* If the process is not yet dead, we need to kill it,
@@ -429,6 +430,7 @@
*/
pd->pd_proc = NULL;
p->p_procdesc = NULL;
+ p->p_flag2 &= ~P2_ZOMBIEREF_PROCDESC;
pd->pd_pid = -1;
procdesc_free(pd);
@@ -633,6 +635,7 @@
}
pd = p->p_procdesc;
if (pd != NULL) {
+ MPASS((p->p_flag2 & P2_ZOMBIEREF_PROCDESC) != 0);
refcount_acquire(&pd->pd_refcount);
PROCDESC_LOCK(pd);
MPASS(pd->pd_fpcount > 0);
@@ -644,6 +647,8 @@
pd->pd_proc = p;
pd->pd_pid = p->p_pid;
p->p_procdesc = pd;
+ MPASS((p->p_flag2 & P2_ZOMBIEREF_PROCDESC) == 0);
+ p->p_flag2 |= P2_ZOMBIEREF_PROCDESC;
}
procdesc_finit(pd, fp);
PROC_UNLOCK(p);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -903,6 +903,8 @@
#define P2_LOGSIGEXIT_ENABLE 0x00800000 /* Disable logging on sigexit */
#define P2_LOGSIGEXIT_CTL 0x01000000 /* Override kern.logsigexit */
#define P2_HWT 0x02000000 /* Process is using HWT. */
+#define P2_ZOMBIEREF_PARENT 0x04000000
+#define P2_ZOMBIEREF_PROCDESC 0x08000000
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
@@ -1205,7 +1207,8 @@
void proc_linkup0(struct proc *p, struct thread *td);
void proc_linkup(struct proc *p, struct thread *td);
struct proc *proc_realparent(struct proc *child);
-void proc_reap(struct thread *td, struct proc *p, int *status, int options);
+void proc_reap(struct thread *td, struct proc *p, int *status, int options,
+ int zombieref);
void proc_reparent(struct proc *child, struct proc *newparent, bool set_oppid);
void proc_set_p2_wexit(struct proc *p);
void proc_set_traced(struct proc *p, bool stop);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 25, 9:01 AM (9 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35469712
Default Alt Text
D58264.id182162.diff (5 KB)
Attached To
Mode
D58264: processes: add zombie references, each of them prevents reap
Attached
Detach File
Event Timeline
Log In to Comment