1*99c8b231SMauro Carvalho Chehab========================= 2917d8e2dSAleksa SaraiProcess Number Controller 3917d8e2dSAleksa Sarai========================= 4917d8e2dSAleksa Sarai 5917d8e2dSAleksa SaraiAbstract 6917d8e2dSAleksa Sarai-------- 7917d8e2dSAleksa Sarai 8917d8e2dSAleksa SaraiThe process number controller is used to allow a cgroup hierarchy to stop any 9917d8e2dSAleksa Sarainew tasks from being fork()'d or clone()'d after a certain limit is reached. 10917d8e2dSAleksa Sarai 11917d8e2dSAleksa SaraiSince it is trivial to hit the task limit without hitting any kmemcg limits in 12917d8e2dSAleksa Saraiplace, PIDs are a fundamental resource. As such, PID exhaustion must be 13917d8e2dSAleksa Saraipreventable in the scope of a cgroup hierarchy by allowing resource limiting of 14917d8e2dSAleksa Saraithe number of tasks in a cgroup. 15917d8e2dSAleksa Sarai 16917d8e2dSAleksa SaraiUsage 17917d8e2dSAleksa Sarai----- 18917d8e2dSAleksa Sarai 19917d8e2dSAleksa SaraiIn order to use the `pids` controller, set the maximum number of tasks in 20917d8e2dSAleksa Saraipids.max (this is not available in the root cgroup for obvious reasons). The 21917d8e2dSAleksa Sarainumber of processes currently in the cgroup is given by pids.current. 22917d8e2dSAleksa Sarai 23917d8e2dSAleksa SaraiOrganisational operations are not blocked by cgroup policies, so it is possible 24917d8e2dSAleksa Saraito have pids.current > pids.max. This can be done by either setting the limit to 25917d8e2dSAleksa Saraibe smaller than pids.current, or attaching enough processes to the cgroup such 26917d8e2dSAleksa Saraithat pids.current > pids.max. However, it is not possible to violate a cgroup 27917d8e2dSAleksa Saraipolicy through fork() or clone(). fork() and clone() will return -EAGAIN if the 28917d8e2dSAleksa Saraicreation of a new process would cause a cgroup policy to be violated. 29917d8e2dSAleksa Sarai 30917d8e2dSAleksa SaraiTo set a cgroup to have no limit, set pids.max to "max". This is the default for 31917d8e2dSAleksa Saraiall new cgroups (N.B. that PID limits are hierarchical, so the most stringent 32917d8e2dSAleksa Sarailimit in the hierarchy is followed). 33917d8e2dSAleksa Sarai 34917d8e2dSAleksa Saraipids.current tracks all child cgroup hierarchies, so parent/pids.current is a 35917d8e2dSAleksa Saraisuperset of parent/child/pids.current. 36917d8e2dSAleksa Sarai 3705b71f6fSTibor BillesThe pids.events file contains event counters: 38*99c8b231SMauro Carvalho Chehab 3905b71f6fSTibor Billes - max: Number of times fork failed in the cgroup because limit was hit in 4005b71f6fSTibor Billes self or ancestors. 41917d8e2dSAleksa Sarai 42917d8e2dSAleksa SaraiExample 43917d8e2dSAleksa Sarai------- 44*99c8b231SMauro Carvalho Chehab 45*99c8b231SMauro Carvalho ChehabFirst, we mount the pids controller:: 46917d8e2dSAleksa Sarai 47917d8e2dSAleksa Sarai # mkdir -p /sys/fs/cgroup/pids 48917d8e2dSAleksa Sarai # mount -t cgroup -o pids none /sys/fs/cgroup/pids 49*99c8b231SMauro Carvalho Chehab 50*99c8b231SMauro Carvalho ChehabThen we create a hierarchy, set limits and attach processes to it:: 51917d8e2dSAleksa Sarai 52917d8e2dSAleksa Sarai # mkdir -p /sys/fs/cgroup/pids/parent/child 53917d8e2dSAleksa Sarai # echo 2 > /sys/fs/cgroup/pids/parent/pids.max 54917d8e2dSAleksa Sarai # echo $$ > /sys/fs/cgroup/pids/parent/cgroup.procs 55917d8e2dSAleksa Sarai # cat /sys/fs/cgroup/pids/parent/pids.current 56917d8e2dSAleksa Sarai 2 57917d8e2dSAleksa Sarai # 58917d8e2dSAleksa Sarai 59*99c8b231SMauro Carvalho ChehabIt should be noted that attempts to overcome the set limit (2 in this case) will 60917d8e2dSAleksa Saraifail:: 61917d8e2dSAleksa Sarai 62917d8e2dSAleksa Sarai # cat /sys/fs/cgroup/pids/parent/pids.current 63917d8e2dSAleksa Sarai 2 64917d8e2dSAleksa Sarai # ( /bin/echo "Here's some processes for you." | cat ) 65917d8e2dSAleksa Sarai sh: fork: Resource temporary unavailable 66917d8e2dSAleksa Sarai # 67917d8e2dSAleksa Sarai 68917d8e2dSAleksa SaraiEven if we migrate to a child cgroup (which doesn't have a set limit), we will 69*99c8b231SMauro Carvalho Chehabnot be able to overcome the most stringent limit in the hierarchy (in this case, 70917d8e2dSAleksa Saraiparent's):: 71917d8e2dSAleksa Sarai 72917d8e2dSAleksa Sarai # echo $$ > /sys/fs/cgroup/pids/parent/child/cgroup.procs 73917d8e2dSAleksa Sarai # cat /sys/fs/cgroup/pids/parent/pids.current 74917d8e2dSAleksa Sarai 2 75917d8e2dSAleksa Sarai # cat /sys/fs/cgroup/pids/parent/child/pids.current 76917d8e2dSAleksa Sarai 2 77917d8e2dSAleksa Sarai # cat /sys/fs/cgroup/pids/parent/child/pids.max 78917d8e2dSAleksa Sarai max 79917d8e2dSAleksa Sarai # ( /bin/echo "Here's some processes for you." | cat ) 80917d8e2dSAleksa Sarai sh: fork: Resource temporary unavailable 81917d8e2dSAleksa Sarai # 82917d8e2dSAleksa Sarai 83917d8e2dSAleksa SaraiWe can set a limit that is smaller than pids.current, which will stop any new 84*99c8b231SMauro Carvalho Chehabprocesses from being forked at all (note that the shell itself counts towards 85917d8e2dSAleksa Saraipids.current):: 86917d8e2dSAleksa Sarai 87917d8e2dSAleksa Sarai # echo 1 > /sys/fs/cgroup/pids/parent/pids.max 88917d8e2dSAleksa Sarai # /bin/echo "We can't even spawn a single process now." 89917d8e2dSAleksa Sarai sh: fork: Resource temporary unavailable 90917d8e2dSAleksa Sarai # echo 0 > /sys/fs/cgroup/pids/parent/pids.max 91917d8e2dSAleksa Sarai # /bin/echo "We can't even spawn a single process now." 92917d8e2dSAleksa Sarai sh: fork: Resource temporary unavailable 93 # 94