[cs631apue] Openmax.c fails earlier than expected

Jan Schaumann jschauma at stevens.edu
Wed Sep 16 11:49:44 EDT 2020


Charles Magyar IV <cmagyar at stevens.edu> wrote:
> If errno == EMFILE, the errno = 24.  "Too many open files" according to the man page of errno.
> 
> In the else block, errno equals 23 during my run.
> This is ENFILE, and means "Too many open files in system.
>  Maximum number of file descriptors allowable on the system has been reached and a request
>  for an open cannot be satistfied until at least one has been closed."
> 
> So it turns out that the entire system is simply out of space.

Correct.  That is, there's a difference between _a
process_ having reached the limit of how many files it
can open and _the whole system_ having reached its
limit.

Normally, the limit for a process is smaller than that
of the entire system, but we bumped it to 'unlimited',
meaning we set the per-process limit to be equal to
that of the system-wide limit.

Since nowe we're talking about the system wide limit,
we are no longer just competing with ourselves, but
with all processes on the system.  In other words, any
file open by any other process reduces the number of
files our process can open.

So the number of files we can open before encountering
ENFILE should be:

ourfiles = number of files this process can open 
otherfiles = number of files open by any other process
max = system wide limit, i.e., 3404 in this case

ourfiles = max - otherfiles

> In another test, I ran
>  >  fstat | wc -l
> > 249

fstat(1) shows us the open _file descriptors_, but the
limit is on entries in the file table.  That is, if a
process has multiple file descriptors pointing to the
same file table entry (such as e.g., duplicated file
descriptors such as when a process has stdin,
stdout, and stderr all connected to terminal), only
the one file table entry counts towards the limit.

You can use the pstat(1) command with the '-f' flag to
show you the collated mapping; the output includes a
column "CNT" that shows you how many  references to
the givenf ile table entry there are.

You can also use 'fstat -A' to get the relevant object
address, and correlate it with the output of 'pstat'.
For example:

$ fstat -A | sort -k1,1 | grep pts/0
ffffcf1371e74040 jschauma sh          1995    0 /dev/pts        3 crw--w----   pts/0 rw
ffffcf1371e74040 jschauma sh          1995    1 /dev/pts        3 crw--w----   pts/0 rw
ffffcf1371e74040 jschauma sh          1995    2 /dev/pts        3 crw--w----   pts/0 rw
...
$ fstat -A | sort -k1,1 | grep -c pts/0
17
$ $ pstat -f | grep ffffcf1371e74040
ffffcf1371e74040 file        RW   14    0 ffffcf136cc22970   0  372401

That is, pstat(1) shows us that there are 14
references to /dev/pts/0 (our pseudo-terminal).

(But fstat(1) showed us 17 - can you find out why
'pstat' showed 3 fewer?)

Anyway, try to run the same command and compare to the
output of 'pstat -f'.  Does that match the number of
files you are then able to open?

-Jan


More information about the cs631apue mailing list