How to set limits (ulimit) for services in RHEL6 and older with upstart, sysvinit

Solution Verified - Updated

Environment

  • Red Hat Enterprise Linux 4
  • Red Hat Enterprise Linux 5
  • Red Hat Enterprise Linux 6

Issue

  • How to set limits for services started at boot

  • Limits are not set for services starting at boot even though they are configured in /etc/security/limits.conf or in files under /etc/security/limits.d

  • Restarting the service sets the limits correctly

  • Process address space limit is not taking effect following patching

Resolution

See also: How to set limits (ulimit) for services run by systemd for Red Hat Enterprise Linux (RHEL) 7


  1. Execute help ulimit from a shell to determine the options for desired limits

    ~]# help ulimit
    ulimit: ulimit [-SHacdefilmnpqrstuvx] [limit]
        Modify shell resource limits.
        
        Provides control over the resources available to the shell and processes
        it creates, on systems that allow such control.
        
        Options:
          -S	use the `soft' resource limit
          -H	use the `hard' resource limit
          -a	all current limits are reported
          -b	the socket buffer size
          -c	the maximum size of core files created
          -d	the maximum size of a process's data segment
          -e	the maximum scheduling priority (`nice')
          -f	the maximum size of files written by the shell and its children
          -i	the maximum number of pending signals
          -l	the maximum size a process may lock into memory
          -m	the maximum resident set size
          -n	the maximum number of open file descriptors
          -p	the pipe buffer size
          -q	the maximum number of bytes in POSIX message queues
          -r	the maximum real-time scheduling priority
          -s	the maximum stack size
          -t	the maximum amount of cpu time in seconds
          -u	the maximum number of user processes
          -v	the size of virtual memory
          -x	the maximum number of file locks
    ...
    

    For example, to set the soft and hard nofile (open file descriptor) limit to 8192:

    ulimit -SHn 8192
    
  2. Add the desired ulimit command(s) to /etc/sysconfig/<SERVICENAME>, for example:

    echo "ulimit -SHn 8192   # nofile" >>/etc/sysconfig/httpd
    echo "ulimit -SHu 10240  # nproc" >>/etc/sysconfig/httpd
    
  3. Restart the service and check /proc/<PID>/limits output
    For example:

    ~]# service httpd restart
    Stopping httpd:                                            [  OK  ]
    Starting httpd:                                            [  OK  ]
    ~]# cat /proc/$(</var/run/httpd/httpd.pid)/limits
    Limit                     Soft Limit           Hard Limit           Units     
    Max cpu time              unlimited            unlimited            seconds   
    Max file size             unlimited            unlimited            bytes     
    Max data size             unlimited            unlimited            bytes     
    Max stack size            10485760             unlimited            bytes     
    Max core file size        0                    unlimited            bytes     
    Max resident set          unlimited            unlimited            bytes     
    Max processes             10240                10240                processes 
    Max open files            8192                 8192                 files     
    Max locked memory         65536                65536                bytes     
    Max address space         unlimited            unlimited            bytes     
    Max file locks            unlimited            unlimited            locks     
    Max pending signals       7388                 7388                 signals   
    Max msgqueue size         819200               819200               bytes     
    Max nice priority         0                    0                    
    Max realtime priority     0                    0                    
    Max realtime timeout      unlimited            unlimited            us        
    

The vast majority of daemon-spawning service-scripts in RHEL source config files from /etc/sysconfig/<SERVICENAME>; however, there are some (rare) exceptions

  • If /proc/<PID>/limits does not reflect the changes added to /etc/sysconfig/<SERVICENAME>, check for the appropriate config file name1 or insert the ulimit command(s) into the service script itself, for example:

    ~]# sed -i.bak '2iulimit -SHn 8192; ulimit -SHu 10240' /etc/rc.d/init.d/httpd
    ~]# head -4 /etc/rc.d/init.d/httpd
    #!/bin/bash
    ulimit -SHn 8192; ulimit -SHu 10240
    #
    # httpd        Startup script for the Apache HTTP Server
    
1

You can check what files are sourced by a service script with: egrep -w '\.|source' /etc/rc.d/init.d/<SERVICENAME> | grep -vF init.d/functions.

Root Cause

  • Limits configured in /etc/security/limits.conf or in files under /etc/security/limits.d are applied to user-sessions only by PAM (via the pam_limits module)

  • When a daemon is started by a service script at boot, it is normally not done via a user-session, so the system defaults apply; PAM plays no role

  • Resource limits are inherited by child processes (or set by setrlimit()), so when a service is started by a user (via a service command or a direct execution of the init.d script), the service process(es) inherit the limits of the user's session -- this most often means inheriting limits from the root user

Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.