From owner-freebsd-current Fri Sep 13 14:09:45 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id OAA17462 for current-outgoing; Fri, 13 Sep 1996 14:09:45 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.5/8.7.3) with SMTP id OAA17451 for ; Fri, 13 Sep 1996 14:09:37 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id HAA24395; Sat, 14 Sep 1996 07:07:01 +1000 Date: Sat, 14 Sep 1996 07:07:01 +1000 From: Bruce Evans Message-Id: <199609132107.HAA24395@godzilla.zeta.org.au> To: freebsd-current@freebsd.org, rwm@MPGN.COM Subject: Re: Max Files Open Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >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