Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Nov 2017 14:38:07 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r326397 - in stable/10: lib/libc/sys sys/kern sys/sys
Message-ID:  <201711301438.vAUEc7OJ041759@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Nov 30 14:38:07 2017
New Revision: 326397
URL: https://svnweb.freebsd.org/changeset/base/326397

Log:
  MFC r326122:
  Kill all descendants of the reaper, even if they are descendants of a
  subordinate reaper.  Also, mark reapers when listing pids.
  
  PR:	223745

Modified:
  stable/10/lib/libc/sys/procctl.2
  stable/10/sys/kern/kern_procctl.c
  stable/10/sys/sys/procctl.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libc/sys/procctl.2
==============================================================================
--- stable/10/lib/libc/sys/procctl.2	Thu Nov 30 14:19:47 2017	(r326396)
+++ stable/10/lib/libc/sys/procctl.2	Thu Nov 30 14:38:07 2017	(r326397)
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 21, 2015
+.Dd November 21, 2017
 .Dt PROCCTL 2
 .Os
 .Sh NAME
@@ -211,7 +211,7 @@ of the process.
 The
 .Fa pi_flags
 field returns the following flags, further describing the descendant:
-.Bl -tag -width "Dv REAPER_PIDINFO_VALID"
+.Bl -tag -width "Dv REAPER_PIDINFO_REAPER"
 .It Dv REAPER_PIDINFO_VALID
 Set to indicate that the
 .Vt procctl_reaper_pidinfo
@@ -226,6 +226,9 @@ of the returned array.
 The
 .Fa pi_pid
 field identifies the direct child of the reaper.
+.It Dv REAPER_PIDINFO_REAPER
+The reported process is itself a reaper.
+The descendants of the subordinate reaper are not reported.
 .El
 .It Dv PROC_REAP_KILL
 Request to deliver a signal to some subset of the descendants of the reaper.

Modified: stable/10/sys/kern/kern_procctl.c
==============================================================================
--- stable/10/sys/kern/kern_procctl.c	Thu Nov 30 14:19:47 2017	(r326396)
+++ stable/10/sys/kern/kern_procctl.c	Thu Nov 30 14:38:07 2017	(r326397)
@@ -221,6 +221,8 @@ reap_getpids(struct thread *td, struct proc *p, struct
 		pip->pi_flags = REAPER_PIDINFO_VALID;
 		if (proc_realparent(p2) == reap)
 			pip->pi_flags |= REAPER_PIDINFO_CHILD;
+		if ((p2->p_treeflag & P_TREE_REAPER) != 0)
+			pip->pi_flags |= REAPER_PIDINFO_REAPER;
 		i++;
 	}
 	sx_sunlock(&proctree_lock);
@@ -231,20 +233,60 @@ reap_getpids(struct thread *td, struct proc *p, struct
 	return (error);
 }
 
