linux内核框架分析,Linux内核中Cgroup框架分析

为什么要有cgroup

Linux系统中经常有个需求就是希望能限制某个或者某些进程的分配资源。也就是能完成一组容器的概念,在这个容器中,有分配好的特定比例的cpu时间,IO时间,可用内存大小等。于是就出现了cgroup的概念,cgroup就是controller group,最初由google的工程师提出,后来被整合进Linux内核中。

Cgroup是将任意进程进行分组化管理的Linux内核功能。cgroup本身提供将进程进行分组化管理的功能和接口的基础结构。

而后的Android操作系统也就凭借着这个技术,为每个应用程序分配不同的cgroup,将每个程序进行隔离,达到了一个应用程序不会影响其他应用程序环境的目的。

cgroups概念扫盲

关于cgroups本文主要分析的是Linux内核中cgroups整体框架,不涉及对各个子系统的介绍和cgroupsfs的介绍,在分析cgroup整体框架的时候,首先我们需要对cgroups中的一些概念有所深刻认识,只有在这个基础上,才能明白为何cgroups的框架是设计成这样的,为了节约篇幅,更好突出cgroup框架这一内容,所以我不打算花时间来描述cgroup的一些概念。关于这方面的内容我推荐阅读附录A中提到的文章,如果你英文不好,你也可以参考下我总结的几篇cgroup文章,从基本概念到用户态的基本使用都所有涉及文章链接参考附录B

cgroups框架分析

cgroups框架中涉及了大量的结构体,并且嵌入了很多list_head以及hlist_node等数据结构,目的是将这些数据结构链接在一起,无论从任何一个结构体出发都可以很好的找到自己想要的目标结构体,因此内核中也出现了大量的短小精悍的inline funtion,这些function基本只有一两句话,核心的语句就是通过list_head或者hlist_node找到目标链接的结构体。内核中更有甚者会给两个概念上是多对多的这样关系的结构体专门抽象出一个单独的结构体嵌入list_head实现两个结构体的多对多关系,cgroup中就有这样的例子。

cgroups中的结构体概述

struct task_struct,这是进程描述符的结构体,和cgroup相关的则是其中struct css_set *cgroup成员,以及struct list_head cg_list成员,struct css_set这是个啥东东呢,css的全称为cgroup subsystem state,也就是cgroup子系统的状态,set很自然就是集合的意思了,所以css_set维护了一组子系统的状态。所以呢css_set中核心的成员就是struct cgroup_subsys_state[CGROUP_SUBSYS_COUNT],一个子系统对应一个这样的结构体,好吧那就继续分析下这个结构体吧,struct cgroup_subsys_state对于这个结构体来说,里面有这个子系统对应的cgroup,这个子系统引用的次数,一个子系统如果使用了,那么肯定是属于一个cgroup的,所以这个结构体中最核心的成员应该是struct cgroup *cgroup,很显然struct cgroup就是一个cgroup组,如果不知道什么是cgroup中组或者是层次的概念,请看附录A或B中提到的文章,好了现在一个子系统对应一个cgroup,那么现在来看看struct cgroup是个啥啥,struct cgroup 首先会指向一组子系统,因为一个cgroup可以对应多个子系统,其次,一个cgroup应该维护层次关系,应该可以找到其兄弟cgroup,父cgroup等信息,所以cgroup中含有struct list_head children,struct list_head sibling还有struct cgroup cgroup,还应该有个啥呢?cgroup的name,所以就有了*struct cgroup_name __rcu *name这个成员,还应该有个指针指向cgroupfs文件系统,因为创建一个cgroup会在对应的cgroupfs文件系统中创建一系列的文件,所以就有了一个struct cgroupfs_root *root 成员,struct cgroup_name 就是一个char数组,加上一个锁,这个部分核心成员应该算是cgroupfs_root吧,好了到此为止吧,再往下分析我怕我收不住。总结一下就是结构体中的成员以及结构体之间的关于和cgroup的基本概念息息相关,所以在掌握cgroup的基本概念的前提下去分析cgroup框架是必经之路。cgroup框架还不仅仅是这些,下面会继续挖掘cgroup中结构体之间的深层次关系。

cgroups中结构体之间的关系

0818b9ca8b590ca3270a3433284dd417.png

cgroups中结构体之间的关系

0818b9ca8b590ca3270a3433284dd417.png 从上面的这幅图可以看出,通过task_struct可以找到一个css_set,这是一个子系统状态的集合,里面有cgroup_subsys_state,所以,通过task_struct来找到这个进程附加在哪些子系统中,受到哪些子系统的限制,通过cgroup_subsys_state子系统状态结构体又可以找到这个子系统属于哪个cgroup,所以通过css_set建立了task_struct和cgroup_subsys 以及task_struct和cgroup的一对多的关系。同时内核为了方便查找css_set,将所有的css_set建立了一个hash table ,通过子系统可以快速找到子系统对应的状态,也就是cgroup_subsys_state,注意看下task_struct的cg_list成员,这个成员将所有具有相同css_set的进程连接起来,好吧,这一切都是为了快速查找,内核设计可谓之用心良苦啊。

0818b9ca8b590ca3270a3433284dd417.png css_set和cgroup是什么样的关系呢,内核为了清晰的表达出这两者的关系可谓之用心良苦,专门设计了一个结构体来表现其多对多的关系cg_cgroup_link,一个css_set对应多个子系统,每个子系统都有其对应的cgroup,所以一个css_set对应多个cgroup,反之,一个cgroup可能包含多个子系统,而多个子系统可能分开存在于多个css_set集合中,所以一个cgroup就对应多个css_set了 好吧,到此为止内核完美的呈现了这些数据结构直接的关系。最后来张大集合。

0818b9ca8b590ca3270a3433284dd417.png 这张是cgroup涉及到的一些 结构体,以及这些结构体之间的关系,可见关系还是很复杂的,其中cgroup_subsys很重要,这是一个抽象类,每一个子系统都会去实例化这样的一个结构体,然后实现其中的一些方法,比如附加子系统,对子系统中的数据读写,等等一系列的操作,cgroupfs_root则是表示的是一个层次,很显然这个结构体应该将所有层次连接起来,以及所有的子系统连接起来,所以你会看到图中有roo_list和subsys_list两个链表。到此为止整个cgroup的框架其实以及很清楚了。

总结: cgroup总体框架的代码不难,难的是这些结构体的复杂关系。

附录

附录A

RedHat Resource Manager Document: https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html

附录B

Cgroup基本入门http://www.zyfforlinux.cc/2015/06/04/Container%E6%8A%80%E6%9C%AF%E4%B9%8Bcgroup%E5%85%A5%E9%97%A8/Cgroup基本使用http://www.zyfforlinux.cc/2015/06/06/Container%E6%8A%80%E6%9C%AF%E4%B9%8Bcgroup%E4%BD%BF%E7%94%A8/Cgroup使用进阶http://www.zyfforlinux.cc/2015/06/08/Container%E6%8A%80%E6%9C%AF%E4%B9%8Bcgroup%E6%8F%90%E9%AB%98/

转自张义飞的博客,部分内容和图来自网络。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值