select() and huge fd count per process

Vedad Kajtaz (vk@mankind.net)
Wed, 30 Dec 1998 07:38:36 +0100


Hi,

I'm writing a server that is supposed to support to support up to 2000
simultaneously
connected people (the network engine is using select()) and have few
hundreds of
file descriptors open (other than 2000 sockets)

The problem is that the kernel, by default, doesn't allow as much open
file descriptors
open as that. Thus, i applied the filehandle.patch.linux.v8.04 patch
against 2.0.36 kernel, as
i've been told this would solve my problem.

What happens is strange:
i compiled and run 3 servers on that computer; two of them work just
fine. The third
one, unlike 2 others, first opens 1500 files, then starts accepting
client. His problem
is that his select() never sleeps*; when stracing it, i saw select
dealing with bogus fd's (i checked
the network engine, FD_ZERO is called before select, than FD_SET is
called for each
socket, engine logs showed that descriptors that appears in strace are
_not_ set by FD_SET)
This doesn't happen if the third server is run on a separate computer
(same hardware, same rh distrib and same kernel config)

*this occurs even when thers no clients connected, global socket count
for the 3 servers
is 1500 open files + 3 listen()ing sockets

this might mean that the patch i've applied didnt take care of select(),
FD_SETSIZE and FD_ macros?
anyway, my real question would be "what do i have to do to make a server
able to accept up to
X clients in select() and have up to Y file descriptors open) by one
process?", X and Y being quite large :-)

Here is my config:

{
max fds per process: 4096
max number of process: 512
} in general setup, brought by the filehandle patch

i included those lines at the end of /etc/rc.d/rc.sysinit (redhat 5.1):

echo 12288 >/proc/sys/kernel/inode-max
echo 4096 >/proc/sys/kernel/file-max

(a subquestion: is there a ratio between inode-max and file-max values
numbers? is so, what is it,
and why?)

i do this as one of first things in main() for all servers:
struct rlimit Limits;

Limits.rlim_cur = MAXFILES_CUR; // 4096 in .h, tried with
lower values too
Limits.rlim_max = MAXFILES_MAX; // 4096 in .h

if(setrlimit(RLIMIT_NOFILE, &Limits) != 0)
{
Log(ServerLog, "setrlimit() failed!"); // ServerLog
is the only fd i've opened before

// calling setrlimit
FatalError("setrlimit() failed!");
}
// without doing this, socket() and fopen() calls fail starting with
about 250-300th fds in use

am i doing something wrong?
if not, are there other stable patches for doing this?
(i have to use 2.0.36 as aic driver was broken on previous version,
couldnt boot with both adaptec-dontrememberthenumber and
ncr-dontremember cards, so i need a patch that applies to
2.0.36)
As the game started and the servers are already in use, i can't afford
installing an untested kernel and/or patch.

Please help! :)

-- Vedad Kajtaz

PS: email me if you need more info (ie strace output, kernel
configfile,..)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/