Cgroup文件系统

Cgroup文件系统用于管理Linux中的资源限制。通过mount命令创建并挂载cgroup层级,如`cpu_and_mem`,附加cpu、cpuset、memory子系统。在cgroup下创建子目录`foo`,其`tasks`文件记录所属进程。VFS作为内核层面对不同文件系统调用的抽象,而cgroup文件系统定义了自己的超级块、文件操作和控制文件结构,通过函数指针调用相应操作函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

cgroup用户空间的管理是通过cgroup文件系统实现的。

比如要创建一个层级:mount -t cgroup -o cpu,cpuset,memory cpu_and_mem /cgroup/cpu_and_mem

这个命令就创建一个名为cpu_and_mem的层级,这个层级上附加了cpu,cpuset,memory三个子系统,并把层级挂载到了/cgroup/cpu_and_mem


创建一个cgroup:

cd /cgroup/cpu_and_mem

mkdir foo

通过以上两个命令,我们就再刚才创建的层级下创建了一个叫foo的cgroup

你再cd foo,然后ls,你会发现一些文件,这是cgroup相关子系统的控制文件,你可以读取这些控制文件,这些控制文件存储的值就是对相应的cgroup的控制信息,你也可以写控制文件来更改控制信息。


在这些文件中,有一个叫tasks的文件,里面包含了所有属于这个cgroup的进程的进程号

在刚才创建的foo下,你cat tasks,应该是空的,因为此时这个cgroup里面还没有进程

你cd /cgroup/cpu_and_mem再cat tasks,你可以看到系统中所有进程的进程号,这是因为每创建一个层级的时候,系统的所有进程都会自动被加到该层级的根cgroup里面。tasks文件不仅可以读,还可以写,你将一个进程的进程号写入到某个cgroup目录下的tasks里面,你就将这个进程加入了相应的cgroup


cgroup文件系统的实现:

在讲cgroup文件系统的实现之前,必须简单的介绍一下Linux VFS

VFS是所谓的虚拟文件系统转换,是一个内核软件层,用来处理与Unix标准文件系统的所有系统调用。VFS对用户提供统一的读写等文件操作调用接口,当用户调用读写等函数时,内核则调用特定的文件系统实现。具体而言,文件在内核内存中是一个file数据结构来表示的。这个数据结构包含一个f_op的字段,该字段中包含了一组指向特定文件系统实现的函数指针。当用户执行read()操作时,内核调用sys_read(),然后sys_read()查找到指向该文件属于的文件系统的读函数指针,并调用它,即file->f_op->read()。

VFS其实是面向对象的,在这里,对象是一个软件结构,既定义数据也定义了之上的操作。出于效率,Linux并没有采用C++之类的面向对象的语言,而是采用了C的结构体,然后在结构体里面定义了一系列的函数指针这些函数指针对应于对象的方法。


下面看下cgroup文件系统的定义:

static struct file_system_type cgroup_fs_type = {
	.name = "cgroup",
	.mount = cgroup_mount,
	.kill_sb = cgroup_kill_sb,
};

这里定义了两个函数指针,定义了一个文件系统必须实现的两个操作get_sb和kill_sb,即获得超级块和释放超级块。这两个操作会在使用mount系统调用挂载cgroup文件系统时使用。


cgroup超级块的定义:

static const struct super_operations cgroup_ops = {
	.statfs = simple_statfs,
	.drop_inode = generic_delete_inode,
	.show_options = cgroup_show_options,
	.remount_fs = cgroup_remount,
};
cgroup索引块定义:

static const struct inode_operations cgroup_dir_inode_operations = {
	.lookup = cgroup_lookup,
	.mkdir = cgroup_mkdir,
	.rmdir = cgroup_rmdir,
	.rename = cgroup_rename,
};

在cgroup文件系统中,使用mkdir创建cgroup或者用rmdir删除cgroup时,就会调用相应的函数指针指向的函数。比如:使用mkdir创建cgroup时,会调用cgroup_mkdir,然后在cgroup_mkdir中再调用具体实现的cgroup_create函数。


cgroup文件操作定义:

static const struct file_operations cgroup_file_operations = {
	.read = cgroup_file_read,
	.write = cgroup_file_write,
	.llseek = generic_file_llseek,
	.open = cgroup_file_open,
	.release = cgroup_file_release,
};
在cgroup文件系统中,对目录下的控制文件进行操作时,会调用该结构体中指针指向的函数。比如:对文件进行读操作时,会调用cgroup_file_read,在cgroup_file_read中,会根据需要调用该文件对应的cftype结构体定义的对应读函数。


我们再来看cgroup文件系统中的cgroup控制文件。cgroup定义一个cftype的结构体来管理控制文件。

cftype中除了定义文件的名字和相关权限标记外,主要是定义了对文件进行操作的函数指针。不同的文件可以有不同的操作,对文件进行操作时,相关函数指针指向的函数会被调用。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值