Check the Open Fd Limit for a Given Process in Linux

Check the open FD limit for a given process in Linux

Count the entries in /proc/<pid>/fd/. The hard and soft limits applying to the process can be found in /proc/<pid>/limits.

Max open files for working process

As a system administrator: The /etc/security/limits.conf file controls this on most Linux installations; it allows you to set per-user limits. You'll want a line like myuser - nofile 1000.

Within a process: The getrlimit and setrlimit calls control most per-process resource allocation limits. RLIMIT_NOFILE controls the maximum number of file descriptors. You will need appropriate permissions to call it.

About limiting the number of file descriptors

/proc/sys/fs/file-max takes precedence over any ulimit settings in the shell.

More over /proc/sys/fs/file-max is the total number of FD open for ALL processes on given machine.

ulimit settings are per process, so any new process started will have given limit (unless the total form file-max is exceeded in the system).

Counting open files per process

Have a look at the /proc/ file system:

ls /proc/$pid/fd/ | wc -l

To do this for all processes, use this:

cd /proc
for pid in [0-9]*
do
echo "PID = $pid with $(ls /proc/$pid/fd/ | wc -l) file descriptors"
done

As a one-liner (filter by appending | grep -v "0 FDs"):

for pid in /proc/[0-9]*; do printf "PID %6d has %4d FDs\n" $(basename $pid) $(ls $pid/fd | wc -l); done

As a one-liner including the command name, sorted by file descriptor count in descending order (limit the results by appending | head -10):

for pid in /proc/[0-9]*; do p=$(basename $pid); printf "%4d FDs for PID %6d; command=%s\n" $(ls $pid/fd | wc -l) $p "$(ps -p $p -o comm=)"; done | sort -nr

Credit to @Boban for this addendum:

You can pipe the output of the script above into the following script to see the ten processes (and their names) which have the most file descriptors open:

  ...
done | sort -rn -k5 | head | while read -r _ _ pid _ fdcount _
do
command=$(ps -o cmd -p "$pid" -hc)
printf "pid = %5d with %4d fds: %s\n" "$pid" "$fdcount" "$command"
done

Here's another approach to list the top-ten processes with the most open fds, probably less readable, so I don't put it in front:

find /proc -maxdepth 1 -type d -name '[0-9]*' \
-exec bash -c "ls {}/fd/ | wc -l | tr '\n' ' '" \; \
-printf "fds (PID = %P), command: " \
-exec bash -c "tr '\0' ' ' < {}/cmdline" \; \
-exec echo \; | sort -rn | head

Getting count of current used file descriptors from C code

For the current process count, you can use getrlimit to get the file descriptor limit, then iterate over all integers from 0 to that limit and try calling fcntl with the F_GETFD command. It will succeed only on the file descriptors which are actually open, letting you count them.

Edit: I now have a better way to do it. After getting the rlimit, make a large array of struct pollfd (as large as the limit if possible; otherwise you can break it down into multiple runs/calls) with each fd in the range and the events member set to 0. Call poll on the array with 0 timeout, and look for the POLLNVAL flag in the revents for each member. This will tell you which among a potentially-huge set of fds are invalid with a single syscall, rather than one syscall per fd.

Max number of open files per process in Linux

There is no issue here.

A pipe has two ends, each gets its own file descriptor.

So, each end of a pipe counts as a file against the limit.

The slight difference between 1024/2 = 512 and 510 is because your process has already opened the files stdin, stdout, and stderr, which counts against the limit.

Finding open file descriptors for a process linux ( C code )?

Since you're on Linux, you've (almost certainly) got the /proc filesystem mounted. That means that the easiest method is going to be to get a list of the contents of /proc/self/fd; each file in there is named after a FD. (Use g_dir_open, g_dir_read_name and g_dir_close to do the listing, of course.)

Getting the information otherwise is moderately awkward (there's no helpful POSIX API for example; this is an area that wasn't standardized).



Related Topics



Leave a reply



Submit