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
How to Establish Ssl Connection Upon Wget on Ubuntu 14.04 Lts
Need to Remove the Count from the Output When Using "Uniq -C" Command
Best Practice to Run Linux Service as a Different User
Bash Script: Using "Script" Command from a Bash Script for Logging a Session
Prevent Linux Thread from Being Interrupted by Scheduler
Linux/Unix Environment Variables
Unix: How to Delete Files Listed in a File
Linux: Command to Open Url in Default Browser
Receiving Key Press and Key Release Events in Linux Terminal Applications
Linux X64: Why Does R10 Come Before R8 and R9 in Syscalls
Interpreting Segfault Messages
Unix - Create Path of Folders and File
How to Portably Extend a File Accessed Using Mmap()
What Is an Anonymous Inode in Linux