cgroup的实现相对namespace要复杂一些,网上也有一些代码分析,大家对代码分析的兴趣估计也不大,所以这里就不放代码分析了,主要对其使用进行说明,么么哒。
Cgroup是linux内核集成的资源控制机制,cgroup与用户态交互通过特殊文件系统cgroup文件系统,进行交互,所有设置或者查看cgroup的动作都可以通过cgroup文件系统下的文件完成,因此除了编译内核的时候需要打开特定的选项之外,还需在系统启动之后挂载cgroup文件系统方能使用cgroup的控制功能。几个重要概念:
Ø cgroup: 一组进程的行为控制。要对某个进程进行资源限制,就将进程添加到cgroup中,一个cgroup可以有多个进程。
Ø hierarchy: 一组cgroup的集合,可以理解成cgroup的根,cgroup是hierarchy的结点。一个hierarchy的资源限制为1,代表拥有系统所有资源,cgroup资源限制小于1,分配系统资源。
Ø subsystem: cgroup可以进行多种资源限制,某种资源限制就是一个subsystem,所有的subsystem构成了资源限制的所有资源种类。
三者之间的主要关系:
Ø 创建新hierarchy时,系统中的所有任务都是那个hierarchy的根cgroup的初始成员。
Ø 一个subsystem最多只能附加到一个hierarchy。
Ø 一个hierarchy可以附加多个subsystem。
Ø 一个进程可以是多个cgroup的成员,但是这些cgroup必须在不同的hierarchy下。
Ø 创建子进程时,子进程自动成为父进程所在 cgroup 的成员。可根据需要将该子进程移动到不同的 cgroup 中。
Cgroup包含了11个子系统,分别是:
Ø Blkio:控制块设备的访问,比如带宽等。
Ø cpu :控制进程占用cpu的多少。
Ø Cpuacct: 记录cgroup 中进程使用的 CPU 情况。
Ø Cpuset:为 cgroup 中的进程分配CPU和内存节点。
Ø Devices:控制进程对设备的访问。
Ø Freezer:挂起或者恢复 cgroup 中的进程。
Ø Memory:设定 cgroup 中进程的内存限制,统计使用的内存资源。
Ø net_cls:使用等级识别符(classid)标记网络数据包,使得Linux 流量控制程序(tc)识别具体 cgroup 中的数据包。
Ø Ns:命名空间子系统,默认创建cgroup的时候会创建命名空间,新的内核不支持。
Ø Debug:用于调试。
Ø Perf:按cgroup进行性能统计。
Cgroup与用户态的交互通过cgroup文件系统完成,cgroup的每一控制箱在cgroup文件系统下都会对应一个文件,通过对文件的读写,来实现资源的控制。cgroup文件系统的定义:
static struct file_system_type cgroup_fs_type = {
.name = "cgroup",
.get_sb = cgroup_get_sb,
.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 = simple_lookup,
.mkdir = cgroup_mkdir,
.rmdir = cgroup_rmdir,
.rename = cgroup_rename,
};
在cgroup文件系统中,使用mkdir创建cgroup或者用rmdir删除cgroup时,就会调用相应的函数指针指向的函数。
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文件系统为cgroups控制文件定义了一个cftype的结构体。cftype的定义:
struct cftype {
char name[MAX_CFTYPE_NAME];
int private; /*
mode_t mode;
size_t max_write_len;
int (*open)(struct inode *inode, struct file *file);
ssize_t (*read)(struct cgroup *cgrp, struct cftype *cft,
struct file *file,
char __user *buf, size_t nbytes, loff_t *ppos);
u64 (*read_u64)(struct cgroup *cgrp, struct cftype *cft);
s64 (*read_s64)(struct cgroup *cgrp, struct cftype *cft);
int (*read_map)(struct cgroup *cont, struct cftype *cft,
struct cgroup_map_cb *cb);
int (*read_seq_string)(struct cgroup *cont, struct cftype *cft,
struct seq_file *m);
ssize_t (*write)(struct cgroup *cgrp, struct cftype