Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Aug 2012 19:53:33 +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-9@freebsd.org
Subject:   svn commit: r239582 - in stable/9/sys: kern nlm sys
Message-ID:  <201208221953.q7MJrXRG087835@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Aug 22 19:53:33 2012
New Revision: 239582
URL: http://svn.freebsd.org/changeset/base/239582

Log:
  MFC r239301:
  Add a sysctl kern.pid_max, which limits the maximum pid the system is
  allowed to allocate, and corresponding tunable with the same
  name. Note that existing processes with higher pids are left intact.
  
  MFC r239328:
  Fix grammar.
  
  MFC r239329:
  As a safety measure, disable lowering pid_max too much.

Modified:
  stable/9/sys/kern/init_main.c
  stable/9/sys/kern/kern_fork.c
  stable/9/sys/kern/kern_mib.c
  stable/9/sys/kern/kern_thread.c
  stable/9/sys/kern/subr_param.c
  stable/9/sys/nlm/nlm_advlock.c
  stable/9/sys/sys/proc.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/init_main.c
==============================================================================
--- stable/9/sys/kern/init_main.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/kern/init_main.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -476,6 +476,7 @@ proc0_init(void *dummy __unused)
 	knlist_init_mtx(&p->p_klist, &p->p_mtx);
 	STAILQ_INIT(&p->p_ktr);
 	p->p_nice = NZERO;
+	/* pid_max cannot be greater than PID_MAX */
 	td->td_tid = PID_MAX + 1;
 	LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
 	td->td_state = TDS_RUNNING;

