Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Aug 2012 16:07:00 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Julian Elischer <julian@freebsd.org>
Cc:        freebsd-hackers@freebsd.org, Dan Plassche <dplassche@gmail.com>
Subject:   Re: FreeBSD 1.x Binaries Work Except under Chroot
Message-ID:  <20120814130700.GD5883@deviant.kiev.zoral.com.ua>
In-Reply-To: <5029A9CE.8070307@freebsd.org>
References:  <CAOD8YqpVzT0pdBCHaMcu2krpjHcP3eotyDtiBR7OzUK1E9Hi5g@mail.gmail.com> <20120810170715.GI2425@deviant.kiev.zoral.com.ua> <CAOD8Yqpz89-bxN7vpsyNWisr7eMDjcbvTSfknvG6M_jZFOW-yQ@mail.gmail.com> <20120811184522.GK2425@deviant.kiev.zoral.com.ua> <CAOD8YqqNpY33t450jovcJRRf6BGffPCyO%2BF4LB0N_SbhZJd-0g@mail.gmail.com> <5029A9CE.8070307@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--/unnNtmY43mpUSKx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Aug 13, 2012 at 06:28:46PM -0700, Julian Elischer wrote:
> On 8/13/12 3:33 PM, Dan Plassche wrote:
> >Konstantin,
> >
> >My apologies for any confusion.  Your patch solved the problem on
> >8.2.  Static and dynamic a.out binaries from 1.1.5.1 are working
> >normally in a chroot environment now.
>=20
> you will also have to change PID_MAX (spelling?) to be 60000
> I have considered making this a tunable..
> If you don't then the shell in the 1.1.5.1 environment will not be=20
> able to handle when a child
> get s a pid of > 16 bits and it will not be able to wait on it. so it=20
> will suspend for ever.
> teh result is that you can not complete  a "make world".
>=20
> last time I tried a "make world" completed in about 1 minute and a kernel
> (1.1.5.1 GENERIC) compiled in way less than a minute. that was in 7.x=20
> days.
>=20
> I'd like to see results under 9.2 on a modern machine.

I committed today a batch of changes that allowed me to run most of
the binaries from 1.1.5.1 CD on real amd64 machine.

Below is the pid_max tunable patch. I first thought that it cannot be
made a writeable sysctl, but then realized that there is nothing wrong
with having existing process pid be greater then pid_max, as far as it
is less then PID_MAX.

diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linpro=
cfs.c
index 3adbe96..03db81a 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -1230,7 +1230,7 @@ static int
 linprocfs_dopid_max(PFS_FILL_ARGS)
 {
=20
-	sbuf_printf(sb, "%i\n", PID_MAX);
+	sbuf_printf(sb, "%i\n", pid_max);
 	return (0);
 }
=20
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index 8456e10..dd4a24f 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -824,7 +824,7 @@ svr4_sys_sysconfig(td, uap)
 		*retval =3D 1;	/* XXX */
 		break;
 	case SVR4_CONFIG_MAXPID:
