1 Key concepts
- process resource limits are implemented and enforced in the kernel.
- limits are part of a process' kernel structure.
- we can check their values in /proc/PID/limits.
- "ulimit" is a built-in in bash, it works by calling system call "getrlimit()" and "setrlimit()".
- different shell may have different commands for set/get resources limits.
- A process's resources limits inherit from its parent process.
- a shell's child processes all have the same limits as the shell by default.
- soft limits and hard limits
- hard limits are the max value soft limits can be set to.
- soft limits are what the kernel checks and enforces.
- Most limits are per-process attributes, while two are per-user. For per-user limits, they affect only the calling process. Other processes belonging to this user are not affected unless they also set or inherit these limits.
- RLIMT_SIGPENDING
- RLIMIT_NPROC, this limit takes into account both process and threads.
2 Where are limits values from?
2.1 The Linux kernel sets limits for PID 1
The Linux kernel is responsible to create the first userspace process and set the limits of its resource.
Some limits values may be hardcoded, while others may be calculated based on the hardware like memory size.
The PID 1 process can run any program, but usually, it executes /sbin/init which in most Linux distributions is a link to /lib/systemd/systemd.
$ cat /proc/1/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 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 62571 62571 processes
Max open files 1048576 1048576 files
Max locked memory 16777216 16777216 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 62571 62571 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
As all other userspace processes are created by PID 1 directly or indirectly, they inherit all those values as their default.
2.2 PAM sets the login process's limits
For ordinary Linux users, they login the system before do anyting else. During the login process, PAM would set the process's limits by pam_limits.so.$ cat /etc/pam.d/system-auth | grep limits
session required pam_limits.so
pam_limits.so reads its configration from
- /etc/security/limits.conf
- /etc/security/limits.d/*.conf
PAM may hardcod some limits which are not in the configration files.
After successful login, the login process executes the users' defualt shell, so the shell process inherits all these limits.
To see a shell's limits, use its built-in command. For bash, it's 'ulimit'.
# print all hard limits
$ ulimit -Ha
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62571
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 62571
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
# print all soft limits
$ ulimit -Sa
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 62571
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 62571
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
We can see limits in /proc/$$/limits too.
$ cat /proc/$$/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 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 62571 62571 processes
Max open files 1024 4096 files
Max locked memory 16777216 16777216 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 62571 62571 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
2.3 The process sets its own limits
A process can set its own limits by call 'setrlimits()' system call at any time. But here are some restrictions.
- Only privileged users can set Hard limits to a higher value.
- Any user can lower the hard limits.
- Any user can change soft limits from 0 to the value of their hard one.
- Hard limits cannot be lower than soft limits. (or, soft limits cannot be higher than hard limits)
- Some hard limits may have a ceiling posed by the kernel. e.g. Hard limit of nofiles can not be higher than /proc/sys/fs/nr_open.
3 Examples
$ ulimit -Hn
4096
$ ulimit -Sn
1024
# Hard limit can be set higher only by root
$ ulimit -Hn 4097
-bash: ulimit: open files: cannot modify limit: Operation not permitted
# Hard limit can not be lower than soft limit
$ ulimit -Hn 1023
-bash: ulimit: open files: cannot modify limit: Invalid argument
# Soft limit can not be higher than hard limit
$ ulimit -Sn 4097
-bash: ulimit: open files: cannot modify limit: Invalid argument
# check what limits were set by PAM
$ diff /proc/1/limits /proc/$$/limits
9c9
< Max open files 1048576 1048576 files
---
> Max open files 1024 4096 files
No comments:
Post a Comment