summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-01-05 03:27:09 +0000
committerkib <kib@FreeBSD.org>2015-01-05 03:27:09 +0000
commit5777edec4a4de6b756dc614129b8c3ac1605481d (patch)
tree6960c9f306d6b65c6d55b3a1dab46a3fe4eb9100 /sys/kern/kern_fork.c
parent6e9fd215c729431fe469e85f7af8fc605988227d (diff)
downloadFreeBSD-src-5777edec4a4de6b756dc614129b8c3ac1605481d.zip
FreeBSD-src-5777edec4a4de6b756dc614129b8c3ac1605481d.tar.gz
Merge reaper facility.
MFC r270443 (by mjg): Properly reparent traced processes when the tracer dies. MFC r273452 (by mjg): Plug unnecessary PRS_NEW check in kern_procctl. MFC 275800: Add a facility for non-init process to declare itself the reaper of the orphaned descendants. MFC r275821: Add missed break. MFC r275846 (by mckusick): Add some additional clarification and fix a few gammer nits. MFC r275847 (by bdrewery): Bump Dd for r275846.
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d3a7741..2a83327 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -267,11 +267,21 @@ retry:
* Scan the active and zombie procs to check whether this pid
* is in use. Remember the lowest pid that's greater
* than trypid, so we can avoid checking for a while.
+ *
+ * Avoid reuse of the process group id, session id or
+ * the reaper subtree id. Note that for process group
+ * and sessions, the amount of reserved pids is
+ * limited by process limit. For the subtree ids, the
+ * id is kept reserved only while there is a
+ * non-reaped process in the subtree, so amount of
+ * reserved pids is limited by process limit times
+ * two.
*/
p = LIST_FIRST(&allproc);
again:
for (; p != NULL; p = LIST_NEXT(p, p_list)) {
while (p->p_pid == trypid ||
+ p->p_reapsubtree == trypid ||
(p->p_pgrp != NULL &&
(p->p_pgrp->pg_id == trypid ||
(p->p_session != NULL &&
@@ -618,12 +628,22 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
* of init. This effectively disassociates the child from the
* parent.
*/
- if (flags & RFNOWAIT)
- pptr = initproc;
- else
+ if ((flags & RFNOWAIT) != 0) {
+ pptr = p1->p_reaper;
+ p2->p_reaper = pptr;
+ } else {
+ p2->p_reaper = (p1->p_treeflag & P_TREE_REAPER) != 0 ?
+ p1 : p1->p_reaper;
pptr = p1;
+ }
p2->p_pptr = pptr;
LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling);
+ LIST_INIT(&p2->p_reaplist);
+ LIST_INSERT_HEAD(&p2->p_reaper->p_reaplist, p2, p_reapsibling);
+ if (p2->p_reaper == p1)
+ p2->p_reapsubtree = p2->p_pid;
+ else
+ p2->p_reapsubtree = p1->p_reapsubtree;
sx_xunlock(&proctree_lock);
/* Inform accounting that we have forked. */
OpenPOWER on IntegriCloud