Solution | The 4 parameters are: sysctls fs.file-max and fs.nr_open , and a process's soft and hard limits.
When the soft and hard limits get hit and the effect:
This section discusses all the situations where the limits get hit.
- A process can open a number of files up to its soft limit and no more. Generally, a process opens files with the
open() syscall, but can be others e.g. fork() . If it tries to open more files than the soft limit, the syscall will return the error code:
-1 EMFILE (Too many open files)
What happens then depends on how the application was programmed; it could deal with the situation gracefully and log an error message, or it could crash. vTM will notice when it's running low on free fds even before the error happens, and logs the warning message:
WARN fewfreefds
Running out of free file descriptors, see documentation for information on how to increase limit
- If the total number of open fds on the system is equal to or greater than the sysctl
fs.file-max , and if the process doesn't have root privileges, then that process will get the above -1 EMFILE error if it attempts to open more files. If the process has root privileges, then it can continue opening files above the fs.file-max limit, up to its soft limit.
How to see the limits
-
syscalls used by programs
getrlimit() will return the hard and soft limits.
prlimit() can return and set the hard and soft limits.
sysconf() can only return the soft limit (with the parameter _SC_OPEN_MAX).
-
prlimit program
The prlimit program is a wrapper around the prlimit() syscall. E.g. to get the limit of your current shell:
# prlimit --nofile
RESOURCE DESCRIPTION SOFT HARD UNITS
NOFILE max number of open files 1024 4096 files
To get the limit of another process:
# prlimit --nofile -p 21739
RESOURCE DESCRIPTION SOFT HARD UNITS
NOFILE max number of open files 1048576 1048576 files
-
getconf program
This is a wrapper around the sysconf() c library call (which in turn calls prlimit() ), and likewise only supports showing the soft limit, not the hard limit.
# getconf OPEN_MAX
1024
-
/proc filesystem
The file /proc/<pid>/limits shows the current limits for any given pid.
# grep files /proc/2408/limits
Max open files 1024 4096 files
How to increase the limits:
-
prlimit()/setrlimit() syscalls
If programmed to do so, a process can raise its soft limit up to its hard limit, with the prlimit() or setrlimit() syscalls. If the process has root privileges, it can raise its hard limit (and hence soft limit) up to the value of the sysctl fs.nr_open (additionally since it has root privileges, it could also raise the fs.nr_open sysctl value up to some kernel defined limit, and hence also its hard and soft limits). Examples of interfaces various software uses:
vTM: System > Global Settings > System Settings > maxfds (This is mentioned in the docs referenced in the error message above) bash: ulimit -n <number> SSHD and other login management software linked with PAM (Pluggable Authentication Modules) uses the file /etc/security/limits.conf to configure the limits. All of these interfaces simply tell the software to call prlimit() or setrlimit() with the value given, for relevant hard or soft limit.
-
Inheritance
A process will inherit the limits of the process that spawned it. Typically this is your shell or /sbin/init. Therefore if a program doesn't have a feature to call prlimit(), its limits can still be set, by setting the limit in the calling process e.g. your shell, then restarting the process from that. E.g. in bash:
# ulimit -n 12345
# sleep 30 &
[1] 13049
# grep files /proc/`pidof sleep`/limits
Max open files 12345 12345 files
-
prlimit command
The prlimit command is a wrapper around the prlimit() syscall, hence it can modify the limits of any other process, if it has permission.
# sleep 30 &
# prlimit --nofile=123 -p `pidof sleep`
# grep files /proc/`pidof sleep`/limits
Max open files 123 123 files
The prlimit program can also start new processes with a custom limit:
# prlimit --nofile=1234 sleep 30 &
[4] 11992
# grep files /proc/`pidof sleep`/limits
Max open files 1234 1234 files
This is actually just an example of inheritance, which we can see using strace:
strace prlimit --nofile=1234 /bin/sleep 1
...
prlimit64(0, RLIMIT_NOFILE, {rlim_cur=1234, rlim_max=1234}, NULL) = 0
execve("/bin/sleep", ["/bin/sleep", "1"], 0x7ffc9cbbb630 /* 66 vars */) = 0
...
|
|
---|