Cgroup文件系统

  • Post author:
  • Post category:其他


Cgroup

文件系统

static struct file_system_type cgroup_fs_type = {


.name = “cgroup”,

.mount = cgroup_mount,

.kill_sb = cgroup_kill_sb,

.fs_flags = FS_USERNS_MOUNT,

};

static struct file_system_type cgroup2_fs_type = {


.name = “cgroup2”,

.mount = cgroup_mount,

.kill_sb = cgroup_kill_sb,

.fs_flags = FS_USERNS_MOUNT,

};

Cgroups用户空间的管理是通过

cgroup


文件系统实现的。

比如要创建一个层级:V1

mount -t cgroup -o cpu,cpuset,memory none /sys/test_cgroup

这个命令就创建一个名为test_cgroup的层级,这个层级上附加了

cpu,cpuset,memory


三个子系统,并把层级挂载到了


/sys/test_cgroup

.

创建一个

cgroup



cd /sys/test_cgroup

mkdir test1

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




cgroup



你再cd test1,然后

ls

你会发现一些文件,这是

cgroups


相关子系统的控制文件,你可以读取这些控制文件,这些控制文件存储的值就是对相应的


cgrouop


的控制信息,你也可以写控制文件来更改控制信息。

在这些文件中,有一个叫

tasks


的文件,里面的包含了所有属于这个


cgroup


的进程的进程号。

在刚才创建的

test1


下,你


cat tasks


,应该是空的,因为此时这个


cgroup


里面还没有进程。你


change to root cgroup,



cat tasks


,你可以看到系统中所有进程的进程号,这是因为每创建一个层级的时候,系统的所有进程都会自动被加到该层级的根


cgroup


里面。


Tasks


文件不仅可以读,还可以写,你将一个进程的进程号写入到某个


cgroup


目录下的


tasks


里面,你就将这个进程加入了相应的


cgroup




/**

* cgroup_init – cgroup initialization

*

* Register cgroup filesystem and /proc file, and initialize

* any subsystems that didn’t request early init.

*/

int __init cgroup_init(void)

{


struct cgroup_subsys *ss;

int ssid;

BUILD_BUG_ON(CGROUP_SUBSYS_COUNT > 16);

BUG_ON(percpu_init_rwsem(&cgroup_threadgroup_rwsem));

BUG_ON(cgroup_init_cftypes(NULL, cgroup_dfl_base_files));

BUG_ON(cgroup_init_cftypes(NULL, cgroup_legacy_base_files));

/*

* The latency of the synchronize_sched() is too high for cgroups,

* avoid it at the cost of forcing all readers into the slow path.

*/

rcu_sync_enter_start(&cgroup_threadgroup_rwsem.rss);

get_user_ns(init_cgroup_ns.user_ns);

mutex_lock(&cgroup_mutex);

/*

* Add init_css_set to the hash table so that dfl_root can link to

* it during init.

*/

hash_add(css_set_table, &init_css_set.hlist,

css_set_hash(init_css_set.subsys));

BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0));

mutex_unlock(&cgroup_mutex);

for_each_subsys(ss, ssid) {


if (ss->early_init) {


struct cgroup_subsys_state *css =

init_css_set.subsys[ss->id];

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

GFP_KERNEL);

BUG_ON(css->id < 0);

} else {


cgroup_init_subsys(ss, false);

}

list_add_tail(&init_css_set.e_cset_node[ssid],

&cgrp_dfl_root.cgrp.e_csets[ssid]);

/*

* Setting dfl_root subsys_mask needs to consider the

* disabled flag and cftype registration needs kmalloc,

* both of which aren’t available during early_init.

*/

if (cgroup_disable_mask & (1 << ssid)) {


static_branch_disable(cgroup_subsys_enabled_key[ssid]);

printk(KERN_INFO “Disabling %s control group subsystem\n”,

ss->name);

continue;

}

if (cgroup_ssid_no_v1(ssid))

printk(KERN_INFO “Disabling %s control group subsystem in v1 mounts\n”,

ss->name);

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

if (ss->implicit_on_dfl)

cgrp_dfl_implicit_ss_mask |= 1 << ss->id;

else if (!ss->dfl_cftypes)

cgrp_dfl_inhibit_ss_mask |= 1 << ss->id;

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


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)

ss->bind(init_css_set.subsys[ssid]);

}

/* init_css_set.subsys[] has been updated, re-hash */

hash_del(&init_css_set.hlist);

hash_add(css_set_table, &init_css_set.hlist,

css_set_hash(init_css_set.subsys));

WARN_ON(sysfs_create_mount_point(fs_kobj, “cgroup”));

WARN_ON(register_filesystem(&cgroup_fs_type));

WARN_ON(register_filesystem(&cgroup2_fs_type));

WARN_ON(!proc_create(“cgroups”, 0, NULL, &proc_cgroupstats_operations));

return 0;

}

/**

* cgroup_init_early – cgroup initialization at system boot

*

* Initialize cgroups at system boot, and initialize any

* subsystems that request early init.

*/

int __init cgroup_init_early(void)

{


static struct cgroup_sb_opts  opts;

struct cgroup_subsys *ss;

int i;

init_cgroup_root(&cgrp_dfl_root, &opts);

cgrp_dfl_root.cgrp.self.flags |= CSS_NO_REF;

RCU_INIT_POINTER(init_task.cgroups, &init_css_set);

for_each_subsys(ss, i) {


WARN(!ss->css_alloc || !ss->css_free || ss->name || ss->id,

“invalid cgroup_subsys %d:%s css_alloc=%p css_free=%p id:name=%d:%s\n”,

i, cgroup_subsys_name[i], ss->css_alloc, ss->css_free,

ss->id, ss->name);

WARN(strlen(cgroup_subsys_name[i]) > MAX_CGROUP_TYPE_NAMELEN,

“cgroup_subsys_name %s too long\n”, cgroup_subsys_name[i]);

ss->id = i;

ss->name = cgroup_subsys_name[i];

if (!ss->legacy_name)

ss->legacy_name = cgroup_subsys_name[i];

if (ss->early_init)

cgroup_init_subsys(ss, true);

}

return 0;

}



版权声明:本文为sunlei0625原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。