svn commit: r366082 - stable/12/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Wed Sep 23 17:25:05 UTC 2020
Author: kib
Date: Wed Sep 23 17:25:04 2020
New Revision: 366082
URL: https://svnweb.freebsd.org/changeset/base/366082
Log:
MFC r365814:
Fix fixjobc+orhpanage.
Modified:
stable/12/sys/kern/kern_proc.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/kern/kern_proc.c
==============================================================================
--- stable/12/sys/kern/kern_proc.c Wed Sep 23 17:20:04 2020 (r366081)
+++ stable/12/sys/kern/kern_proc.c Wed Sep 23 17:25:04 2020 (r366082)
@@ -557,6 +557,35 @@ isjobproc(struct proc *q, struct pgrp *pgrp)
q->p_pgrp->pg_session == pgrp->pg_session);
}
+static struct proc *
+jobc_reaper(struct proc *p)
+{
+ struct proc *pp;
+
+ sx_assert(&proctree_lock, SX_LOCKED);
+
+ for (pp = p;;) {
+ pp = pp->p_reaper;
+ if (pp->p_reaper == pp ||
+ (pp->p_treeflag & P_TREE_GRPEXITED) == 0)
+ return (pp);
+ }
+}
+
+static struct proc *
+jobc_parent(struct proc *p)
+{
+ struct proc *pp;
+
+ sx_assert(&proctree_lock, SX_LOCKED);
+
+ pp = proc_realparent(p);
+ if (pp->p_pptr == NULL ||
+ (pp->p_treeflag & P_TREE_GRPEXITED) == 0)
+ return (pp);
+ return (jobc_reaper(pp));
+}
+
#ifdef INVARIANTS
static void
check_pgrp_jobc(struct pgrp *pgrp)
@@ -573,7 +602,7 @@ check_pgrp_jobc(struct pgrp *pgrp)
if ((q->p_treeflag & P_TREE_GRPEXITED) != 0 ||
q->p_pptr == NULL)
continue;
- if (isjobproc(q->p_pptr, pgrp))
+ if (isjobproc(jobc_parent(q), pgrp))
cnt++;
}
KASSERT(pgrp->pg_jobc == cnt, ("pgrp %d %p pg_jobc %d cnt %d",
@@ -695,6 +724,25 @@ pgadjustjobc(struct pgrp *pgrp, bool entering)
PGRP_UNLOCK(pgrp);
}
+static void
+fixjobc_enterpgrp_q(struct pgrp *pgrp, struct proc *p, struct proc *q, bool adj)
+{
+ struct pgrp *childpgrp;
+ bool future_jobc;
+
+ sx_assert(&proctree_lock, SX_LOCKED);
+
+ if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ return;
+ childpgrp = q->p_pgrp;
+ future_jobc = childpgrp != pgrp &&
+ childpgrp->pg_session == pgrp->pg_session;
+
+ if ((adj && !isjobproc(p, childpgrp) && future_jobc) ||
+ (!adj && isjobproc(p, childpgrp) && !future_jobc))
+ pgadjustjobc(childpgrp, adj);
+}
+
/*
* Adjust pgrp jobc counters when specified process changes process group.
* We count the number of processes in each process group that "qualify"
@@ -709,8 +757,6 @@ static void
fixjobc_enterpgrp(struct proc *p, struct pgrp *pgrp)
{
struct proc *q;
- struct pgrp *childpgrp;
- bool future_jobc;
sx_assert(&proctree_lock, SX_LOCKED);
PROC_LOCK_ASSERT(p, MA_NOTOWNED);
@@ -720,36 +766,49 @@ fixjobc_enterpgrp(struct proc *p, struct pgrp *pgrp)
if (p->p_pgrp == pgrp)
return;
- if (isjobproc(p->p_pptr, pgrp))
+ if (isjobproc(jobc_parent(p), pgrp))
pgadjustjobc(pgrp, true);
LIST_FOREACH(q, &p->p_children, p_sibling) {
- if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ if ((q->p_treeflag & P_TREE_ORPHANED) != 0)
continue;
- childpgrp = q->p_pgrp;
- future_jobc = childpgrp != pgrp &&
- childpgrp->pg_session == pgrp->pg_session;
- if (!isjobproc(p, childpgrp) && future_jobc)
- pgadjustjobc(childpgrp, true);
+ fixjobc_enterpgrp_q(pgrp, p, q, true);
}
+ LIST_FOREACH(q, &p->p_orphans, p_orphan)
+ fixjobc_enterpgrp_q(pgrp, p, q, true);
- if (isjobproc(p->p_pptr, p->p_pgrp))
+ if (isjobproc(jobc_parent(p), p->p_pgrp))
pgadjustjobc(p->p_pgrp, false);
LIST_FOREACH(q, &p->p_children, p_sibling) {
- if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ if ((q->p_treeflag & P_TREE_ORPHANED) != 0)
continue;
- childpgrp = q->p_pgrp;
- future_jobc = childpgrp != pgrp &&
- childpgrp->pg_session == pgrp->pg_session;
- if (isjobproc(p, childpgrp) && !future_jobc)
- pgadjustjobc(childpgrp, false);
+ fixjobc_enterpgrp_q(pgrp, p, q, false);
}
+ LIST_FOREACH(q, &p->p_orphans, p_orphan)
+ fixjobc_enterpgrp_q(pgrp, p, q, false);
}
static void
+fixjobc_kill_q(struct proc *p, struct proc *q, bool adj)
+{
+ struct pgrp *childpgrp;
+
+ sx_assert(&proctree_lock, SX_LOCKED);
+
+ if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ return;
+ childpgrp = q->p_pgrp;
+
+ if ((adj && isjobproc(jobc_reaper(q), childpgrp) &&
+ !isjobproc(p, childpgrp)) || (!adj && !isjobproc(jobc_reaper(q),
+ childpgrp) && isjobproc(p, childpgrp)))
+ pgadjustjobc(childpgrp, adj);
+}
+
+static void
fixjobc_kill(struct proc *p)
{
struct proc *q;
- struct pgrp *childpgrp, *pgrp;
+ struct pgrp *pgrp;
sx_assert(&proctree_lock, SX_LOCKED);
PROC_LOCK_ASSERT(p, MA_NOTOWNED);
@@ -769,7 +828,7 @@ fixjobc_kill(struct proc *p)
* Check p's parent to see whether p qualifies its own process
* group; if so, adjust count for p's process group.
*/
- if (isjobproc(p->p_pptr, pgrp))
+ if (isjobproc(jobc_parent(p), pgrp))
pgadjustjobc(pgrp, false);
/*
@@ -778,21 +837,19 @@ fixjobc_kill(struct proc *p)
* adjust counts for children's process groups.
*/
LIST_FOREACH(q, &p->p_children, p_sibling) {
- if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ if ((q->p_treeflag & P_TREE_ORPHANED) != 0)
continue;
- childpgrp = q->p_pgrp;
- if (isjobproc(q->p_reaper, childpgrp) &&
- !isjobproc(p, childpgrp))
- pgadjustjobc(childpgrp, true);
+ fixjobc_kill_q(p, q, true);
}
+ LIST_FOREACH(q, &p->p_orphans, p_orphan)
+ fixjobc_kill_q(p, q, true);
LIST_FOREACH(q, &p->p_children, p_sibling) {
- if ((q->p_treeflag & P_TREE_GRPEXITED) != 0)
+ if ((q->p_treeflag & P_TREE_ORPHANED) != 0)
continue;
- childpgrp = q->p_pgrp;
- if (!isjobproc(q->p_reaper, childpgrp) &&
- isjobproc(p, childpgrp))
- pgadjustjobc(childpgrp, false);
+ fixjobc_kill_q(p, q, false);
}
+ LIST_FOREACH(q, &p->p_orphans, p_orphan)
+ fixjobc_kill_q(p, q, false);
}
void
More information about the svn-src-all
mailing list