The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/ns_cgroup.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
   14 struct ns_cgroup {
   15         struct cgroup_subsys_state css;
   16 };
   17 
   18 struct cgroup_subsys ns_subsys;
   19 
   20 static 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 
   27 int 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  */
   45 static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup,
   46                          struct task_struct *task, bool threadgroup)
   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         if (threadgroup) {
   60                 struct task_struct *c;
   61                 rcu_read_lock();
   62                 list_for_each_entry_rcu(c, &task->thread_group, thread_group) {
   63                         if (!cgroup_is_descendant(new_cgroup, c)) {
   64                                 rcu_read_unlock();
   65                                 return -EPERM;
   66                         }
   67                 }
   68                 rcu_read_unlock();
   69         }
   70 
   71         return 0;
   72 }
   73 
   74 /*
   75  * Rules: you can only create a cgroup if
   76  *     1. you are capable(CAP_SYS_ADMIN)
   77  *     2. the target cgroup is a descendant of your own cgroup
   78  */
   79 static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
   80                                                 struct cgroup *cgroup)
   81 {
   82         struct ns_cgroup *ns_cgroup;
   83 
   84         if (!capable(CAP_SYS_ADMIN))
   85                 return ERR_PTR(-EPERM);
   86         if (!cgroup_is_descendant(cgroup, current))
   87                 return ERR_PTR(-EPERM);
   88 
   89         ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
   90         if (!ns_cgroup)
   91                 return ERR_PTR(-ENOMEM);
   92         return &ns_cgroup->css;
   93 }
   94 
   95 static void ns_destroy(struct cgroup_subsys *ss,
   96                         struct cgroup *cgroup)
   97 {
   98         struct ns_cgroup *ns_cgroup;
   99 
  100         ns_cgroup = cgroup_to_ns(cgroup);
  101         kfree(ns_cgroup);
  102 }
  103 
  104 struct cgroup_subsys ns_subsys = {
  105         .name = "ns",
  106         .can_attach = ns_can_attach,
  107         .create = ns_create,
  108         .destroy  = ns_destroy,
  109         .subsys_id = ns_subsys_id,
  110 };

Cache object: 7f3ccfd52bd253a86ccb5ab71969b062


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.