diff options
author | Aristeu Rozanski <aris@redhat.com> | 2013-02-15 11:55:46 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-03-20 10:50:17 -0400 |
commit | 1909554c9715e4d032497993bb56f2726bfa89ae (patch) | |
tree | db3a67d9f29afd47e8d827cebeabd5f87a7a1225 /security | |
parent | c39a2a3018f8065cb5ea38b0314c1bbedb2cfa0d (diff) |
devcg: use css_online and css_offline
Allocate resources and change behavior only when online. This is needed in
order to determine if a node is suitable for hierarchy propagation or if it's
being removed.
Locking:
Both functions take devcgroup_mutex to make changes to device_cgroup structure.
Hierarchy propagation will also take devcgroup_mutex before walking the
tree while walking the tree itself is protected by rcu lock.
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Aristeu Rozanski <aris@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/device_cgroup.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index ddf3c709c0c2..16c9e1069be6 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -185,36 +185,59 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) | |||
185 | __dev_exception_clean(dev_cgroup); | 185 | __dev_exception_clean(dev_cgroup); |
186 | } | 186 | } |
187 | 187 | ||
188 | /** | ||
189 | * devcgroup_online - initializes devcgroup's behavior and exceptions based on | ||
190 | * parent's | ||
191 | * @cgroup: cgroup getting online | ||
192 | * returns 0 in case of success, error code otherwise | ||
193 | */ | ||
194 | static int devcgroup_online(struct cgroup *cgroup) | ||
195 | { | ||
196 | struct dev_cgroup *dev_cgroup, *parent_dev_cgroup = NULL; | ||
197 | int ret = 0; | ||
198 | |||
199 | mutex_lock(&devcgroup_mutex); | ||
200 | dev_cgroup = cgroup_to_devcgroup(cgroup); | ||
201 | if (cgroup->parent) | ||
202 | parent_dev_cgroup = cgroup_to_devcgroup(cgroup->parent); | ||
203 | |||
204 | if (parent_dev_cgroup == NULL) | ||
205 | dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; | ||
206 | else { | ||
207 | ret = dev_exceptions_copy(&dev_cgroup->exceptions, | ||
208 | &parent_dev_cgroup->exceptions); | ||
209 | if (!ret) | ||
210 | dev_cgroup->behavior = parent_dev_cgroup->behavior; | ||
211 | } | ||
212 | mutex_unlock(&devcgroup_mutex); | ||
213 | |||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | static void devcgroup_offline(struct cgroup *cgroup) | ||
218 | { | ||
219 | struct dev_cgroup *dev_cgroup = cgroup_to_devcgroup(cgroup); | ||
220 | |||
221 | mutex_lock(&devcgroup_mutex); | ||
222 | dev_cgroup->behavior = DEVCG_DEFAULT_NONE; | ||
223 | mutex_unlock(&devcgroup_mutex); | ||
224 | } | ||
225 | |||
188 | /* | 226 | /* |
189 | * called from kernel/cgroup.c with cgroup_lock() held. | 227 | * called from kernel/cgroup.c with cgroup_lock() held. |
190 | */ | 228 | */ |
191 | static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) | 229 | static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) |
192 | { | 230 | { |
193 | struct dev_cgroup *dev_cgroup, *parent_dev_cgroup; | 231 | struct dev_cgroup *dev_cgroup; |
194 | struct cgroup *parent_cgroup; | 232 | struct cgroup *parent_cgroup; |
195 | int ret; | ||
196 | 233 | ||
197 | dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); | 234 | dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); |
198 | if (!dev_cgroup) | 235 | if (!dev_cgroup) |
199 | return ERR_PTR(-ENOMEM); | 236 | return ERR_PTR(-ENOMEM); |
200 | INIT_LIST_HEAD(&dev_cgroup->exceptions); | 237 | INIT_LIST_HEAD(&dev_cgroup->exceptions); |
238 | dev_cgroup->behavior = DEVCG_DEFAULT_NONE; | ||
201 | parent_cgroup = cgroup->parent; | 239 | parent_cgroup = cgroup->parent; |
202 | 240 | ||
203 | if (parent_cgroup == NULL) | ||
204 | dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; | ||
205 | else { | ||
206 | parent_dev_cgroup = cgroup_to_devcgroup(parent_cgroup); | ||
207 | mutex_lock(&devcgroup_mutex); | ||
208 | ret = dev_exceptions_copy(&dev_cgroup->exceptions, | ||
209 | &parent_dev_cgroup->exceptions); | ||
210 | dev_cgroup->behavior = parent_dev_cgroup->behavior; | ||
211 | mutex_unlock(&devcgroup_mutex); | ||
212 | if (ret) { | ||
213 | kfree(dev_cgroup); | ||
214 | return ERR_PTR(ret); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | return &dev_cgroup->css; | 241 | return &dev_cgroup->css; |
219 | } | 242 | } |
220 | 243 | ||
@@ -587,6 +610,8 @@ struct cgroup_subsys devices_subsys = { | |||
587 | .can_attach = devcgroup_can_attach, | 610 | .can_attach = devcgroup_can_attach, |
588 | .css_alloc = devcgroup_css_alloc, | 611 | .css_alloc = devcgroup_css_alloc, |
589 | .css_free = devcgroup_css_free, | 612 | .css_free = devcgroup_css_free, |
613 | .css_online = devcgroup_online, | ||
614 | .css_offline = devcgroup_offline, | ||
590 | .subsys_id = devices_subsys_id, | 615 | .subsys_id = devices_subsys_id, |
591 | .base_cftypes = dev_cgroup_files, | 616 | .base_cftypes = dev_cgroup_files, |
592 | 617 | ||