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;
    
    }
 
