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