本文共 4448 字,大约阅读时间需要 14 分钟。
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; }转载地址:http://sxqti.baihongyu.com/