程序號控制器

摘要

程序號控制器用於允許 cgroup 層級結構在達到特定限制後,阻止任何新的任務透過 fork() 或 clone() 建立。

由於在不觸及任何現有 kmemcg 限制的情況下達到任務限制是很容易的,因此 PID 是一種基本資源。因此,必須透過允許對 cgroup 中任務數量進行資源限制來防止在 cgroup 層級結構範圍內出現 PID 耗盡。

用法

為了使用 pids 控制器,請在 pids.max 中設定最大任務數量(出於明顯原因,根 cgroup 中不提供此功能)。當前 cgroup 中的程序數量由 pids.current 提供。

組織操作不受 cgroup 策略的阻止,因此 pids.current > pids.max 是可能的。這可以透過將限制設定為小於 pids.current,或將足夠的程序附加到 cgroup 以使 pids.current > pids.max 來實現。但是,透過 fork() 或 clone() 違反 cgroup 策略是不可能的。如果建立新程序將導致違反 cgroup 策略,則 fork() 和 clone() 將返回 -EAGAIN。

要將 cgroup 設定為無限制,請將 pids.max 設定為 “max”。這是所有新 cgroup 的預設設定(請注意,PID 限制是分層的,因此遵循層級結構中最嚴格的限制)。

pids.current 跟蹤所有子 cgroup 層級結構,因此 parent/pids.current 是 parent/child/pids.current 的超集。

pids.events 檔案包含事件計數器

  • max:由於自身或祖先中達到限制,cgroup 中 fork 失敗的次數。

示例

首先,我們掛載 pids 控制器

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

然後我們建立一個層級結構,設定限制並將程序附加到其中

# 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
#

應該注意的是,嘗試突破設定的限制(本例中為 2)將會失敗

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

即使我們遷移到沒有設定限制的子 cgroup,我們也無法突破層級結構中最嚴格的限制(本例中是父級的限制)

# 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
#

我們可以設定一個小於 pids.current 的限制,這將完全阻止任何新程序的 fork(請注意,shell 本身也會計入 pids.current)

# 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
#