Merge to Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.13-vs2...
[linux-2.6.git] / kernel / vserver / namespace.c
1 /*
2  *  linux/kernel/vserver/namespace.c
3  *
4  *  Virtual Server: Context Namespace Support
5  *
6  *  Copyright (C) 2003-2005  Herbert Pƶtzl
7  *
8  *  V0.01  broken out from context.c 0.07
9  *  V0.02  added task locking for namespace
10  *
11  */
12
13 #include <linux/utsname.h>
14 #include <linux/sched.h>
15 #include <linux/vs_context.h>
16 #include <linux/vserver/namespace.h>
17 #include <linux/vserver/namespace_cmd.h>
18 #include <linux/dcache.h>
19 #include <linux/mount.h>
20 #include <linux/fs.h>
21
22 #include <asm/errno.h>
23 #include <asm/uaccess.h>
24
25
26 /* namespace functions */
27
28 #include <linux/namespace.h>
29
30 int vx_set_namespace(struct vx_info *vxi, struct namespace *ns, struct fs_struct *fs)
31 {
32         struct fs_struct *fs_copy;
33
34         if (vxi->vx_namespace)
35                 return -EPERM;
36         if (!ns || !fs)
37                 return -EINVAL;
38
39         fs_copy = copy_fs_struct(fs);
40         if (!fs_copy)
41                 return -ENOMEM;
42
43         get_namespace(ns);
44         vxi->vx_namespace = ns;
45         vxi->vx_fs = fs_copy;
46         return 0;
47 }
48
49 int vc_enter_namespace(uint32_t id, void __user *data)
50 {
51         struct vx_info *vxi;
52         struct fs_struct *old_fs, *fs;
53         struct namespace *old_ns;
54         int ret = 0;
55
56         if (!vx_check(0, VX_ADMIN))
57                 return -ENOSYS;
58
59         vxi = lookup_vx_info(id);
60         if (!vxi)
61                 return -ESRCH;
62
63         ret = -EINVAL;
64         if (!vxi->vx_namespace)
65                 goto out_put;
66
67         ret = -ENOMEM;
68         fs = copy_fs_struct(vxi->vx_fs);
69         if (!fs)
70                 goto out_put;
71
72         ret = 0;
73         task_lock(current);
74         old_ns = current->namespace;
75         old_fs = current->fs;
76         get_namespace(vxi->vx_namespace);
77         current->namespace = vxi->vx_namespace;
78         current->fs = fs;
79         task_unlock(current);
80
81         put_namespace(old_ns);
82         put_fs_struct(old_fs);
83 out_put:
84         put_vx_info(vxi);
85         return ret;
86 }
87
88 int vc_set_namespace(uint32_t id, void __user *data)
89 {
90         struct fs_struct *fs;
91         struct namespace *ns;
92         struct vx_info *vxi;
93         int ret;
94
95         vxi = lookup_vx_info(id);
96         if (!vxi)
97                 return -ESRCH;
98
99         task_lock(current);
100         fs = current->fs;
101         atomic_inc(&fs->count);
102         ns = current->namespace;
103         get_namespace(current->namespace);
104         task_unlock(current);
105
106         ret = vx_set_namespace(vxi, ns, fs);
107
108         put_namespace(ns);
109         put_fs_struct(fs);
110         put_vx_info(vxi);
111         return ret;
112 }
113