读书人

控制组剖解文件系统的观点

发布时间: 2012-07-15 20:20:06 作者: rapoo

控制组剖析——文件系统的观点
控制组剖析——文件系统的观点

前言
在前面的文章中介绍了cgroup设计中的主要数据结构以及数据结构间的关联,并简要分析了子系统的实现.在文中还提到内核采用控制组文件系统对控制组进行管理,本文中将从文件系统的角度对cgroup进行剖析.

1 VFS简介

虚拟文件系统(VFS)也称为虚拟文件系统转换(Virtual Filesystem Switch),它是一个内核软件层,用来处理与Unix标准文件系统相关的所有系统调用.VFS蕴涵的主要思想是引入了一个通用文件模型(common file model),该模型可表示所有支持的文件系统,其反映了传统Unix文件系统提供的文件模型.通用文件模型由如下对象结构组成:
超级块对象(superblock object):存放已经安装的文件系统有关信息.一般情况下对应于文件系统中的文件系统控制块.
索引节点对象(inode object):存放关于具体文件的信息,该结构中包含了一个索引节点号,它唯一标志了一个存在的文件.
目录项对象(dentry object):存放文件名和具体文件进行链接的有关信息.
文件对象(file object):存放打开文件和进程之间交互信息.
在下面将从VFS入手,介绍控制组文件系统的设计与实现.

2 控制组文件系统

2.1 注册文件系统

为使内核能够识别所安装的文件系统,目标文件系统的源码必须包含在内核映像,或者以模块的形式动态装载.VFS为追踪内核中所有的文件系统,内核使用文件系统类型注册机制来实现.系统中每个注册的文件系统使用file_system_type对象来表示,控制组文件系统类型定义如下:

static ssize_t cgroup_file_write(struct file *file, const char __user *buf, size_t nbytes, loff_t *ppos){//获取文件对应的cftype对象和cgroup对象指针struct cftype *cft = __d_cft(file->f_dentry);struct cgroup *cgrp = __d_cdt(file->f_dentry->d_parent);if(cgroup_is_removed(cgrp))return -ENODEV;if(cft->write)return cft->write(cgrp,cft,file,buf,nbytes,ppos);if(cft->write_u64 || cft->write_s64)return cgroup_write_X64(cgrp,cft,file,buf,nbytes,ppos);if(cft->write_string)return cgroup_write_string(cgrp,cft,file,buf,nbytes,ppos);if(cft->trigger){int ret = cft->trigger(cgrp,(unsigned int)cft->private);return ret ? ret : nbytes;}return -EINVAL;}

cgroup_write_X64和cgroup_write_string分别封装了cftype相关接口,主要负责从用户空间拷贝数据,如果需要还会将数据转换为期望的格式,然后调用cftype接口实现写操作.cftype对象的trigger接口定义了在不关注实际写内容时从用户空间获得一些反馈(kick)信息.

3 控制组proc接口

为便于查看控制组信息,控制组文件系统在proc系统中创建了/proc/cgroups和/proc/<pid>/cgroup文件./proc/cgroups统计子系统和层次结构的信息,其格式为:
subsys_name hierarchy num_cgroups enabled
其中,subsys_name为子系统名称,hierarchy为子系统连接到层次结构id,num_cgroups为层次结构中控制组数量,enabled表示子系统是否被打开.
/proc/<pid>/cgroup统计了任务所属层次结构信息,其输出格式为:
hierarchy_id:subsys_root_name:cgroup_path
其中hierarchy_id为任务所属的层次结构id,subsys_root_name为连接到层次结构的子系统和层次结构名称,cgroup_path:为控制组对应目录的路径.
由于每个任务可同时属于多个层次结构故输出信息可能为多行.
以上统计信息分别由proc_cgroupstats_show()和proc_cgroup_show()函数输出,由于代码较为简单,就不再对其进行详细论述.

4 小结

本文主要从文件系统的角度论述了控制组的组织管理,分别介绍了控制组文件系统注册、超级块管理、索引节点操作、文件操作的实现,并简要介绍了控制组在proc文件系统中的接口.通过控制组文件系统用户对控制组的操作会更加简单,比如使用mkdir命令即可创建子控制组,当需要销毁控制组时,只需使用rmdir命令将控制组对应的目录删除即可,当然,在删除目录之前必须保证没有子控制组,如果待删除的控制组不是根控制组,还需保证控制组中没有任务存在.

5 附录

5.1 rebind_subsystems实现

rebind_subsystems()实现了层次结构和子系统的重绑定,子系统重绑定时需满足如下条件:
1) 如果将子系统连接到层次结构,那么必须保证该层次结构没有链接到除rootnode以外的其他层次结构.
2) 如果解除子系统和层次结构的链接,那么解除链接后需将子系统链接到rootnode.
cgroupfs_root结构的actual_subsys_bits数据项保存了链接到层次结构的子系统位图,通过位运算很容易得到需链接和解除链接的子系统位图:
removed_bits = root->actual_subsys_bits & ~final_bits;
added_bits = final_bits & ~root->actual_subsys_bits;
在计算出removed_bits和added_bits后,需验证需要添加的子系统是空闲的(当前链接到rootnode),如果通过验证,则根据上述规则添加和解除子系统.

5.2 文件系统和层次结构的关联

为关联文件系统和层次结构,文件系统和层次结构对象间有如下关联关系,在下面的表示中A.a<---->B.b表示通过结构A的数据项a可找到相关的结构B,反之,通过结构B中数据项b可找到相关结构A.
1) 超级块和控制组系统根
superblock.s_fs_info<------>cgroupfs_root.sb
2) 目录和控制组
dentry.d_fsdata<------->cgroup.dentry
3) 目录和控制文件
dentry.d_fsdata-------->cftype

结束语
将层次结构作为文件系统不仅符合控制组间的树形层次结构,更方便了用户对控制组的管理和信息交互.从用户的观点来看,层次结构和普通的文件系统没有两样,对控制组的操作转换为对文件的操作,简化了用户空间对控制组进行管理的复杂度,从而允许用户空间使用简单的rmdir,mkdir等命令即可实现对控制组的管理.

冗长的论述有时会让人厌烦,希望您可以忍受我杂乱无章的表述,good luck!

读书人网 >操作系统

热点推荐