+static void
+reap_kill_proc(struct thread *td, struct proc *p2, ksiginfo_t *ksi,
+    struct procctl_reaper_kill *rk, int *error)
+{
+	int error1;
+
+	PROC_LOCK(p2);
+	error1 = p_cansignal(td, p2, rk->rk_sig);
+	if (error1 == 0) {
+		pksignal(p2, rk->rk_sig, ksi);
+		rk->rk_killed++;
+		*error = error1;
+	} else if (*error == ESRCH) {
+		rk->rk_fpid = p2->p_pid;
+		*error = error1;
+	}
+	PROC_UNLOCK(p2);
+}
+
+struct reap_kill_tracker {
+	struct proc *parent;
+	TAILQ_ENTRY(reap_kill_tracker) link;
+};
+
+TAILQ_HEAD(reap_kill_tracker_head, reap_kill_tracker);
+
+static void
+reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2)
+{
+	struct reap_kill_tracker *t;
+
+	t = malloc(sizeof(struct reap_kill_tracker), M_TEMP, M_WAITOK);
+	t->parent = p2;
+	TAILQ_INSERT_TAIL(tracker, t, link);
+}
+
 static int
 reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk)
 {
 	struct proc *reap, *p2;
 	ksiginfo_t ksi;
-	int error, error1;
+	struct reap_kill_tracker_head tracker;
+	struct reap_kill_tracker *t;
+	int error;
 
 	sx_assert(&proctree_lock, SX_LOCKED);
 	if (IN_CAPABILITY_MODE(td))
 		return (ECAPMODE);
-	if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG)
+	if (rk->rk_sig <= 0 || rk->rk_sig > _SIG_MAXSIG ||
+	    (rk->rk_flags & ~(REAPER_KILL_CHILDREN |
+	    REAPER_KILL_SUBTREE)) != 0 || (rk->rk_flags &
+	    (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) ==
+	    (REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE))
 		return (EINVAL);
-	if ((rk->rk_flags & ~(REAPER_KILL_CHILDREN | REAPER_KILL_SUBTREE)) != 0)
-		return (EINVAL);
 	PROC_UNLOCK(p);
 	reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p;
 	ksiginfo_init(&ksi);
@@ -255,26 +297,33 @@ reap_kill(struct thread *td, struct proc *p, struct pr
 	error = ESRCH;
 	rk->rk_killed = 0;
 	rk->rk_fpid = -1;
-	for (p2 = (rk->rk_flags & REAPER_KILL_CHILDREN) != 0 ?
-	    LIST_FIRST(&reap->p_children) : LIST_FIRST(&reap->p_reaplist);
-	    p2 != NULL;
-	    p2 = (rk->rk_flags & REAPER_KILL_CHILDREN) != 0 ?
-	    LIST_NEXT(p2, p_sibling) : LIST_NEXT(p2, p_reapsibling)) {
-		if ((rk->rk_flags & REAPER_KILL_SUBTREE) != 0 &&
-		    p2->p_reapsubtree != rk->rk_subtree)
-			continue;
-		PROC_LOCK(p2);
-		error1 = p_cansignal(td, p2, rk->rk_sig);
-		if (error1 == 0) {
-			pksignal(p2, rk->rk_sig, &ksi);
-			rk->rk_killed++;
-			error = error1;
-		} else if (error == ESRCH) {
-			error = error1;
-			rk->rk_fpid = p2->p_pid;
+	if ((rk->rk_flags & REAPER_KILL_CHILDREN) != 0) {
+		for (p2 = LIST_FIRST(&reap->p_children); p2 != NULL;
+		    p2 = LIST_NEXT(p2, p_sibling)) {
+			reap_kill_proc(td, p2, &ksi, rk, &error);
+			/*
+			 * Do not end the loop on error, signal
+			 * everything we can.
+			 */
 		}
-		PROC_UNLOCK(p2);
-		/* Do not end the loop on error, signal everything we can. */
+	} else {
+		TAILQ_INIT(&tracker);
+		reap_kill_sched(&tracker, reap);
+		while ((t = TAILQ_FIRST(&tracker)) != NULL) {
+			MPASS((t->parent->p_treeflag & P_TREE_REAPER) != 0);
+			TAILQ_REMOVE(&tracker, t, link);
+			for (p2 = LIST_FIRST(&t->parent->p_reaplist); p2 != NULL;
+			    p2 = LIST_NEXT(p2, p_reapsibling)) {
+				if (t->parent == reap &&
+				    (rk->rk_flags & REAPER_KILL_SUBTREE) != 0 &&
+				    p2->p_reapsubtree != rk->rk_subtree)
+					continue;
+				if ((p2->p_treeflag & P_TREE_REAPER) != 0)
+					reap_kill_sched(&tracker, p2);
+				reap_kill_proc(td, p2, &ksi, rk, &error);
+			}
+			free(t, M_TEMP);
+		}
 	}
 	PROC_LOCK(p);
 	return (error);

Modified: stable/10/sys/sys/procctl.h
==============================================================================
--- stable/10/sys/sys/procctl.h	Thu Nov 30 14:19:47 2017	(r326396)
+++ stable/10/sys/sys/procctl.h	Thu Nov 30 14:38:07 2017	(r326397)
@@ -77,6 +77,7 @@ struct procctl_reaper_pidinfo {
 
 #define	REAPER_PIDINFO_VALID	0x00000001
 #define	REAPER_PIDINFO_CHILD	0x00000002
+#define	REAPER_PIDINFO_REAPER	0x00000004
 
 struct procctl_reaper_pids {
 	u_int	rp_count;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201711301438.vAUEc7OJ041759>