Ulimit
ulimit(1) is a shell-builtin, its output and values differ across shells and operating system defaults.
Linux
To enable limits, one can just use the ulimit(1) shell-builtin. To enable limits permanently, PAM can be used:
$ grep -r pam_limit /etc/pam.d/
/etc/pam.d/common-session:session required pam_limits.so
/etc/pam.d/su: session required pam_limits.so
/etc/pam.d/cron: session required pam_limits.so
/etc/pam.d/login: session required pam_limits.so
Programs like cron or sshd are usually compiled agains libpam.so. For ssh, the sshd_config must set UsePAM=yes.
Use limits.conf to configure reasonable limits. A working example, limiting everybody in the group "users":
root - core 1048576 # -c 1024 MB (0, core file size) @staff - core 524288 # -c 512 MB * - core 524288 # -c 512 MB * - data 32768 # -d 32 MB (unlimited, data seg size) @staff - fsize unlimited # -f (unlimited, file size) * - fsize 1048576 # -f 1024 MB * - memlock 64 # -l 64 KB (64 KB, locked memory) root - nofile 512 # -n 512 (1024, open files, max: 2^20) @staff - nofile 256 # -n 256 * - nofile 128 # -n 128 * - rss 131072 # -m 128 MB (unlimited, resident set size) * - stack 8192 # -s 8 MB (8192 KB, stack size) * - cpu unlimited # -t (unlimited, cpu time) root - nproc 512 # -u 512 (1024, number of processes) @staff - nproc 512 # -u 512 * - nproc 64 # -u 64 @staff - as unlimited # -v (unlimited, per process address space) * - as 524288 # -v 512 MB * - maxlogins 10 # (unlimited, max number of logins per user) * - maxsyslogins 20 # (unlimited, max number of logins per system) * - priority 5 # -e 5 (0, priority of user processes) root - locks 1024 # -x 1024 (unlimited, file locks per user) * - locks 32 # -x 32 * - sigpending 1024 # -i 1024 (?, pending signals) * - msgqueue 8192 # -q 8192 (819200, POSIX message queues) * hard nice 0 # (0, nice level allowed [-20, 19]) * soft nice 5 # * - rtprio 0 # -r 0 (0, realtime priority) # @users - pipe 8 # -p 8 (8, pipe size in 512 bytes) # @lusers - chroot /mnt/chroot # change root to directory (Debian-specific)
- Group and wildcard limits are not applied to root. To apply a limit to the root user, <domain> must be the literal username root.
- Notice how we set both soft and hard limits ("-") for most of the settings but a few. For example, we want the "@users" to be reniced to "5" per default but if they need more CPU priority, they can elevate themselves to "0".
- testparm(1) will complain if nofile is set lower than 2^14:
$ testparm Load smb config files from /etc/samba/smb.conf rlimit_max: increasing rlimit_max (512) to minimum Windows limit (16384)
- See also Debian #608624 for details on this matter.
Changing ulimit for running processes
To change ulimits for running processes[1][2], the prlimit()[3] syscall is used, available since Linux 2.6.36-rc1[4]
$ prlimit --core -p $$ RESOURCE DESCRIPTION SOFT HARD UNITS CORE max core file size 0 unlimited blocks $ prlimit --core=`expr 32 \* 1024 \* 1024`: -p $$ # 32 MB corefile size in bytes $ prlimit --core -p $$ RESOURCE DESCRIPTION SOFT HARD UNITS CORE max core file size 33554432 unlimited blocks $ ulimit -c 32768 # 32 MB corefile size in KBytes
If prlimit is not available[5][6][7], we can still modify the ulimit value of a process via /proc:
$ grep core /proc/$$/limits Max core file size 33554432 unlimited bytes $ printf "Max core file size=`expr 64 \* 1024 \* 1024`:unlimited" > /proc/$$/limits # 64 MB corefile size in bytes $ ulimit -c 65536 # 64 MB corefile size in KBytes
Note: For some reason this does not seem to work in more current kernels. Also, only root seems to be allowed to modify these values.
Then there's gdb[2] to change these values, although the interface is a bit cryptic and may not work in all cases:
$ grep RLIMIT_CORE /usr/include/asm-generic/resource.h #define RLIMIT_CORE 4 /* max core file size */ $ gdb -p $$ (gdb) set $rlim = &{0ll, 0ll} (gdb) print getrlimit(4, $rlim) $1 = 0 # corefile size of 0 (gdb) print *$rlim $2 = {0, -1} # print softlimit, hardlimit (gdb) set *$rlim[0] = 64*1024*1024 (gdb) print setrlimit(4, $rlim) $3 = 0
Solaris
TBD...
MacOS
While ulimit(1) can be used to display and modify current session limits, launchctl(1) will be able to set default values:
$ launchctl limit cpu unlimited unlimited filesize unlimited unlimited data unlimited unlimited stack 8388608 67104768 core 0 unlimited rss unlimited unlimited memlock unlimited unlimited maxproc 709 1064 maxfiles 256 unlimited
With launchd.conf(5), these can be set permanently. While /etc/launchd.conf sets the system's default, $HOME/.launchd.conf will set a user's defaults. However, according to the manpage, this is currently unsupported.
$ cat /etc/launchd.conf # resource limit soft hard limit cpu unlimited unlimited limit filesize unlimited unlimited limit data unlimited unlimited limit stack 8388608 67104768 limit core 1048576 unlimited limit rss unlimited unlimited limit memlock unlimited unlimited limit maxproc 709 1064 limit maxfiles 256 unlimited
Links
- ulimit -a for various shells
- Understanding ulimit output
- Linux Shell Limits
- fork bomb