Reset Search
 

 

Article

KB43935 - File descriptor limits and vTM

« Go Back

Information

 
Last Modified Date11/13/2020 1:01 PM
Synopsis
This article explains the file descriptor limits on Linux and how they affect the vTM behaviour.
Problem or Goal
There are 4 different parameters involved in file descriptor limits which can be confusing to understand what they mean and how they interact.
Cause
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.

  1. 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
  2. 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

  1. 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).
  2. 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
  3. 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
  4. /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:

  1. 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.

  2. 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
  3. 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
    ...
Related Links
Attachment 1 
Created ByLaurence Darby

Feedback

 

Was this article helpful?


   

Feedback

Please tell us how we can make this article more useful.

Characters Remaining: 255