Author: kib
Date: Wed Aug 15 15:56:21 2012
New Revision: 239301
URL: http://svn.freebsd.org/changeset/base/239301

Log:
  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 after:    1 week

Modified:
  head/sys/kern/init_main.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_mib.c
  head/sys/kern/kern_thread.c
  head/sys/kern/subr_param.c
  head/sys/nlm/nlm_advlock.c
  head/sys/sys/proc.h

Modified: head/sys/kern/init_main.c
==============================================================================
--- head/sys/kern/init_main.c   Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/kern/init_main.c   Wed Aug 15 15:56:21 2012        (r239301)
@@ -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 then PID_MAX */
        td->td_tid = PID_MAX + 1;
        LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
        td->td_state = TDS_RUNNING;

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c   Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/kern/kern_fork.c   Wed Aug 15 15:56:21 2012        (r239301)
@@ -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: head/sys/kern/kern_mib.c
==============================================================================
--- head/sys/kern/kern_mib.c    Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/kern/kern_mib.c    Wed Aug 15 15:56:21 2012        (r239301)
@@ -499,6 +499,30 @@ 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. */
+       if (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: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/kern/kern_thread.c Wed Aug 15 15:56:21 2012        (r239301)
@@ -269,7 +269,11 @@ threadinit(void)
 {
 
        mtx_init(&tid_lock, "TID lock", NULL, MTX_DEF);
-       /* leave one number for thread0 */
+
+       /*
+        * pid_max cannot be greater then 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: head/sys/kern/subr_param.c
==============================================================================
--- head/sys/kern/subr_param.c  Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/kern/subr_param.c  Wed Aug 15 15:56:21 2012        (r239301)
@@ -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,13 @@ 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.
+        */
+       TUNABLE_INT_FETCH("kern.pid_max", &pid_max);
+       if (pid_max > PID_MAX)
+               pid_max = PID_MAX;
 }
 
 /*

Modified: head/sys/nlm/nlm_advlock.c
==============================================================================
--- head/sys/nlm/nlm_advlock.c  Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/nlm/nlm_advlock.c  Wed Aug 15 15:56:21 2012        (r239301)
@@ -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 then 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: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Wed Aug 15 15:53:27 2012        (r239300)
+++ head/sys/sys/proc.h Wed Aug 15 15:56:21 2012        (r239301)
@@ -696,11 +696,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))
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to