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