Cgroup學習筆記


1.什么是Cgroup

Cgroups 是 control groups 的縮寫,是 Linux 內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO 等等)的機制。最初由 google 的工程師提出,后來被整合進 Linux 內核。Cgroups 也是 LXC 為實現虛擬化所使用的資源管理手段,可以說沒有 cgroups 就沒有 LXC。

2.Cgroup可以做什么

1.限制進程組可以使用的資源數量,限制進程最大使用的內存等。
2.進程組的優先級控制,比如為某個進程組分配特定的cpu share。
3.記錄進程組使用的資源數量,比如記錄某個進程CPU的使用時間。
4.進程組隔離,比如通過namespace以達到隔離的目的。
5.進程組控制,比如可以將進程組掛起或恢復。

3.Cgroup的模型

(1) 進程模型
在說Cgroup的模型之前,先回顧下進程模型,在linux系統上,所有的進程都有一個共同的父進程,叫做init進程,這個進程在內核啟動的時候開始執行,然后通過init進程啟動其他的進程,這些進程都是init的子進程。因為所有的進程都有一個共同的父進程。那么linux的進程模型就是一個單繼承層次的模型,或者稱之為樹狀模型。除此之外每一個linux進程但是除了init進程,都繼承了一些環境變量(例如PATH環境變量)。
(2) Cgroup模型
Cgroup其實和進程類似,Cgroup也是繼承體系,並且子Cgroup繼承其父Cgroup的某些屬性,兩者最基本的差別在於,進程是單繼承體系。而Cgroup可以存在多個不同的繼承體系(就是可以有多個單繼承體系,每個單繼承體系互不影響)。

4.Cgroup的一些概念

在Cgroup中有這樣四個概念,可以說理解了這四個概念,那么對於如何使用Cgroup:

Subsystems: 稱之為子系統,一個子系統就是一個資源控制器,比如cpu子系統就是控制cpu時間分配的一個控制器。
Hierarchies: 可以稱之為層次體系,也可以稱之為繼承體系,指的是Control Groups是按照層次體系的關系進行組織的。
Control Groups: 一組按照某種標准划分的進程。進程可以從一個Control Groups遷移到另外一個Control Groups中,同時Control Groups中的進程也會受到這個組的資源限制。
Tasks: 在Cgroups中,Tasks就是系統的一個進程。

5.Subsystems

在Red_Hat_Enterprise_Linux-6系列的linux中,默認提供了如下子系統,功能如下:

blkio: 這個子系統為塊設備設定輸入/輸出限制,比如物理設備(磁盤,固態硬盤,USB 等等) 。
cpu: 這個子系統使用調度程序提供對 CPU 的 cgroup 任務訪問。
cpuacct: 這個子系統自動生成 cgroup 中任務所使用的 CPU 報告。
cpuset: 這個子系統為 cgroup 中的任務分配獨立 CPU(在多核系統)和內存節點。
devices: 這個子系統可允許或者拒絕 cgroup 中的任務訪問設備。
freezer: 這個子系統掛起或者恢復 cgroup 中的任務。
memory: 這個子系統設定 cgroup 中任務使用的內存限制,並自動生成由那些任務使用的內存資源報告。
net_cls:這個子系統使用等級識別符(classid)標記網絡數據包,可允許 Linux 流量控制程序(tc)識別從具體 cgroup 中生成的數據包。
ns: 名稱空間子系統。

Ubuntu中的目錄是/sys/fs/cgroup, 但是高通的Android手機中這個目錄下是空的,存在於/dev目錄下,cgroup.rc指定了各個子系統的文件的路徑

/dev/cgroup_info # strings cgroup.rc
blkio:/dev/blkio
cgroup2:/dev/cg2_bpf /dev/cpuctl
cpuacct:/acct
cpuset:/dev/cpuset //system-background、top-app也在這里面。
freezer:/dev/freezer
memory:/dev/memcg
schedtune:/dev/stune

也可以# mount | grep cgroup 來查看都掛載在哪里了。

6.Tasks文件不僅可以讀,還可以寫,你將一個進程的進程號寫入到某個cgroup目錄下的tasks里面,你就將這個進程加入了相應的cgroup。

7.cgroup文件系統和VFS文件系統類似,cgroups的定義如下

struct file_system_type cgroup_fs_type = {
    .name = "cgroup",
    .mount = cgroup_mount,
    .kill_sb = cgroup_kill_sb, //kill_sb釋放超級塊。
    .fs_flags = FS_USERNS_MOUNT,
};

8.Cgroup在kernel中的入口是:subsys_initcall(cgroup_sysfs_init); //msm-4.19\kernel\cgroup\cgroup.c

9.在cgroup文件系統中,對目錄下的文件進行操作時,會調用struct kernfs_ops cgroup_kf_ops 結構體中指向的函數。比如:對文件進行讀操作時,會調用 cgroup_file_read,在 cgroup_file_read 中,會根據需要調用該文件對應的 cftype 結構體定義的對應讀函數。

cgroups通過實現cgroup文件系統來為用戶提供管理cgroup的工具,而cgroup文件系統是基於Linux VFS實現的。相應地,cgroups為控制文件定義了相應的數據結構cftype,對其操作由cgroup文件系統定義的通過操作捕獲,再調用cftype定義的具體實現。