Modified: stable/9/sys/kern/kern_fork.c
==============================================================================
--- stable/9/sys/kern/kern_fork.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/kern/kern_fork.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -209,8 +209,8 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARG
 	pid = randompid;
 	error = sysctl_handle_int(oidp, &pid, 0, req);
 	if (error == 0 && req->newptr != NULL) {
-		if (pid < 0 || pid > PID_MAX - 100)	/* out of range */
-			pid = PID_MAX - 100;
+		if (pid < 0 || pid > pid_max - 100)	/* out of range */
+			pid = pid_max - 100;
 		else if (pid < 2)			/* NOP */
 			pid = 0;
 		else if (pid < 100)			/* Make it reasonable */
@@ -259,8 +259,8 @@ retry:
 	 * restart somewhat above 0, as the low-numbered procs
 	 * tend to include daemons that don't exit.
 	 */
-	if (trypid >= PID_MAX) {
-		trypid = trypid % PID_MAX;
+	if (trypid >= pid_max) {
+		trypid = trypid % pid_max;
 		if (trypid < 100)
 			trypid += 100;
 		pidchecked = 0;

Modified: stable/9/sys/kern/kern_mib.c
==============================================================================
--- stable/9/sys/kern/kern_mib.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/kern/kern_mib.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -499,6 +499,34 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, vnod
 SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD,
     0, sizeof(struct proc), "sizeof(struct proc)");
 
+static int
+sysctl_kern_pid_max(SYSCTL_HANDLER_ARGS)
+{
+	int error, pm;
+
+	pm = pid_max;
+	error = sysctl_handle_int(oidp, &pm, 0, req);
+	if (error || !req->newptr)
+		return (error);
+	sx_xlock(&proctree_lock);
+	sx_xlock(&allproc_lock);
+
+	/*
+	 * Only permit the values less then PID_MAX.
+	 * As a safety measure, do not allow to limit the pid_max too much.
+	 */
+	if (pm < 300 || pm > PID_MAX)
+		error = EINVAL;
+	else
+		pid_max = pm;
+	sx_xunlock(&allproc_lock);
+	sx_xunlock(&proctree_lock);
+	return (error);
+}
+SYSCTL_PROC(_kern, OID_AUTO, pid_max, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_TUN |
+    CTLFLAG_MPSAFE, 0, 0, sysctl_kern_pid_max, "I",
+    "Maximum allowed pid");
+
 #include <sys/bio.h>
 #include <sys/buf.h>
 SYSCTL_INT(_debug_sizeof, OID_AUTO, bio, CTLFLAG_RD,

Modified: stable/9/sys/kern/kern_thread.c
==============================================================================
--- stable/9/sys/kern/kern_thread.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/kern/kern_thread.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -266,7 +266,11 @@ threadinit(void)
 {
 
 	mtx_init(&tid_lock, "TID lock", NULL, MTX_DEF);
-	/* leave one number for thread0 */
+
+	/*
+	 * pid_max cannot be greater than PID_MAX.
+	 * leave one number for thread0.
+	 */
 	tid_unrhdr = new_unrhdr(PID_MAX + 2, INT_MAX, &tid_lock);
 
 	thread_zone = uma_zcreate("THREAD", sched_sizeof_thread(),

Modified: stable/9/sys/kern/subr_param.c
==============================================================================
--- stable/9/sys/kern/subr_param.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/kern/subr_param.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -41,12 +41,13 @@ __FBSDID("$FreeBSD$");
 #include "opt_msgbuf.h"
 #include "opt_maxusers.h"
 
-#include <sys/limits.h>
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-#include <sys/sysctl.h>
+#include <sys/limits.h>
 #include <sys/msgbuf.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -92,6 +93,7 @@ int	ncallout;			/* maximum # of timer ev
 int	nbuf;
 int	ngroups_max;			/* max # groups per process */
 int	nswbuf;
+pid_t	pid_max = PID_MAX;
 long	maxswzone;			/* max swmeta KVA storage */
 long	maxbcache;			/* max buffer cache KVA storage */
 long	maxpipekva;			/* Limit on pipe KVA */
@@ -250,6 +252,16 @@ init_param1(void)
 	TUNABLE_INT_FETCH("kern.ngroups", &ngroups_max);
 	if (ngroups_max < NGROUPS_MAX)
 		ngroups_max = NGROUPS_MAX;
+
+	/*
+	 * Only allow to lower the maximal pid.
+	 * Prevent setting up a non-bootable system if pid_max is too low.
+	 */
+	TUNABLE_INT_FETCH("kern.pid_max", &pid_max);
+	if (pid_max > PID_MAX)
+		pid_max = PID_MAX;
+	else if (pid_max < 300)
+		pid_max = 300;
 }
 
 /*

Modified: stable/9/sys/nlm/nlm_advlock.c
==============================================================================
--- stable/9/sys/nlm/nlm_advlock.c	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/nlm/nlm_advlock.c	Wed Aug 22 19:53:33 2012	(r239582)
@@ -98,6 +98,7 @@ nlm_client_init(void *dummy)
 	int i;
 
 	mtx_init(&nlm_svid_lock, "NLM svid lock", NULL, MTX_DEF);
+	/* pid_max cannot be greater than PID_MAX */
 	nlm_svid_allocator = new_unrhdr(PID_MAX + 2, INT_MAX, &nlm_svid_lock);
 	for (i = 0; i < NLM_SVID_HASH_SIZE; i++)
 		LIST_INIT(&nlm_file_svids[i]);

Modified: stable/9/sys/sys/proc.h
==============================================================================
--- stable/9/sys/sys/proc.h	Wed Aug 22 19:45:18 2012	(r239581)
+++ stable/9/sys/sys/proc.h	Wed Aug 22 19:53:33 2012	(r239582)
@@ -693,11 +693,12 @@ MALLOC_DECLARE(M_SUBPROC);
 #define	FIRST_THREAD_IN_PROC(p)	TAILQ_FIRST(&(p)->p_threads)
 
 /*
- * We use process IDs <= PID_MAX; PID_MAX + 1 must also fit in a pid_t,
- * as it is used to represent "no process group".
+ * We use process IDs <= pid_max <= PID_MAX; PID_MAX + 1 must also fit
+ * in a pid_t, as it is used to represent "no process group".
  */
 #define	PID_MAX		99999
 #define	NO_PID		100000
+extern pid_t pid_max;
 
 #define	SESS_LEADER(p)	((p)->p_session->s_leader == (p))
 



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