OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [kernel/] [nsproxy.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  Copyright (C) 2006 IBM Corporation
3
 *
4
 *  Author: Serge Hallyn <serue@us.ibm.com>
5
 *
6
 *  This program is free software; you can redistribute it and/or
7
 *  modify it under the terms of the GNU General Public License as
8
 *  published by the Free Software Foundation, version 2 of the
9
 *  License.
10
 *
11
 *  Jun 2006 - namespaces support
12
 *             OpenVZ, SWsoft Inc.
13
 *             Pavel Emelianov <xemul@openvz.org>
14
 */
15
 
16
#include <linux/module.h>
17
#include <linux/version.h>
18
#include <linux/nsproxy.h>
19
#include <linux/init_task.h>
20
#include <linux/mnt_namespace.h>
21
#include <linux/utsname.h>
22
#include <linux/pid_namespace.h>
23
#include <net/net_namespace.h>
24
 
25
static struct kmem_cache *nsproxy_cachep;
26
 
27
struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
28
 
29
/*
30
 * creates a copy of "orig" with refcount 1.
31
 */
32
static inline struct nsproxy *clone_nsproxy(struct nsproxy *orig)
33
{
34
        struct nsproxy *ns;
35
 
36
        ns = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
37
        if (ns) {
38
                memcpy(ns, orig, sizeof(struct nsproxy));
39
                atomic_set(&ns->count, 1);
40
        }
41
        return ns;
42
}
43
 
44
/*
45
 * Create new nsproxy and all of its the associated namespaces.
46
 * Return the newly created nsproxy.  Do not attach this to the task,
47
 * leave it to the caller to do proper locking and attach it to task.
48
 */
49
static struct nsproxy *create_new_namespaces(unsigned long flags,
50
                        struct task_struct *tsk, struct fs_struct *new_fs)
51
{
52
        struct nsproxy *new_nsp;
53
        int err;
54
 
55
        new_nsp = clone_nsproxy(tsk->nsproxy);
56
        if (!new_nsp)
57
                return ERR_PTR(-ENOMEM);
58
 
59
        new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
60
        if (IS_ERR(new_nsp->mnt_ns)) {
61
                err = PTR_ERR(new_nsp->mnt_ns);
62
                goto out_ns;
63
        }
64
 
65
        new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
66
        if (IS_ERR(new_nsp->uts_ns)) {
67
                err = PTR_ERR(new_nsp->uts_ns);
68
                goto out_uts;
69
        }
70
 
71
        new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
72
        if (IS_ERR(new_nsp->ipc_ns)) {
73
                err = PTR_ERR(new_nsp->ipc_ns);
74
                goto out_ipc;
75
        }
76
 
77
        new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
78
        if (IS_ERR(new_nsp->pid_ns)) {
79
                err = PTR_ERR(new_nsp->pid_ns);
80
                goto out_pid;
81
        }
82
 
83
        new_nsp->user_ns = copy_user_ns(flags, tsk->nsproxy->user_ns);
84
        if (IS_ERR(new_nsp->user_ns)) {
85
                err = PTR_ERR(new_nsp->user_ns);
86
                goto out_user;
87
        }
88
 
89
        new_nsp->net_ns = copy_net_ns(flags, tsk->nsproxy->net_ns);
90
        if (IS_ERR(new_nsp->net_ns)) {
91
                err = PTR_ERR(new_nsp->net_ns);
92
                goto out_net;
93
        }
94
 
95
        return new_nsp;
96
 
97
out_net:
98
        if (new_nsp->user_ns)
99
                put_user_ns(new_nsp->user_ns);
100
out_user:
101
        if (new_nsp->pid_ns)
102
                put_pid_ns(new_nsp->pid_ns);
103
out_pid:
104
        if (new_nsp->ipc_ns)
105
                put_ipc_ns(new_nsp->ipc_ns);
106
out_ipc:
107
        if (new_nsp->uts_ns)
108
                put_uts_ns(new_nsp->uts_ns);
109
out_uts:
110
        if (new_nsp->mnt_ns)
111
                put_mnt_ns(new_nsp->mnt_ns);
112
out_ns:
113
        kmem_cache_free(nsproxy_cachep, new_nsp);
114
        return ERR_PTR(err);
115
}
116
 
117
/*
118
 * called from clone.  This now handles copy for nsproxy and all
119
 * namespaces therein.
120
 */
121
int copy_namespaces(unsigned long flags, struct task_struct *tsk)
122
{
123
        struct nsproxy *old_ns = tsk->nsproxy;
124
        struct nsproxy *new_ns;
125
        int err = 0;
126
 
127
        if (!old_ns)
128
                return 0;
129
 
130
        get_nsproxy(old_ns);
131
 
132
        if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
133
                                CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
134
                return 0;
135
 
136
        if (!capable(CAP_SYS_ADMIN)) {
137
                err = -EPERM;
138
                goto out;
139
        }
140
 
141
        new_ns = create_new_namespaces(flags, tsk, tsk->fs);
142
        if (IS_ERR(new_ns)) {
143
                err = PTR_ERR(new_ns);
144
                goto out;
145
        }
146
 
147
        err = ns_cgroup_clone(tsk);
148
        if (err) {
149
                put_nsproxy(new_ns);
150
                goto out;
151
        }
152
 
153
        tsk->nsproxy = new_ns;
154
 
155
out:
156
        put_nsproxy(old_ns);
157
        return err;
158
}
159
 
160
void free_nsproxy(struct nsproxy *ns)
161
{
162
        if (ns->mnt_ns)
163
                put_mnt_ns(ns->mnt_ns);
164
        if (ns->uts_ns)
165
                put_uts_ns(ns->uts_ns);
166
        if (ns->ipc_ns)
167
                put_ipc_ns(ns->ipc_ns);
168
        if (ns->pid_ns)
169
                put_pid_ns(ns->pid_ns);
170
        if (ns->user_ns)
171
                put_user_ns(ns->user_ns);
172
        put_net(ns->net_ns);
173
        kmem_cache_free(nsproxy_cachep, ns);
174
}
175
 
176
/*
177
 * Called from unshare. Unshare all the namespaces part of nsproxy.
178
 * On success, returns the new nsproxy.
179
 */
180
int unshare_nsproxy_namespaces(unsigned long unshare_flags,
181
                struct nsproxy **new_nsp, struct fs_struct *new_fs)
182
{
183
        int err = 0;
184
 
185
        if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
186
                               CLONE_NEWUSER | CLONE_NEWNET)))