cgroup中的每一個文件的后台動作都是 使用以空結尾的struct cftype數組來定義對cgroup文件進行操作時的后台動作,如 static struct cftype swap_files[] 通過模塊初始化時執行cgroup_add_legacy_cftypes()添加到cgroup系統中,如 cgroup_add_legacy_cftypes(&memory_cgrp_subsys, memsw_cgroup_files)

10.Cgroup是將任意進程進行分組化管理的Linux內核功能。cgroup本身提供將進程進行分組化管理的功能和接口的基礎結構。而后的Android操作系統也就憑借着這個技術,為每個應用程序分配不同的cgroup,將每個程序進行隔離,達到了一個應用程序不會影響其他應用程序環境的目的。

11.概念

task:一個進程。
control group:控制族群,按照某種標准划分的進程組。
hierarchy:層級,control group可以形成樹形的結構,有父節點,子節點,每個節點都是一個control group,子節點繼承父節點的特定屬性。
subsystem:子系統。子系統就是資源控制器,每種子系統就是一個資源的分配器,比如cpu子系統是控制cpu時間分配的。

可以使用lssubsys -al來列出系統支持多少種子系統,和使用ls /sys/fs/cgroup/(ubuntu)來顯示已經掛載的子系統.

12.# mount | grep cgroup可以看掛載目錄,到對應的掛載目錄下,創建一個文件夾,就創建了一個control group了。
實驗1:

/dev/freezer # mkdir mytest
/dev/freezer # ls mytest/
cgroup.clone_children  cgroup.procs  freezer.parent_freezing  freezer.self_freezing  freezer.state  notify_on_release  tasks  yourtest
/dev/freezer/mytest/ # echo $$ > tasks //當前shell進程就被設置進去了,之后更改屬性文件的值可以對其進行設置。

實驗2:

/dev/cpuset # mkdir mytest
/dev/cpuset/mytest # echo "3" > cpus //使用CPU3
/dev/cpuset/mytest # ps -A | grep system_server
1772
/dev/cpuset/mytest # echo 1772 > tasks

上面操作就將system_server線程綁定到CPU3上了。

實驗3:

/dev/memcg # mkdir my_mem_ctl
/dev/memcg/my_mem_ctl # ls
cgroup.clone_children  memory.kmem.failcnt             memory.kmem.tcp.limit_in_bytes      memory.max_usage_in_bytes        memory.move_charge_at_immigrate  memory.swappiness
cgroup.event_control   memory.kmem.limit_in_bytes      memory.kmem.tcp.max_usage_in_bytes  memory.memsw.failcnt             memory.oom_control               memory.usage_in_bytes
cgroup.procs           memory.kmem.max_usage_in_bytes  memory.kmem.tcp.usage_in_bytes      memory.memsw.limit_in_bytes      memory.pressure_level            memory.use_hierarchy
memory.failcnt         memory.kmem.slabinfo            memory.kmem.usage_in_bytes          memory.memsw.max_usage_in_bytes  memory.soft_limit_in_bytes       notify_on_release
memory.force_empty     memory.kmem.tcp.failcnt         memory.limit_in_bytes               memory.memsw.usage_in_bytes      memory.stat                      tasks
/dev/memcg/my_mem_ctl # echo $$ > tasks
/dev/memcg/my_mem_ctl # echo 10M > memory.limit_in_bytes
/dev/memcg/my_mem_ctl # cat memory.limit_in_bytes
10485760

上面是限制當前shell進程最大使用10M內存。

相關文件解釋:

memory.limit_in_bytes  顯示當前內存(進程內存+頁面內存)的使用量
memory.memsw.usage_in_bytes  顯示當前內存(進程內存+頁面內存)+交換區的使用量
memory.limit_in_bytes  設置、顯示內存(進程內存+頁面內存)使用量的限制值
memory.memsw.limit_in_bytes  設置、顯示內存(進程內存+頁面內存)+交換區使用量的限制值
memory.failcnt  顯示當前內存(進程內存+頁面內存)達到限制值的次數
memory.memsw.failcnt 顯示當前內存(進程內存+頁面內存)+交換區達到限制值的次數
memory.max_usage_in_bytes 顯示記錄的內存(進程內存+頁面內存)使用量的最大值
memory.memsw.max_usage_in_bytes 顯示記錄的內存(進程內存+頁面內存)+交換區使用量的最大值
memory.stat 輸出統計信息
memory.force_empty 強制釋放分配給分組的內存
memory.use_hierarchy  設置、顯示層次結構的使用
memory.swappiness  設置、顯示針對分組的swappiness(相當於sysctl的vm.swappiness)

 

 

參考:
Linux Cgroups詳解(三): https://www.cnblogs.com/lisperl/archive/2012/04/23/2466151.html?utm_medium=referral
003_Linux的Cgroup<實例詳解>: https://www.cnblogs.com/itcomputer/p/4634942.html

TODO:
Linux Cgroups詳解(一):https://www.cnblogs.com/lisperl/archive/2012/04/17/2453838.html
Linux Cgroups詳解(二):https://www.cnblogs.com/lisperl/archive/2012/04/18/2455027.html
LXC(Linux containers)快速入門:https://www.cnblogs.com/lisperl/archive/2012/04/15/2450183.html
Linux Cgroup 入門教程:cpuset:https://zhuanlan.zhihu.com/p/121588317

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM