diff options
author | Tejun Heo <tj@kernel.org> | 2014-03-19 10:23:55 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-03-19 10:23:55 -0400 |
commit | a2dd424750807f83632a2a70293961086fd8f870 (patch) | |
tree | 75f55e64a9ad9a4babf4c7effcaf75cf327dd6c8 /kernel/cgroup.c | |
parent | 4d3bb511b5f9980fc3e9ae5939ebc475b231d3fc (diff) |
cgroup: make cgrp_dfl_root mountable
cgrp_dfl_root will be used as the default unified hierarchy. This
patch makes cgrp_dfl_root mountable by making the following changes.
* cgroup_init_early() now initializes cgrp_dfl_root w/
CGRP_ROOT_SANE_BEHAVIOR. The default hierarchy is always sane.
* parse_cgroupfs_options() and cgroup_mount() are updated such that
cgrp_dfl_root is mounted if sane_behavior is specified w/o any
subsystems.
* rebind_subsystems() now populates the root directory of
cgrp_dfl_root. Note that the function still guarantees success of
rebinding subsystems to cgrp_dfl_root. If populating fails while
rebinding to cgrp_dfl_root, it whines but ignores the error.
* For backward compatibility, the default hierarchy shows up in
/proc/$PID/cgroup only after it's explicitly mounted so that
userland which doesn't make use of it doesn't see any change.
* "current_css_set_cg_links" file of debug cgroup now treats the
default hierarchy the same as other hierarchies. This is visible to
userland. Given that it's for debug controller, this should be
fine.
* While at it, implement cgroup_on_dfl() which tests whether a give
cgroup is on the default hierarchy or not.
The above changes make cgrp_dfl_root mostly equivalent to other
controllers but the actual unified hierarchy behaviors are not
implemented yet. Let's plug child cgroup creation in cgrp_dfl_root
from create_cgroup() for now.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 94 |
1 files changed, 61 insertions, 33 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f5754910e80b..69b4939e9f6d 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -142,7 +142,13 @@ static const char *cgroup_subsys_name[] = { | |||
142 | * unattached - it never has more than a single cgroup, and all tasks are | 142 | * unattached - it never has more than a single cgroup, and all tasks are |
143 | * part of that cgroup. | 143 | * part of that cgroup. |
144 | */ | 144 | */ |
145 | static struct cgroup_root cgrp_dfl_root; | 145 | struct cgroup_root cgrp_dfl_root; |
146 | |||
147 | /* | ||
148 | * The default hierarchy always exists but is hidden until mounted for the | ||
149 | * first time. This is for backward compatibility. | ||
150 | */ | ||
151 | static bool cgrp_dfl_root_visible; | ||
146 | 152 | ||
147 | /* The list of hierarchy roots */ | 153 | /* The list of hierarchy roots */ |
148 | 154 | ||
@@ -999,10 +1005,22 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
999 | return -EBUSY; | 1005 | return -EBUSY; |
1000 | } | 1006 | } |
1001 | 1007 | ||
1002 | if (dst_root != &cgrp_dfl_root) { | 1008 | ret = cgroup_populate_dir(&dst_root->cgrp, ss_mask); |
1003 | ret = cgroup_populate_dir(&dst_root->cgrp, ss_mask); | 1009 | if (ret) { |
1004 | if (ret) | 1010 | if (dst_root != &cgrp_dfl_root) |
1005 | return ret; | 1011 | return ret; |
1012 | |||
1013 | /* | ||
1014 | * Rebinding back to the default root is not allowed to | ||
1015 | * fail. Using both default and non-default roots should | ||
1016 | * be rare. Moving subsystems back and forth even more so. | ||
1017 | * Just warn about it and continue. | ||
1018 | */ | ||
1019 | if (cgrp_dfl_root_visible) { | ||
1020 | pr_warning("cgroup: failed to create files (%d) while rebinding 0x%lx to default root\n", | ||
1021 | ret, ss_mask); | ||
1022 | pr_warning("cgroup: you may retry by moving them to a different hierarchy and unbinding\n"); | ||
1023 | } | ||
1006 | } | 1024 | } |
1007 | 1025 | ||
1008 | /* | 1026 | /* |
@@ -1011,7 +1029,7 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
1011 | */ | 1029 | */ |
1012 | mutex_unlock(&cgroup_mutex); | 1030 | mutex_unlock(&cgroup_mutex); |
1013 | for_each_subsys(ss, ssid) | 1031 | for_each_subsys(ss, ssid) |
1014 | if ((ss_mask & (1 << ssid)) && ss->root != &cgrp_dfl_root) | 1032 | if (ss_mask & (1 << ssid)) |
1015 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); | 1033 | cgroup_clear_dir(&ss->root->cgrp, 1 << ssid); |
1016 | mutex_lock(&cgroup_mutex); | 1034 | mutex_lock(&cgroup_mutex); |
1017 | 1035 | ||
@@ -1039,8 +1057,7 @@ static int rebind_subsystems(struct cgroup_root *dst_root, | |||
1039 | ss->bind(css); | 1057 | ss->bind(css); |
1040 | } | 1058 | } |
1041 | 1059 | ||
1042 | if (dst_root != &cgrp_dfl_root) | 1060 | kernfs_activate(dst_root->cgrp.kn); |
1043 | kernfs_activate(dst_root->cgrp.kn); | ||
1044 | return 0; | 1061 | return 0; |
1045 | } | 1062 | } |
1046 | 1063 | ||
@@ -1190,16 +1207,6 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1190 | return -ENOENT; | 1207 | return -ENOENT; |
1191 | } | 1208 | } |
1192 | 1209 | ||
1193 | /* | ||
1194 | * If the 'all' option was specified select all the subsystems, | ||
1195 | * otherwise if 'none', 'name=' and a subsystem name options | ||
1196 | * were not specified, let's default to 'all' | ||
1197 | */ | ||
1198 | if (all_ss || (!one_ss && !opts->none && !opts->name)) | ||
1199 | for_each_subsys(ss, i) | ||
1200 | if (!ss->disabled) | ||
1201 | set_bit(i, &opts->subsys_mask); | ||
1202 | |||
1203 | /* Consistency checks */ | 1210 | /* Consistency checks */ |
1204 | 1211 | ||
1205 | if (opts->flags & CGRP_ROOT_SANE_BEHAVIOR) { | 1212 | if (opts->flags & CGRP_ROOT_SANE_BEHAVIOR) { |
@@ -1211,6 +1218,23 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1211 | pr_err("cgroup: sane_behavior: noprefix, xattr, clone_children, release_agent and name are not allowed\n"); | 1218 | pr_err("cgroup: sane_behavior: noprefix, xattr, clone_children, release_agent and name are not allowed\n"); |
1212 | return -EINVAL; | 1219 | return -EINVAL; |
1213 | } | 1220 | } |
1221 | } else { | ||
1222 | /* | ||
1223 | * If the 'all' option was specified select all the | ||
1224 | * subsystems, otherwise if 'none', 'name=' and a subsystem | ||
1225 | * name options were not specified, let's default to 'all' | ||
1226 | */ | ||
1227 | if (all_ss || (!one_ss && !opts->none && !opts->name)) | ||
1228 | for_each_subsys(ss, i) | ||
1229 | if (!ss->disabled) | ||
1230 | set_bit(i, &opts->subsys_mask); | ||
1231 | |||
1232 | /* | ||
1233 | * We either have to specify by name or by subsystems. (So | ||
1234 | * all empty hierarchies must have a name). | ||
1235 | */ | ||
1236 | if (!opts->subsys_mask && !opts->name) | ||
1237 | return -EINVAL; | ||
1214 | } | 1238 | } |
1215 | 1239 | ||
1216 | /* | 1240 | /* |
@@ -1226,13 +1250,6 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts) | |||
1226 | if (opts->subsys_mask && opts->none) | 1250 | if (opts->subsys_mask && opts->none) |
1227 | return -EINVAL; | 1251 | return -EINVAL; |
1228 | 1252 | ||
1229 | /* | ||
1230 | * We either have to specify by name or by subsystems. (So all | ||
1231 | * empty hierarchies must have a name). | ||
1232 | */ | ||
1233 | if (!opts->subsys_mask && !opts->name) | ||
1234 | return -EINVAL; | ||
1235 | |||
1236 | return 0; | 1253 | return 0; |
1237 | } | 1254 | } |
1238 | 1255 | ||
@@ -1487,6 +1504,14 @@ retry: | |||
1487 | goto out_unlock; | 1504 | goto out_unlock; |
1488 | 1505 | ||
1489 | /* look for a matching existing root */ | 1506 | /* look for a matching existing root */ |
1507 | if (!opts.subsys_mask && !opts.none && !opts.name) { | ||
1508 | cgrp_dfl_root_visible = true; | ||
1509 | root = &cgrp_dfl_root; | ||
1510 | cgroup_get(&root->cgrp); | ||
1511 | ret = 0; | ||
1512 | goto out_unlock; | ||
1513 | } | ||
1514 | |||
1490 | for_each_root(root) { | 1515 | for_each_root(root) { |
1491 | bool name_match = false; | 1516 | bool name_match = false; |
1492 | 1517 | ||
@@ -3622,6 +3647,13 @@ static long cgroup_create(struct cgroup *parent, const char *name, | |||
3622 | struct cgroup_subsys *ss; | 3647 | struct cgroup_subsys *ss; |
3623 | struct kernfs_node *kn; | 3648 | struct kernfs_node *kn; |
3624 | 3649 | ||
3650 | /* | ||
3651 | * XXX: The default hierarchy isn't fully implemented yet. Block | ||
3652 | * !root cgroup creation on it for now. | ||
3653 | */ | ||
3654 | if (root == &cgrp_dfl_root) | ||
3655 | return -EINVAL; | ||
3656 | |||
3625 | /* allocate the cgroup and its ID, 0 is reserved for the root */ | 3657 | /* allocate the cgroup and its ID, 0 is reserved for the root */ |
3626 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); | 3658 | cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); |
3627 | if (!cgrp) | 3659 | if (!cgrp) |
@@ -4061,7 +4093,8 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss) | |||
4061 | */ | 4093 | */ |
4062 | int __init cgroup_init_early(void) | 4094 | int __init cgroup_init_early(void) |
4063 | { | 4095 | { |
4064 | static struct cgroup_sb_opts __initdata opts = { }; | 4096 | static struct cgroup_sb_opts __initdata opts = |
4097 | { .flags = CGRP_ROOT_SANE_BEHAVIOR }; | ||
4065 | struct cgroup_subsys *ss; | 4098 | struct cgroup_subsys *ss; |
4066 | int i; | 4099 | int i; |
4067 | 4100 | ||
@@ -4198,7 +4231,7 @@ int proc_cgroup_show(struct seq_file *m, void *v) | |||
4198 | struct cgroup *cgrp; | 4231 | struct cgroup *cgrp; |
4199 | int ssid, count = 0; | 4232 | int ssid, count = 0; |
4200 | 4233 | ||
4201 | if (root == &cgrp_dfl_root) | 4234 | if (root == &cgrp_dfl_root && !cgrp_dfl_root_visible) |
4202 | continue; | 4235 | continue; |
4203 | 4236 | ||
4204 | seq_printf(m, "%d:", root->hierarchy_id); | 4237 | seq_printf(m, "%d:", root->hierarchy_id); |
@@ -4631,15 +4664,10 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v) | |||
4631 | cset = rcu_dereference(current->cgroups); | 4664 | cset = rcu_dereference(current->cgroups); |
4632 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { | 4665 | list_for_each_entry(link, &cset->cgrp_links, cgrp_link) { |
4633 | struct cgroup *c = link->cgrp; | 4666 | struct cgroup *c = link->cgrp; |
4634 | const char *name = "?"; | ||
4635 | |||
4636 | if (c != &cgrp_dfl_root.cgrp) { | ||
4637 | cgroup_name(c, name_buf, NAME_MAX + 1); | ||
4638 | name = name_buf; | ||
4639 | } | ||
4640 | 4667 | ||
4668 | cgroup_name(c, name_buf, NAME_MAX + 1); | ||
4641 | seq_printf(seq, "Root %d group %s\n", | 4669 | seq_printf(seq, "Root %d group %s\n", |
4642 | c->root->hierarchy_id, name); | 4670 | c->root->hierarchy_id, name_buf); |
4643 | } | 4671 | } |
4644 | rcu_read_unlock(); | 4672 | rcu_read_unlock(); |
4645 | up_read(&css_set_rwsem); | 4673 | up_read(&css_set_rwsem); |