187
                return 0;
188
 
189
        if (!capable(CAP_SYS_ADMIN))
190
                return -EPERM;
191
 
192
        *new_nsp = create_new_namespaces(unshare_flags, current,
193
                                new_fs ? new_fs : current->fs);
194
        if (IS_ERR(*new_nsp)) {
195
                err = PTR_ERR(*new_nsp);
196
                goto out;
197
        }
198
 
199
        err = ns_cgroup_clone(current);
200
        if (err)
201
                put_nsproxy(*new_nsp);
202
 
203
out:
204
        return err;
205
}
206
 
207
void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
208
{
209
        struct nsproxy *ns;
210
 
211
        might_sleep();
212
 
213
        ns = p->nsproxy;
214
 
215
        rcu_assign_pointer(p->nsproxy, new);
216
 
217
        if (ns && atomic_dec_and_test(&ns->count)) {
218
                /*
219
                 * wait for others to get what they want from this nsproxy.
220
                 *
221
                 * cannot release this nsproxy via the call_rcu() since
222
                 * put_mnt_ns() will want to sleep
223
                 */
224
                synchronize_rcu();
225
                free_nsproxy(ns);
226
        }
227
}
228
 
229
void exit_task_namespaces(struct task_struct *p)
230
{
231
        switch_task_namespaces(p, NULL);
232
}
233
 
234
static int __init nsproxy_cache_init(void)
235
{
236
        nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
237
        return 0;
238
}
239
 
240
module_init(nsproxy_cache_init);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.