linux中ss实现源码,源码解析容器底层cgroup的实现

原标题:源码解析容器底层cgroup的实现

在 上一篇文章 里,我们探讨了容器底层 cgroup 的作用与数据结构,本文我们将深入分析 cgroup 的代码实现。

一、cgroup 的初始化和 mount

测试环境版本与第一篇一致:

f70a992f6a34dcd728b9ab39ef1001b6.png

本篇开始我们将分析 cgroup 的代码实现,与书(《精通 Linux 内核—智能设备开发核心技术》,下同)中的原则一致,我们重点分析核心和难点代码,其他部分在不影响理解的情况下一笔带过。

1.1 cgroup 的初始化

cgroup 的初始化分为两个阶段。

第一阶段:初始化 cgrp_dfl_root 和系统支持的 ss,由cgroup_init_early 函数完成。cgrp_dfl_root,看名字就知道,default cgroup_root,默认的 cgroup 层级结构,它在 cgroup v1 中戏份有限,在 v2 中是 c 位。至于 ss 的初始化,主要是 id 和 name,如果 ss 的 early_init 为真,调用 cgroup_init_subsys 完善它与cgrp_dfl_root 的关系。

cgroup_init_subsys 有助于我们理解 cgroup 和 ss 之间的关系,此处展开讨论,代码如下:

void cgroup_init_subsys( structcgroup_subsys*ss, bool early)

{

ss->root = &cgrp_dfl_root;

css = ss->css_alloc(cgroup_css(&cgrp_dfl_root.cgrp, ss));

init_and_link_css(css, ss, &cgrp_dfl_root.cgrp);

if(early) {

css->id = 1;

} else{

css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL);

}

init_css_set.subsys[ss->id] = css; //***,三个星号哈

BUG_ON(online_css(css));

我们在第一篇中说过,ss 和 cgroup 是多对多的关系,通过 css 实现,cgroup_init_subsys 就是完成这个任务的。cgrp_dfl_root 是一个 cgroup_root,它本身内嵌了一个 cgroup,所以具体点就是申请一个 css,建立它与 cgrp_dfl_root.cgrp 的联系。

它先回调 ss->css_alloc 函数申请 css,css_alloc 的参数表示将要产生的 css 的父css(我们在第一篇讲过,css 的两方面作用),调用 cgroup_init_subsys 的时候,父 css 还不存在,所以最终传递的参数是 NULL。

我们分析的 cgroup 子系统 cpuset 的 css_alloc 回调函数是 cpuset_css_alloc,当它发现传递的参数 parent_css 等于 NULL 的时候,直接返回 &top_cpuset.css,也就是一个全局的 css。全局,意味着牵一发动全身,隐约中找到了第一篇课堂作业第一题的答案。

有了 css 后,调用 init_and_link_css 和 online_css 建立 cgroup 和 ss 的关系就是水到渠成的事情了。online_css 会回调 ss->css_online 函数,对 cpuset 而言,因为 css_alloc 返回的是全局的 css,此处 css_online 并没有实际操作。

init_css_set(三颗星,重点)是 init css_set,是一个全局的 css_set,这里使用申请到的 css 为相应的字段赋值。

第二阶段:绑定 ss 与 cgrp_dfl_root,也就是说系统启动的初期所有的 ss 都与默认的 cgroup 层级结构绑定。由 cgroup_init 函数完成,主要逻辑如下:

int cgroup_init(void)

{

BUG_ON(cgroup_init_cftypes( NULL, cgroup_base_files)); //1

BUG_ON(cgroup_init_cftypes( NULL, cgroup1_base_files));

BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0)); //2

for_each_subsys(ss, ssid) {

if(ss->early_init) { //3

struct cgroup_subsys_state *css = init_css_set.subsys[ss->id];

css->id = cgroup_idr_alloc(&ss->css_idr, css, 1, 2, GFP_KERNEL);

} else{

cgroup_init_subsys(ss, false);

}

cgrp_dfl_root.subsys_mask |= 1 << ss->id;

if(ss->dfl_cftypes == ss->legacy_cftypes) { //4

WARN_ON(cgroup_add_cftypes(ss, ss->dfl_cftypes));

} else{

WARN_ON(cgroup_add_dfl_cftypes(ss, ss->dfl_cftypes));

WARN_ON(cgroup_add_legacy_cftypes(ss, ss->legacy_cftypes));

}

if(ss->bind) //5

ss->b

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值