← Documents Documentation/admin-guide/cgroup-v1/pids.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Cgroup v1

Process Number Controller

PIDs controller의 계층적 task limit, event counter와 실패 예제를 설명합니다.

Source pathDocumentation/admin-guide/cgroup-v1/pids.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

Purpose

pids.rst:1-15

Cgroup hierarchy에서 PID exhaustion을 방지하는 controller의 목적입니다.

Interface and example

pids.rst:16-93

`pids.max`, `pids.current`, `pids.events`와 ancestor limit 적용을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =========================
2 Process Number Controller
3 =========================
4
5 Abstract
6 --------
7
8 The process number controller is used to allow a cgroup hierarchy to stop any
9 new tasks from being fork()'d or clone()'d after a certain limit is reached.
10
11 Since it is trivial to hit the task limit without hitting any kmemcg limits in
12 place, PIDs are a fundamental resource. As such, PID exhaustion must be
13 preventable in the scope of a cgroup hierarchy by allowing resource limiting of
14 the number of tasks in a cgroup.
15
16 Usage
17 -----
18
19 In order to use the `pids` controller, set the maximum number of tasks in
20 pids.max (this is not available in the root cgroup for obvious reasons). The
21 number of processes currently in the cgroup is given by pids.current.
22
23 Organisational operations are not blocked by cgroup policies, so it is possible
24 to have pids.current > pids.max. This can be done by either setting the limit to
25 be smaller than pids.current, or attaching enough processes to the cgroup such
26 that pids.current > pids.max. However, it is not possible to violate a cgroup
27 policy through fork() or clone(). fork() and clone() will return -EAGAIN if the
28 creation of a new process would cause a cgroup policy to be violated.
29
30 To set a cgroup to have no limit, set pids.max to "max". This is the default for
31 all new cgroups (N.B. that PID limits are hierarchical, so the most stringent
32 limit in the hierarchy is followed).
33
34 pids.current tracks all child cgroup hierarchies, so parent/pids.current is a
35 superset of parent/child/pids.current.
36
37 The pids.events file contains event counters:
38
39 - max: Number of times fork failed in the cgroup because limit was hit in
40 self or ancestors.
41
42 Example
43 -------
44
45 First, we mount the pids controller::
46
47 # mkdir -p /sys/fs/cgroup/pids
48 # mount -t cgroup -o pids none /sys/fs/cgroup/pids
49
50 Then we create a hierarchy, set limits and attach processes to it::
51
52 # mkdir -p /sys/fs/cgroup/pids/parent/child
53 # echo 2 > /sys/fs/cgroup/pids/parent/pids.max
54 # echo $$ > /sys/fs/cgroup/pids/parent/cgroup.procs
55 # cat /sys/fs/cgroup/pids/parent/pids.current
56 2
57 #
58
59 It should be noted that attempts to overcome the set limit (2 in this case) will
60 fail::
61
62 # cat /sys/fs/cgroup/pids/parent/pids.current
63 2
64 # ( /bin/echo "Here's some processes for you." | cat )
65 sh: fork: Resource temporary unavailable
66 #
67
68 Even if we migrate to a child cgroup (which doesn't have a set limit), we will
69 not be able to overcome the most stringent limit in the hierarchy (in this case,
70 parent's)::
71
72 # echo $$ > /sys/fs/cgroup/pids/parent/child/cgroup.procs
73 # cat /sys/fs/cgroup/pids/parent/pids.current
74 2
75 # cat /sys/fs/cgroup/pids/parent/child/pids.current
76 2
77 # cat /sys/fs/cgroup/pids/parent/child/pids.max
78 max
79 # ( /bin/echo "Here's some processes for you." | cat )
80 sh: fork: Resource temporary unavailable
81 #
82
83 We can set a limit that is smaller than pids.current, which will stop any new
84 processes from being forked at all (note that the shell itself counts towards
85 pids.current)::
86
87 # echo 1 > /sys/fs/cgroup/pids/parent/pids.max
88 # /bin/echo "We can't even spawn a single process now."
89 sh: fork: Resource temporary unavailable
90 # echo 0 > /sys/fs/cgroup/pids/parent/pids.max
91 # /bin/echo "We can't even spawn a single process now."
92 sh: fork: Resource temporary unavailable
93 #
94

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Process Number Controller의 목적

1-15

Process number controller는 일정한 limit에 도달한 뒤 cgroup hierarchy가 `fork()` 또는 `clone()`으로 새 task를 만드는 일을 막을 수 있게 합니다.

현재 설정된 `kmemcg` limit에 닿지 않고도 task limit에는 쉽게 도달할 수 있으므로 PID는 기본 resource입니다. 따라서 cgroup 안의 task 수를 제한해 cgroup hierarchy 범위에서 PID exhaustion을 방지할 수 있어야 합니다.

pids.max, 계층 규칙과 event

16-40

`pids` controller를 사용하려면 `pids.max`에 최대 task 수를 설정합니다. 명백한 이유로 root cgroup에는 이 file이 없습니다. 현재 cgroup에 있는 process 수는 `pids.current`로 확인합니다.

Cgroup policy는 조직 변경 operation을 막지 않으므로 `pids.current > pids.max`가 될 수 있습니다. 현재값보다 작은 limit을 설정하거나 충분히 많은 process를 cgroup에 attach하면 이런 상태가 됩니다. 그러나 `fork()`나 `clone()`으로 policy를 위반할 수는 없습니다. 새 process 생성이 policy를 위반한다면 두 call은 `-EAGAIN`을 반환합니다.

제한이 없는 cgroup은 `pids.max`를 `max`로 설정합니다. 모든 새 cgroup의 default가 이 값입니다. PID limit은 hierarchical하므로 hierarchy에서 가장 엄격한 limit을 따릅니다.

`pids.current`는 모든 child cgroup hierarchy를 추적합니다. 따라서 `parent/pids.current`는 `parent/child/pids.current`의 superset입니다.

`pids.events`의 `max` counter는 해당 cgroup 자신 또는 ancestor의 limit에 걸려 `fork`가 실패한 횟수를 기록합니다.

PIDs controller interface
InterfaceMeaning
pids.maxMaximum tasks or `max`; unavailable in root
pids.currentCurrent tasks including descendants
pids.events: maxFork failures caused by self or ancestor limit
fork()/clone()Return `-EAGAIN` when creation violates policy

Limit, current usage와 failure event의 관계입니다.

Hierarchical PID limit 예제

41-93

먼저 `pids` controller를 mount합니다.

	# mkdir -p /sys/fs/cgroup/pids
	# mount -t cgroup -o pids none /sys/fs/cgroup/pids

그다음 parent와 child hierarchy를 만들고 parent limit을 `2`로 설정한 뒤 현재 shell을 parent에 attach합니다. Parent의 current count는 `2`입니다.

	# mkdir -p /sys/fs/cgroup/pids/parent/child
	# echo 2 > /sys/fs/cgroup/pids/parent/pids.max
	# echo $$ > /sys/fs/cgroup/pids/parent/cgroup.procs
	# cat /sys/fs/cgroup/pids/parent/pids.current
	2
	#

설정한 limit `2`를 넘으려는 시도는 실패하고 shell은 `sh: fork: Resource temporary unavailable`을 출력합니다.

	# cat /sys/fs/cgroup/pids/parent/pids.current
	2
	# ( /bin/echo "Here's some processes for you." | cat )
	sh: fork: Resource temporary unavailable
	#

별도 limit이 없는 child cgroup으로 이동해도 hierarchy에서 가장 엄격한 parent limit을 넘을 수 없습니다. Child의 `pids.max`는 `max`지만 parent와 child의 current count는 모두 `2`이고 새 process 생성은 실패합니다.

	# echo $$ > /sys/fs/cgroup/pids/parent/child/cgroup.procs
	# cat /sys/fs/cgroup/pids/parent/pids.current
	2
	# cat /sys/fs/cgroup/pids/parent/child/pids.current
	2
	# cat /sys/fs/cgroup/pids/parent/child/pids.max
	max
	# ( /bin/echo "Here's some processes for you." | cat )
	sh: fork: Resource temporary unavailable
	#

Limit을 `pids.current`보다 작게 설정하는 것도 허용되며, 그러면 새 process를 전혀 fork할 수 없습니다. Shell 자체도 `pids.current`에 포함됩니다. 예제에서 limit `1`과 `0`은 모두 단일 process조차 새로 실행하지 못하게 합니다.

	# echo 1 > /sys/fs/cgroup/pids/parent/pids.max
	# /bin/echo "We can't even spawn a single process now."
	sh: fork: Resource temporary unavailable
	# echo 0 > /sys/fs/cgroup/pids/parent/pids.max
	# /bin/echo "We can't even spawn a single process now."
	sh: fork: Resource temporary unavailable
	#
Hierarchical enforcement
parent pids.max = 2child pids.max = maxEffective limit = 2fork would create task 3Return -EAGAIN

Child가 unlimited여도 ancestor의 더 엄격한 limit이 process 생성을 막습니다.