linux/kernel/ns_cgroup.c
<<
>>
Prefs
   1/*
   2 * ns_cgroup.c - namespace cgroup subsystem
   3 *
   4 * Copyright 2006, 2007 IBM Corp
   5 */
   6
   7#include <linux/module.h>
   8#include <linux/cgroup.h>
   9#include <linux/fs.h>
  10
  11struct ns_cgroup {
  12        struct cgroup_subsys_state css;
  13        spinlock_t lock;
  14};
  15
  16struct cgroup_subsys ns_subsys;
  17
  18static inline struct ns_cgroup *cgroup_to_ns(
  19                struct cgroup *cgroup)
  20{
  21        return container_of(cgroup_subsys_state(cgroup, ns_subsys_id),
  22                            struct ns_cgroup, css);
  23}
  24
  25int ns_cgroup_clone(struct task_struct *task)
  26{
  27        return cgroup_clone(task, &ns_subsys);
  28}
  29
  30/*
  31 * Rules:
  32 *   1. you can only enter a cgroup which is a child of your current
  33 *     cgroup
  34 *   2. you can only place another process into a cgroup if
  35 *     a. you have CAP_SYS_ADMIN
  36 *     b. your cgroup is an ancestor of task's destination cgroup
  37 *       (hence either you are in the same cgroup as task, or in an
  38 *        ancestor cgroup thereof)
  39 */
  40static int ns_can_attach(struct cgroup_subsys *ss,
  41                struct cgroup *new_cgroup, struct task_struct *task)
  42{
  43        struct cgroup *orig;
  44
  45        if (current != task) {
  46                if (!capable(CAP_SYS_ADMIN))
  47                        return -EPERM;
  48
  49                if (!cgroup_is_descendant(new_cgroup))
  50                        return -EPERM;
  51        }
  52
  53        if (atomic_read(&new_cgroup->count) != 0)
  54                return -EPERM;
  55
  56        orig = task_cgroup(task, ns_subsys_id);
  57        if (orig && orig != new_cgroup->parent)
  58                return -EPERM;
  59
  60        return 0;
  61}
  62
  63/*
  64 * Rules: you can only create a cgroup if
  65 *     1. you are capable(CAP_SYS_ADMIN)
  66 *     2. the target cgroup is a descendant of your own cgroup
  67 */
  68static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
  69                                                struct cgroup *cgroup)
  70{
  71        struct ns_cgroup *ns_cgroup;
  72
  73        if (!capable(CAP_SYS_ADMIN))
  74                return ERR_PTR(-EPERM);
  75        if (!cgroup_is_descendant(cgroup))
  76                return ERR_PTR(-EPERM);
  77
  78        ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
  79        if (!ns_cgroup)
  80                return ERR_PTR(-ENOMEM);
  81        spin_lock_init(&ns_cgroup->lock);
  82        return &ns_cgroup->css;
  83}
  84
  85static void ns_destroy(struct cgroup_subsys *ss,
  86                        struct cgroup *cgroup)
  87{
  88        struct ns_cgroup *ns_cgroup;
  89
  90        ns_cgroup = cgroup_to_ns(cgroup);
  91        kfree(ns_cgroup);
  92}
  93
  94struct cgroup_subsys ns_subsys = {
  95        .name = "ns",
  96        .can_attach = ns_can_attach,
  97        .create = ns_create,
  98        .destroy  = ns_destroy,
  99        .subsys_id = ns_subsys_id,
 100};
 101