[comp.unix.wizards] Determining the max number of open files on System V

dave@romano.WISC.EDU (Dave Cohrs) (06/01/87)

I'm trying to port a program from BSD to Sys V Rel. 3.  Along the way,
it tries to close all of its file descriptors.  On BSD you just call
getdtablesize() to find how many to close, but I can't seem to find
the equivalent on S5R3.

Originally I thought, "Oh, that's, easy, just include <sys/param.h>
and close 0 through NOFILE". Well, I looked at <sys/param.h> and
it said,

	"The following define is here for temporary compatibility
	and should be removed in the next release.  It gives a
	value for the maximum number of open files per process.
	However, this value is no longer a constant."

So, where do I get the real value?  What is "v.v_nofiles" and how do
I get at it's value?

Please, don't tell me I have to muck around in kernel memory!

-- 
Dave Cohrs                                             Proud member of NOTHING
+1 608 262-2196                             UW-Madison Computer Sciences Dept.
dave@cs.wisc.edu                 ...!{harvard,ihnp4,seismo,rutgers}!uwvax!dave
Dave Cohrs                                             Proud member of NOTHING
+1 608 262-2196                             UW-Madison Computer Sciences Dept.
dave@cs.wisc.edu                 ...!{harvard,ihnp4,seismo,rutgers}!uwvax!dave

guy%gorodish@Sun.COM (Guy Harris) (06/01/87)

> I'm trying to port a program from BSD to Sys V Rel. 3.  Along the way,
> it tries to close all of its file descriptors.  On BSD you just call
> getdtablesize() to find how many to close, but I can't seem to find
> the equivalent on S5R3.
> 
> So, where do I get the real value?  What is "v.v_nofiles" and how do
> I get at it's value?

You do

	ulimit(4, 0L);

and the returned value is the maximum number of file descriptors.  Or,
preferably, you do

	int
	getdtablesize()
	{
		extern long ulimit();

		return (ulimit(4, 0L));
	}

and obviate the need to fix all occurrences of "getdtablesize".

No, this isn't documented.  It seems AT&T is maintaining the proud
"use the Force, read the Source" tradition of earlier UNIX
releases....  (They also seem to be maintaining the equally proud
"different for its own sake" or "Not Invented Here" tradition; why
the hell couldn't they have added a "getdtablesize" system call, or
even just supplied a wrapper around "ulimit"?  Whether they like it
or not, "getdtablesize" is as close as you can get to a *de facto*
standard name for the routine that returns the size of the
per-process file table.)
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/02/87)

In article <3635@spool.WISC.EDU> dave@romano.WISC.EDU (Dave Cohrs) writes:
>	"The following define is here for temporary compatibility
>	and should be removed in the next release.  It gives a
>	value for the maximum number of open files per process.
>	However, this value is no longer a constant."

It is quite possible that the value may become "limited only by
availability of kernel dynamic data pool space".  I would suggest
finding another approach that does not depend on there being a
constant limit for this.  However, in the meanwhile you could try
closing all the fds in sequence up to some large number like 128.
Very few programs would ever have fds that large.

kimcm@olamb.UUCP (Kim Chr. Madsen) (06/03/87)

In article <3635@spool.WISC.EDU>, dave@romano.WISC.EDU (Dave Cohrs) writes:
> Originally I thought, "Oh, that's, easy, just include <sys/param.h>
> and close 0 through NOFILE". Well, I looked at <sys/param.h> and
> it said,
> 
> 	"The following define is here for temporary compatibility
> 	and should be removed in the next release.  It gives a
> 	value for the maximum number of open files per process.
> 	However, this value is no longer a constant."
> 
> So, where do I get the real value?  What is "v.v_nofiles" and how do
> I get at it's value?

If you just want to know the actual number run the command "/etc/sysdef",
which gives you the current settings of the turnable kernel parameters
and other system information. Or look into the /etc/master.d/kernel file.

But if you want to inspect the max. number of open files at runtime, you
must use the value stored in the kernel.

> Please, don't tell me I have to muck around in kernel memory!

Don't panic use the nlist(3C) call with the v structure (defined in
<sys/var.h>) the value of v.v_nofiles contains the actual value.

					Regards
					Kim Chr. Madsen

bzs@bu-cs.bu.EDU (Barry Shein) (06/07/87)

From: "Kim Chr. Madsen" <kimcm@olamb.uucp>
>If you just want to know the actual number run the command "/etc/sysdef",
>which gives you the current settings of the turnable kernel parameters
>and other system information. Or look into the /etc/master.d/kernel file.
>
>But if you want to inspect the max. number of open files at runtime, you
>must use the value stored in the kernel.
>
>> Please, don't tell me I have to muck around in kernel memory!

Or just fork off an /etc/sysdef as part of the runtime startup of your
program and get it out of that, maybe use awk to help pluck it out,
consider using popen() or system() into a temp file, or just wrap your
program in a little shell program and feed the value you need in from
the top, say as a command line flag, backquotes come in handy here.

I've written a number of programs which use things like ps and ls to
get info while maximizing portability, they don't take much longer
than you doing the same exact groveling and it's much easier to get
working, and works or is trivially fixable when the next release is
put up on your system or you need to move to a variant. I'd recommend
using a subroutine which forks the job simply because on 4.x you can
use getdtablesize() so it would be trivial to conditionalize at
compile-time.

Remember guys, this is Unix, we keep forks cheap for a reason, why
reinvent the wheel?

	-Barry Shein, Boston University

jfh@killer.UUCP (06/08/87)