-		*retval =3D PID_MAX;
+		*retval =3D pid_max;
 		break;
 	case SVR4_CONFIG_STACK_PROT:
 		*retval =3D PROT_READ|PROT_WRITE|PROT_EXEC;
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vn=
ops.c
index 9f97cd3..9600e9a 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -531,7 +531,7 @@ pfs_lookup(struct vop_cachedlookup_args *va)
 	if ((pn =3D pdn) !=3D NULL) {
 		pid =3D 0;
 		for (pid =3D 0, i =3D 0; i < namelen && isdigit(pname[i]); ++i)
-			if ((pid =3D pid * 10 + pname[i] - '0') > PID_MAX)
+			if ((pid =3D pid * 10 + pname[i] - '0') > pid_max)
 				break;
 		if (i =3D=3D cnp->cn_namelen) {
 			pfs_unlock(pd);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index ba905e0..3174a34 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -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 =3D NZERO;
+	/* pid_max cannot be greater then PID_MAX */
 	td->td_tid =3D PID_MAX + 1;
 	LIST_INSERT_HEAD(TIDHASH(td->td_tid), td, td_hash);
 	td->td_state =3D TDS_RUNNING;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 6cb95cd..69abb23 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -209,8 +209,8 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARGS)
 	pid =3D randompid;
 	error =3D sysctl_handle_int(oidp, &pid, 0, req);
 	if (error =3D=3D 0 && req->newptr !=3D NULL) {
-		if (pid < 0 || pid > PID_MAX - 100)	/* out of range */
-			pid =3D PID_MAX - 100;
+		if (pid < 0 || pid > pid_max - 100)	/* out of range */
+			pid =3D pid_max - 100;
 		else if (pid < 2)			/* NOP */
 			pid =3D 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 >=3D PID_MAX) {
-		trypid =3D trypid % PID_MAX;
+	if (trypid >=3D pid_max) {
+		trypid =3D trypid % pid_max;
 		if (trypid < 100)
 			trypid +=3D 100;
 		pidchecked =3D 0;
@@ -268,7 +268,7 @@ retry:
 	if (trypid >=3D pidchecked) {
 		int doingzomb =3D 0;
=20
-		pidchecked =3D PID_MAX;
+		pidchecked =3D pid_max;
 		/*
 		 * Scan the active and zombie procs to check whether this pid
 		 * is in use.  Remember the lowest pid that's greater
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 75b3af9..dfc8695 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -499,6 +499,30 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, vnode, CTLFLAG_RD,
 SYSCTL_INT(_debug_sizeof, OID_AUTO, proc, CTLFLAG_RD,
     0, sizeof(struct proc), "sizeof(struct proc)");
=20
+static int
+sysctl_kern_pid_max(SYSCTL_HANDLER_ARGS)
+{
+	int error, pm;
+
+	pm =3D pid_max;
+	error =3D sysctl_handle_int(oidp, &pm, 0, req);
+	if (error || !req->newptr)
+		return (error);
+	/* Permit update only if the new securelevel exceeds the old. */
+	sx_xlock(&proctree_lock);
+	sx_xlock(&allproc_lock);
+	if (pm > PID_MAX)
+		error =3D EINVAL;
+	else
+		pid_max =3D pm;
+	sx_xunlock(&allproc_lock);
+	sx_xunlock(&proctree_lock);
+	return (error);
+}
+SYSCTL_PROC(_kern, OID_AUTO, pid_max, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_T=
UN |
+    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,
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 69a416e..d21763c 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -269,7 +269,11 @@ threadinit(void)
 {
=20
 	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 =3D new_unrhdr(PID_MAX + 2, INT_MAX, &tid_lock);
=20
 	thread_zone =3D uma_zcreate("THREAD", sched_sizeof_thread(),
diff --git a/sys/kern/subr_param.c b/sys/kern/subr_param.c
index 8c13336..1c6b867 100644
--- a/sys/kern/subr_param.c
+++ b/sys/kern/subr_param.c
@@ -41,12 +41,13 @@ __FBSDID("$FreeBSD$");
 #include "opt_msgbuf.h"
 #include "opt_maxusers.h"
=20
-#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>
=20
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -92,6 +93,7 @@ int	ncallout;			/* maximum # of timer events */
 int	nbuf;
 int	ngroups_max;			/* max # groups per process */
 int	nswbuf;
+pid_t	pid_max =3D 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 =3D NGROUPS_MAX;
+
+	/*
+	 * Only allow to lower the maximal pid.
+	 */
+	TUNABLE_INT_FETCH("kern.pid_max", &pid_max);
+	if (pid_max > PID_MAX)
+		pid_max =3D PID_MAX;
 }
=20
 /*
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 3883fe4..39e2a58 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -673,7 +673,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void=
 *addr, int data)
 		p =3D td->td_proc;
 		PROC_LOCK(p);
 	} else {
-		if (pid <=3D PID_MAX) {
+		if (pid <=3D pid_max) {
 			if ((p =3D pfind(pid)) =3D=3D NULL) {
 				if (proctree_locked)
 					sx_xunlock(&proctree_lock);
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index 416cd1d..0c53be1 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -98,6 +98,7 @@ nlm_client_init(void *dummy)
 	int i;
=20
 	mtx_init(&nlm_svid_lock, "NLM svid lock", NULL, MTX_DEF);
+	/* pid_max cannot be greater then PID_MAX */
 	nlm_svid_allocator =3D new_unrhdr(PID_MAX + 2, INT_MAX, &nlm_svid_lock);
 	for (i =3D 0; i < NLM_SVID_HASH_SIZE; i++)
 		LIST_INIT(&nlm_file_svids[i]);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 06df632..4c4aa2f 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -696,11 +696,12 @@ MALLOC_DECLARE(M_SUBPROC);
 #define	FIRST_THREAD_IN_PROC(p)	TAILQ_FIRST(&(p)->p_threads)
=20
 /*
- * We use process IDs <=3D 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 <=3D pid_max <=3D 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;
=20
 #define	SESS_LEADER(p)	((p)->p_session->s_leader =3D=3D (p))
=20

--/unnNtmY43mpUSKx
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAlAqTXQACgkQC3+MBN1Mb4jyawCg1eYRwUtO8pL/8ebpRVsFamsB
FCsAoIq1cgz0KNM/dpZHrjtlYwZHHcsS
=IfFX
-----END PGP SIGNATURE-----

--/unnNtmY43mpUSKx--



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