Date: Fri, 26 Apr 2013 17:59:33 +0200 From: Jilles Tjoelker <jilles@stack.nl> To: Bruce Evans <brde@optusnet.com.au> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org Subject: Re: svn commit: r249859 - head/lib/libc/sys Message-ID: <20130426155933.GA24412@stack.nl> In-Reply-To: <20130425204458.F1034@besplex.bde.org> References: <201304242124.r3OLOZW5034818@svn.freebsd.org> <20130425204458.F1034@besplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Apr 25, 2013 at 09:56:01PM +1000, Bruce Evans wrote: > On Wed, 24 Apr 2013, Jilles Tjoelker wrote: > > Log: > > getdtablesize(2): Describe what this function actually does. > > getdtablesize() returns the limit on new file descriptors; this > > says nothing about existing descriptors. > It's still quite broken. > > Modified: head/lib/libc/sys/getdtablesize.2 > > ============================================================================== > > --- head/lib/libc/sys/getdtablesize.2 Wed Apr 24 21:21:03 2013 (r249858) > > +++ head/lib/libc/sys/getdtablesize.2 Wed Apr 24 21:24:35 2013 (r249859) > > @@ -28,12 +28,12 @@ > > .\" @(#)getdtablesize.2 8.1 (Berkeley) 6/4/93 > > .\" $FreeBSD$ > > .\" > > -.Dd June 4, 1993 > > +.Dd April 24, 2013 > > .Dt GETDTABLESIZE 2 > > .Os > > .Sh NAME > > .Nm getdtablesize > > -.Nd get descriptor table size > > +.Nd get file descriptor limit > Now its name doesn't match its description, and the reason for this is > not documented. This seems to be the case on most systems that have this function. > This function is almost obsolete. In POSIX, it is spelled {OPEN_MAX} > or sysconf(__SC_OPEN_MAX). It is sometimes misspelled OPEN_MAX. There is a difference between sysconf(_SC_OPEN_MAX) and getdtablesize(): the latter also takes maxfilesperproc and rctl(8) rules into account. > I prepared to remove the broken definition of OPEN_MAX, but never committed > the final step. /usr/src has very few misuses of OPEN_MAX now, so removing > the definition wouldn't be too hard. Most uses are in compatibility > cruft. E.g., the following from > crypto/openssh/openbsd-compat/bsd-closefrom.c > which is confused about related things: > [snip] If that code is compiled at all, it is a bug. We have closefrom() and OpenSSH should use it. > ... in 4.4BSD and FreeBSD, both sysconf(_SC_OPEN_MAX) are just wrappers for > the resource limit (sysconf() is a libc wrapper and getdtablesize() is > a syscall wrapper). Actually, in FreeBSD, getdtablesize() is not even the > rlmint -- it is the min() of the rlimit and the global sysctl integer > maxfilesperproc. Here the bug is in the rlimit. For the rlimit, > maxfilesperproc is only used when the rlimit is set and when it is used > in the kernel. But when the rlimit is returned to userland, via > getrlimit(), maxfilesperproc is not used, so the rlimit may be wrong if > maxfileperproc was lowered after setting the rlimit. I don't like the idea of rlimits changing of "their own will". Changing maxfileperproc at run time is going to be a bit nasty in any case but seems not as bad as changing rlimits of running processes. > [snip] > > .Sh LIBRARY > > .Lb libc > > .Sh SYNOPSIS > > @@ -41,18 +41,20 @@ > > .Ft int > > .Fn getdtablesize void > > .Sh DESCRIPTION > > -Each process has a fixed size descriptor table, > Actually, each process has a variable size descriptor table, and > getdtablesize() doesn't give the size of this table. > > -which is guaranteed to have at least 20 slots. > Actually, {OPEN_MAX} is guaranteed by POSIX to be at least > {_POSIX_OPEN_MAX}, and {_POSIX_OPEN_MAX} is precisely 20. But these > guarantees and similar ones for stdio's FOPEN_MAX have always been > broken in FreeBSD, since anyone can reduce the rlimit below 20. > Privileged users can break the gurantee even more easily by setting > maxfilesperproc below 20. When POSIX standardized rlimits, it didn't > properly specify the behaviour for the interaction of the rlimit with > {OPEN_MAX}, at least initially. The 2001 version breaks its own > guarantee by just saying that if the rlimit is reduced to less than > {_POSIX_OPEN_MAX}, then "unexpected behaviour may occur". Reductions > from 707112 to less than 20 won't occur often in practice. Ones from > 707112 to less than the largest currently open fd (+1) are more common > in practice and cause similarly unexpected behaviours, but the 2001 > version of POSIX is even more underspecified for them. Recent versions of POSIX allow {OPEN_MAX} to be based on the rlimit. In that case, it may change when the rlimit is changed. I think the "unexpected behaviour may occur" is intended to allow both permitting an rlimit below 20 and forbidding such a change. In the former case, the execution environment is no longer POSIX compliant. In particular, on most systems, setting the rlimit to 0 disables all operations that need to open a new file descriptor and it is implementation-specific which operations are affected (in addition to those returning a file descriptor). > > -The entries in > > -the descriptor table are numbered with small integers starting at 0. > Still correct, though not very interesting. > > The > > .Fn getdtablesize > > -system call returns the size of this table. > > +system call returns the maximum number of file descriptors > > +that the current process may open. > Actually, the process may open more than this number, after raising its > (soft) rlimit, if this is possible. True, but this requires different function calls than just ones allocating file descriptors. > > +The maximum file descriptor number that the system may assign > > +is the return value minus one. > > +Existing file descriptor numbers may be higher > > +if the limit was lowered after they were opened. > > .Sh SEE ALSO > > .Xr close 2 , > > +.Xr closefrom 2 , > > .Xr dup 2 , > > -.Xr open 2 , > > -.Xr select 2 > > +.Xr getrlimit 2 , > > +.Xr sysconf 2 > > .Sh HISTORY > > The > > .Fn getdtablesize I suppose rctl(8) can be added here. > open(2) is probably still relevant. It seems to be the natuaral place to > document {OPEN_MAX}, but it says nothing about any spelling of OPEN_MAX. > (The closest that it gets is saying that [EMFILE] means that the process > has reached its limit for open file descriptors. Not sure if open(2) is indeed the right place. > apropos(1) gives nothing appropriate for OPEN_MAX. In fact, even > OPEN_MAX is not mentioned in any man page. Only _SC_OPEN_MAX is > mentioned (in sysconf(3)), and it is misdescribed as being the > maximum number of open files per user id.) Yes, wrong. > Some limits are better descrtibed than {OPEN_MAX}, in intro(2). I was > a little surprised to not find much about the file descriptor limits > there. In fact, there is a very incomplete description of them for > [EMFILE]. This says that the limit is the release one of 64 (that was > for the 4.4BSD-Lite* release) and that getdtablesize(2) will obtain the > current limit. Similar historical limits have been changed to POSIX > ones mainly for pathnames. Hmm, that sentence about a limit of 64 can go away. -- Jilles Tjoelker
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130426155933.GA24412>