Root/kernel/pid_namespace.c

1/*
2 * Pid namespaces
3 *
4 * Authors:
5 * (C) 2007 Pavel Emelyanov <xemul@openvz.org>, OpenVZ, SWsoft Inc.
6 * (C) 2007 Sukadev Bhattiprolu <sukadev@us.ibm.com>, IBM
7 * Many thanks to Oleg Nesterov for comments and help
8 *
9 */
10
11#include <linux/pid.h>
12#include <linux/pid_namespace.h>
13#include <linux/syscalls.h>
14#include <linux/err.h>
15#include <linux/acct.h>
16#include <linux/slab.h>
17#include <linux/proc_fs.h>
18
19#define BITS_PER_PAGE (PAGE_SIZE*8)
20
21struct pid_cache {
22    int nr_ids;
23    char name[16];
24    struct kmem_cache *cachep;
25    struct list_head list;
26};
27
28static LIST_HEAD(pid_caches_lh);
29static DEFINE_MUTEX(pid_caches_mutex);
30static struct kmem_cache *pid_ns_cachep;
31
32/*
33 * creates the kmem cache to allocate pids from.
34 * @nr_ids: the number of numerical ids this pid will have to carry
35 */
36
37static struct kmem_cache *create_pid_cachep(int nr_ids)
38{
39    struct pid_cache *pcache;
40    struct kmem_cache *cachep;
41
42    mutex_lock(&pid_caches_mutex);
43    list_for_each_entry(pcache, &pid_caches_lh, list)
44        if (pcache->nr_ids == nr_ids)
45            goto out;
46
47    pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
48    if (pcache == NULL)
49        goto err_alloc;
50
51    snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
52    cachep = kmem_cache_create(pcache->name,
53            sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid),
54            0, SLAB_HWCACHE_ALIGN, NULL);
55    if (cachep == NULL)
56        goto err_cachep;
57
58    pcache->nr_ids = nr_ids;
59    pcache->cachep = cachep;
60    list_add(&pcache->list, &pid_caches_lh);
61out:
62    mutex_unlock(&pid_caches_mutex);
63    return pcache->cachep;
64
65err_cachep:
66    kfree(pcache);
67err_alloc:
68    mutex_unlock(&pid_caches_mutex);
69    return NULL;
70}
71
72static struct pid_namespace *create_pid_namespace(struct pid_namespace *parent_pid_ns)
73{
74    struct pid_namespace *ns;
75    unsigned int level = parent_pid_ns->level + 1;
76    int i, err = -ENOMEM;
77
78    ns = kmem_cache_zalloc(pid_ns_cachep, GFP_KERNEL);
79    if (ns == NULL)
80        goto out;
81
82    ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
83    if (!ns->pidmap[0].page)
84        goto out_free;
85
86    ns->pid_cachep = create_pid_cachep(level + 1);
87    if (ns->pid_cachep == NULL)
88        goto out_free_map;
89
90    kref_init(&ns->kref);
91    ns->level = level;
92    ns->parent = get_pid_ns(parent_pid_ns);
93
94    set_bit(0, ns->pidmap[0].page);
95    atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
96
97    for (i = 1; i < PIDMAP_ENTRIES; i++)
98        atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
99
100    err = pid_ns_prepare_proc(ns);
101    if (err)
102        goto out_put_parent_pid_ns;
103
104    return ns;
105
106out_put_parent_pid_ns:
107    put_pid_ns(parent_pid_ns);
108out_free_map:
109    kfree(ns->pidmap[0].page);
110out_free:
111    kmem_cache_free(pid_ns_cachep, ns);
112out:
113    return ERR_PTR(err);
114}
115
116static void destroy_pid_namespace(struct pid_namespace *ns)
117{
118    int i;
119
120    for (i = 0; i < PIDMAP_ENTRIES; i++)
121        kfree(ns->pidmap[i].page);
122    kmem_cache_free(pid_ns_cachep, ns);
123}
124
125struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
126{
127    if (!(flags & CLONE_NEWPID))
128        return get_pid_ns(old_ns);
129    if (flags & (CLONE_THREAD|CLONE_PARENT))
130        return ERR_PTR(-EINVAL);
131    return create_pid_namespace(old_ns);
132}
133
134void free_pid_ns(struct kref *kref)
135{
136    struct pid_namespace *ns, *parent;
137
138    ns = container_of(kref, struct pid_namespace, kref);
139
140    parent = ns->parent;
141    destroy_pid_namespace(ns);
142
143    if (parent != NULL)
144        put_pid_ns(parent);
145}
146
147void zap_pid_ns_processes(struct pid_namespace *pid_ns)
148{
149    int nr;
150    int rc;
151    struct task_struct *task;
152
153    /*
154     * The last thread in the cgroup-init thread group is terminating.
155     * Find remaining pid_ts in the namespace, signal and wait for them
156     * to exit.
157     *
158     * Note: This signals each threads in the namespace - even those that
159     * belong to the same thread group, To avoid this, we would have
160     * to walk the entire tasklist looking a processes in this
161     * namespace, but that could be unnecessarily expensive if the
162     * pid namespace has just a few processes. Or we need to
163     * maintain a tasklist for each pid namespace.
164     *
165     */
166    read_lock(&tasklist_lock);
167    nr = next_pidmap(pid_ns, 1);
168    while (nr > 0) {
169        rcu_read_lock();
170
171        /*
172         * Any nested-container's init processes won't ignore the
173         * SEND_SIG_NOINFO signal, see send_signal()->si_fromuser().
174         */
175        task = pid_task(find_vpid(nr), PIDTYPE_PID);
176        if (task)
177            send_sig_info(SIGKILL, SEND_SIG_NOINFO, task);
178
179        rcu_read_unlock();
180
181        nr = next_pidmap(pid_ns, nr);
182    }
183    read_unlock(&tasklist_lock);
184
185    do {
186        clear_thread_flag(TIF_SIGPENDING);
187        rc = sys_wait4(-1, NULL, __WALL, NULL);
188    } while (rc != -ECHILD);
189
190    acct_exit_ns(pid_ns);
191    return;
192}
193
194static __init int pid_namespaces_init(void)
195{
196    pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
197    return 0;
198}
199
200__initcall(pid_namespaces_init);
201

Archive Download this file



interactive