Cgroup 凍結器¶
Cgroup 凍結器對於批處理作業管理系統非常有用,該系統根據系統管理員的需求啟動和停止一組任務以排程機器資源。這種程式常用於 HPC 叢集,以排程對整個叢集的訪問。Cgroup 凍結器使用 cgroup 來描述批處理作業管理系統將啟動/停止的任務集。它還提供了一種啟動和停止構成作業的任務的方法。
Cgroup 凍結器也將有助於檢查點(checkpointing)執行中的任務組。凍結器允許檢查點程式碼透過嘗試將 cgroup 中的任務強制進入靜止狀態來獲取任務的一致映象。一旦任務靜止,另一個任務就可以遍歷 /proc 或呼叫核心介面來收集有關靜止任務的資訊。檢查點任務可以在發生可恢復錯誤時稍後重新啟動。這也允許透過將收集到的資訊複製到另一個節點並在該節點上重新啟動任務,從而在叢集節點之間遷移檢查點任務。
在使用者空間中,SIGSTOP 和 SIGCONT 序列並不總是足以停止和恢復任務。我們希望凍結的任務內部可以觀察到這兩個訊號。雖然 SIGSTOP 無法被捕獲、阻塞或忽略,但父任務可以透過等待或 ptracing 看到它。SIGCONT 尤其不適用,因為它可以被任務捕獲。任何旨在監視 SIGSTOP 和 SIGCONT 的程式都可能因嘗試使用 SIGSTOP 和 SIGCONT 停止和恢復任務而出現問題。我們可以使用巢狀的 bash shell 來演示這個問題
$ echo $$
16644
$ bash
$ echo $$
16690
From a second, unrelated bash shell:
$ kill -SIGSTOP 16690
$ kill -SIGCONT 16690
<at this point 16690 exits and causes 16644 to exit too>
發生這種情況是因為 bash 可以觀察到這兩個訊號並選擇如何響應它們。
另一個捕獲並響應這些訊號的程式示例是 gdb。事實上,任何設計用於使用 ptrace 的程式都可能遇到這種停止和恢復任務方法的困擾。
相比之下,cgroup 凍結器使用核心凍結器程式碼來防止凍結/解凍週期對被凍結的任務可見。這使得上述 bash 示例和 gdb 能夠按預期執行。
Cgroup 凍結器是分層的。凍結一個 cgroup 會凍結屬於該 cgroup 及其所有子 cgroup 的所有任務。每個 cgroup 都有自己的狀態(自狀態)和從父級繼承的狀態(父狀態)。當且僅當(iff)兩個狀態都為 THAWED 時,cgroup 才為 THAWED。
以下 cgroupfs 檔案由 cgroup 凍結器建立。
freezer.state: 可讀寫。
讀取時,返回 cgroup 的有效狀態——“THAWED”、“FREEZING” 或 “FROZEN”。這是自狀態和父狀態的組合。如果任何一個處於凍結中,則 cgroup 處於凍結中(FREEZING 或 FROZEN)。
當屬於 cgroup 及其子代的所有任務都變為凍結狀態時,處於 FREEZING 狀態的 cgroup 會轉換為 FROZEN 狀態。請注意,當有新任務新增到 cgroup 或其子 cgroup 中時,cgroup 會從 FROZEN 狀態恢復到 FREEZING 狀態,直到新任務被凍結。
寫入時,設定 cgroup 的自狀態。允許兩個值——“FROZEN” 和 “THAWED”。如果寫入 FROZEN,則 cgroup(如果尚未凍結)將與其所有子 cgroup 一起進入 FREEZING 狀態。
如果寫入 THAWED,則 cgroup 的自狀態將變為 THAWED。請注意,如果父狀態仍在凍結中,則有效狀態可能不會變為 THAWED。如果 cgroup 的有效狀態變為 THAWED,則所有因該 cgroup 而處於凍結狀態的子代也將離開凍結狀態。
freezer.self_freezing: 只讀。
顯示自狀態。如果自狀態為 THAWED,則為 0;否則為 1。當且僅當(iff)上次寫入 freezer.state 的值為“FROZEN”時,此值為 1。
freezer.parent_freezing: 只讀。
顯示父狀態。如果 cgroup 的任何祖先都未凍結,則為 0;否則為 1。
根 cgroup 不可凍結,且上述介面檔案不存在。
用法示例
# mkdir /sys/fs/cgroup/freezer # mount -t cgroup -ofreezer freezer /sys/fs/cgroup/freezer # mkdir /sys/fs/cgroup/freezer/0 # echo $some_pid > /sys/fs/cgroup/freezer/0/tasks
獲取凍結器子系統的狀態
# cat /sys/fs/cgroup/freezer/0/freezer.state
THAWED
凍結容器中的所有任務
# echo FROZEN > /sys/fs/cgroup/freezer/0/freezer.state
# cat /sys/fs/cgroup/freezer/0/freezer.state
FREEZING
# cat /sys/fs/cgroup/freezer/0/freezer.state
FROZEN
解凍容器中的所有任務
# echo THAWED > /sys/fs/cgroup/freezer/0/freezer.state
# cat /sys/fs/cgroup/freezer/0/freezer.state
THAWED
這是基本機制,在簡單場景下,它應該能正確地處理使用者空間任務。
此凍結器實現存在缺陷(參見 提交 76f969e8948d8(“cgroup: cgroup v2 凍結器”))並且推薦使用 cgroup v2 凍結器。