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