Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Sep 1996 07:07:01 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-current@freebsd.org, rwm@MPGN.COM
Subject:   Re: Max Files Open
Message-ID:  <199609132107.HAA24395@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>We had changed the Kernel Parameter (params.c)
>maxfilesperproc to 2048 and rebuilt the Kernel.  It still only let us have
>64 files open.  (FreeBSD 2.2-current)  After searching around for 64
>through all the C and H files we found a #define in syslimits.h:
>
>#define OPEN_MAX 64
>
>Which also claimed to be the per process file descriptor limit.  
>
>Why are their two different parameters?  Under Ultrix, we just changed the
>one file in params.c and it was done.  Seems to me these should be the same.

Historical reasons.  OPEN_MAX is a POSIX constant that is supposed to
be defined if the limit on the number of open files can be determined at
compile time.  It can't be determined at compile time on any system that
has setrlimit(2), so it shouldn't be defined.  It is also (ab)used to
set the soft rlimit on the number of open files (indirectly; the equally
bogus constant NOFILES is defined as OPEN_MAX and used in init_main.c to
initialize to soft limit for proc0; the limit is inherited across forks).

In early versions of FreeBSD, the maxfilesperproc limit didn't exist.
The limit was maxfiles, which can be changed at runtime using sysctl(8).
maxfilesperproc was supposed to allow more flexibility, but it can no
longer be changed using sysctl in -current.  No one complained when it
was broken, so I guess no one actually uses it.

There are some bugs and inherent problems in getrlimit() and setrlimit()
involving the fuzzy hard limit.  The limit is initially RLIM_INFINITY =
0x7fffffffffffffff but it metamorphoses to maxfilesperproc when it is
set and may change again if maxfilesperproc is changed.  The bug causes
strange behaviour in the ulimit command in /bin/sh:

	$ ulimit -n
	64  # soft limit
	$ ulimit -H -n
	unlimited  # it won't tell yout that this is 0x7fffffffffffffff
	$ ulimit -n 99999
	# no error, although 99999 is much larger than the real hard limit
	$ ulimit -n
	360
	$ ulimit -H -n
	360
	$ ulimit -n 99999
	ulimit: bad limit: Operation not permitted  # because 99999 > 360

POSIX specifies that the limit doesn't change across process lifetimes
to avoid problems like this.  This is fundamentally incompatible with
setrlimit(), but this shouldn't be a problem because processes should
keep track of changes when they call setrlimit().  OTOH, changes
to maxprocperuid may cause problems.  Fix: set the hard limit to
maxprocperuid at fork time and don't change it later.  This also fixes
the bogus initial infinite limit.

Similer bogons afflict CHILD_MAX/MAXUPRC, maxproc and maxuprocperuid.
One more: the sysctl variable kern.maxproc read-only in -current.

Bruce



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