freezer_cg: disable writing freezer.state of root cgroup

With this change, control file 'freezer.state' doesn't exist in root
cgroup, making root cgroup unfreezable.

I think it's reasonable to disallow freeze tasks in the root cgroup.  And
then we can avoid fork overhead when freezer subsystem is compiled but not
used.

Also make writing invalid value to freezer.state returns EINVAL rather
than EIO.  This is more consistent with other cgroup subsystem.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: Paul Menage <menage@google.com>
Cc: Cedric Le Goater <clg@fr.ibm.com>
Cc: Paul Menage <menage@google.com>
Cc: Matt Helsley <matthltc@us.ibm.com>
Cc: "Serge E. Hallyn" <serue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Li Zefan 2008-11-12 13:26:50 -08:00 committed by Linus Torvalds
parent 687446760b
commit 3b1b3f6e57
2 changed files with 22 additions and 10 deletions

View file

@ -54,9 +54,12 @@ freezer.state. Writing "FROZEN" to the state file will freeze all tasks in the
cgroup. Subsequently writing "THAWED" will unfreeze the tasks in the cgroup. cgroup. Subsequently writing "THAWED" will unfreeze the tasks in the cgroup.
Reading will return the current state. Reading will return the current state.
Note freezer.state doesn't exist in root cgroup, which means root cgroup
is non-freezable.
* Examples of usage : * Examples of usage :
# mkdir /containers/freezer # mkdir /containers
# mount -t cgroup -ofreezer freezer /containers # mount -t cgroup -ofreezer freezer /containers
# mkdir /containers/0 # mkdir /containers/0
# echo $some_pid > /containers/0/tasks # echo $some_pid > /containers/0/tasks
@ -94,6 +97,6 @@ things happens:
the freezer.state file the freezer.state file
2) Userspace retries the freezing operation by writing "FROZEN" to 2) Userspace retries the freezing operation by writing "FROZEN" to
the freezer.state file (writing "FREEZING" is not legal the freezer.state file (writing "FREEZING" is not legal
and returns EIO) and returns EINVAL)
3) The tasks that blocked the cgroup from entering the "FROZEN" 3) The tasks that blocked the cgroup from entering the "FROZEN"
state disappear from the cgroup's set of tasks. state disappear from the cgroup's set of tasks.

View file

@ -192,6 +192,13 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
*/ */
freezer = task_freezer(task); freezer = task_freezer(task);
/*
* The root cgroup is non-freezable, so we can skip the
* following check.
*/
if (!freezer->css.cgroup->parent)
return;
spin_lock_irq(&freezer->lock); spin_lock_irq(&freezer->lock);
BUG_ON(freezer->state == CGROUP_FROZEN); BUG_ON(freezer->state == CGROUP_FROZEN);
@ -335,7 +342,7 @@ static int freezer_write(struct cgroup *cgroup,
else if (strcmp(buffer, freezer_state_strs[CGROUP_FROZEN]) == 0) else if (strcmp(buffer, freezer_state_strs[CGROUP_FROZEN]) == 0)
goal_state = CGROUP_FROZEN; goal_state = CGROUP_FROZEN;
else else
return -EIO; return -EINVAL;
if (!cgroup_lock_live_group(cgroup)) if (!cgroup_lock_live_group(cgroup))
return -ENODEV; return -ENODEV;
@ -354,6 +361,8 @@ static struct cftype files[] = {
static int freezer_populate(struct cgroup_subsys *ss, struct cgroup *cgroup) static int freezer_populate(struct cgroup_subsys *ss, struct cgroup *cgroup)
{ {
if (!cgroup->parent)
return 0;
return cgroup_add_files(cgroup, ss, files, ARRAY_SIZE(files)); return cgroup_add_files(cgroup, ss, files, ARRAY_SIZE(files));
} }