In article <7730@brl-adm.ARPA>, bzs@bu-cs.bu.EDU (Barry Shein) writes:
>                                                         I'd recommend
> using a subroutine which forks the job simply because on 4.x you can
> use getdtablesize() so it would be trivial to conditionalize at
> compile-time.
> 
> Remember guys, this is Unix, we keep forks cheap for a reason, why
> reinvent the wheel?
> 
> 	-Barry Shein, Boston University

I was the guy at my last job who benchmarked unix on our system.  I learned
many things from this little experience.  Rule 1:  Fork is as expensive a
system call as you can get.  The only thing more expensive is fork/exec.
Rule 2:  Emulation libraries are easy to write.  Writing getdtablesize()
is worth the effort especially since you can sell it as a 'Berkeley
Enhancement' - or your can always use it yourself when dealing with all of
the code from usenet that uses it.

Don't fork - please.  I believe there are no fewer than 2 forks() per
system(3) call, and a 68000 machine can only handle 30 or so per second,
depending on the size of the module.

- John.

guy@gorodish.UUCP (06/08/87)

> Remember guys, this is Unix, we keep forks cheap for a reason, why
> reinvent the wheel?

Remember guys, this is UNIX where developers forget to document all
sorts of useful things, they put "ulimit(4, 0L)" in for a reason.
The way you get the max number of open files in S5R3 is

	int ndescriptors;
	extern long ulimit();

	ndescriptors = ulimit(4, 0L);

as indicated in my previous posting, not by various unnecessary
kludges involving poking around in "/dev/kmem" or running
"/etc/sysdef".
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

domo@riddle.UUCP (06/10/87)

Agreed that finding out how many files you have to close in order to be
sure you've closed them all is a pain on most implementations of UN*X.
IEEE 1003.1 is attempting to address this and related issues (after they
were highlighted by IBM and others).

The current draft (#10) of 1003.1, which recently dropped
stone-like through my (physical) mailbox, incorporates something that I and
others cooked up at the April Toronto meeting.  The affected section is
2.9, "Numerical Limits".  As the changes have yet to be reviewed by the
working group, they may well be thrown out or heavily modified later this
month.

Basically what the draft says is that things like OPEN_MAX, the maximum
number of files that a process can have open at any given time, are defined
in a header file, <limits.h>, as "bounded ranges".  OPEN_MAX defines at
compile time the "minimum maximum" number of files that a program can
expect to be able to have open when it runs on a particular
POSIX-conforming implementation (provided that the host system is not
overloaded, that is, in this case, that it hasn't run out of space in its
system open file or inode tables), while OPEN_MAX_CEIL defines the maximum
number of files that any instance of this implementation could ever allow
the program to have open.

What this means to the programmer is that applications may be written so
that they rely on being able to open OPEN_MAX files; so that they run
better if they succeed in opening more files than that (although there's no
point in trying if OPEN_MAX_CEIL are already open); and so that they can be
sure that everything is closed (when spawning children, for example) if they

	for (i = 0; i < OPEN_MAX_CEIL; (void) close(i++));

Thanks for the idea of the bounded range are due to Terence Dowling of Rolm,
who's not on the net.

There's much more of this sort of thing in the draft standard.  The
alternative to this compile-time approach is a run-time library function
which delivers either all possible information (in which case you get a
fixed-size structure, and lose binary application compatibility if in 
subsequent releases of a particular POSIX-conforming implementation the
amount of information returned increases); or requested items one at a time
in some sort of union.  If anybody would care to submit a proposal along
these lines to the working group, it is likely that it would be gladly
received.

(Binary compatibility is outside the terms of reference of 1003.1, but that
doesn't stop people from caring about it.)

Copy relevant correspondence to John S Quarterman, moderator for
comp.std.unix.  He can be reached at ut-sally!std-unix.

I am
Dominic Dunlop	Phone +44 628 75343
Sphinx Ltd.	UKnet domo@sphinx.co.uk

POSIX is a trademark of the IEEE

jimr@hcrvx2.UUCP (Jim Robinson) (06/11/87)

In article <20599@sun.uucp> guy@gorodish.UUCP writes:
>Remember guys, this is UNIX where developers forget to document all
>sorts of useful things, they put "ulimit(4, 0L)" in for a reason.
>The way you get the max number of open files in S5R3 is

Is there not a certain amount of risk in using an undocumented feature,
as there is no guarantee whatsoever that it will  exist in later
releases?

J.B. Robinson

bzs@bu-cs.bu.EDU (Barry Shein) (06/17/87)

John Haugh responding to my note:
>Don't fork - please.  I believe there are no fewer than 2 forks() per
>system(3) call, and a 68000 machine can only handle 30 or so per second,
>depending on the size of the module.
>
>- John.

Gee, then I assume you can code more than 30 /dev/kmem grovelers per
second and fix them just as quick on each change to the OS? Port them
to machines that don't support a /dev/kmem? A microbuck saved is a
microbuck earned I suppose.

I also assume this means you are recommending against shell scripts
and pipes and all that nonsense, just litters the system with lots of
fork/execs, feh! Better everyone on the system just programs
everything themselves, maybe we should delete everything but an editor
and the C compiler.

	-Barry Shein, Boston University

hansen@pegasus.UUCP (Tony L. Hansen) (06/24/87)

< Remember guys, this is UNIX where developers forget to document all
< sorts of useful things, they put "ulimit(4, 0L)" in for a reason.
< The way you get the max number of open files in S5R3 is
< 
< 	int ndescriptors;
< 	extern long ulimit();
< 	ndescriptors = ulimit(4, 0L);

This feature is documented in the System V release 3.1 documentation. So now
you can safely expect it to remain there for awhile. :-)

					Tony Hansen
					ihnp4!pegasus!hansen