Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / vserver / switch.c
1 /*
2  *  linux/kernel/vserver/switch.c
3  *
4  *  Virtual Server: Syscall Switch
5  *
6  *  Copyright (C) 2003-2005  Herbert Pƶtzl
7  *
8  *  V0.01  syscall switch
9  *  V0.02  added signal to context
10  *  V0.03  added rlimit functions
11  *  V0.04  added iattr, task/xid functions
12  *  V0.05  added debug/history stuff
13  *  V0.06  added compat32 layer
14  *
15  */
16
17 #include <linux/linkage.h>
18 #include <linux/sched.h>
19 #include <linux/compat.h>
20 #include <asm/errno.h>
21
22 #include <linux/vserver/network.h>
23 #include <linux/vserver/switch.h>
24 #include <linux/vserver/debug.h>
25
26
27 static inline
28 int vc_get_version(uint32_t id)
29 {
30 #ifdef  CONFIG_VSERVER_LEGACY_VERSION
31         if (id == 63)
32                 return VCI_LEGACY_VERSION;
33 #endif
34         return VCI_VERSION;
35 }
36
37 #include <linux/vserver/context_cmd.h>
38 #include <linux/vserver/cvirt_cmd.h>
39 #include <linux/vserver/limit_cmd.h>
40 #include <linux/vserver/network_cmd.h>
41 #include <linux/vserver/sched_cmd.h>
42 #include <linux/vserver/debug_cmd.h>
43 #include <linux/vserver/inode_cmd.h>
44 #include <linux/vserver/dlimit_cmd.h>
45 #include <linux/vserver/signal_cmd.h>
46 #include <linux/vserver/namespace_cmd.h>
47
48 #include <linux/vserver/legacy.h>
49 #include <linux/vserver/inode.h>
50 #include <linux/vserver/dlimit.h>
51
52
53 #ifdef  CONFIG_COMPAT
54 #define __COMPAT(name, id, data, compat)        \
55         (compat) ? name ## _x32 (id, data) : name (id, data)
56 #else
57 #define __COMPAT(name, id, data, compat)        \
58         name (id, data)
59 #endif
60
61
62 static inline
63 long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
64 {
65         vxdprintk(VXD_CBIT(switch, 0),
66                 "vc: VCMD_%02d_%d[%d], %d,%p,%d",
67                 VC_CATEGORY(cmd), VC_COMMAND(cmd),
68                 VC_VERSION(cmd), id, data, compat);
69
70 #ifdef  CONFIG_VSERVER_LEGACY
71         if (!capable(CAP_CONTEXT) &&
72                 /* dirty hack for capremove */
73                 !(cmd==VCMD_new_s_context && id==-2))
74                 return -EPERM;
75 #else
76         if (!capable(CAP_CONTEXT))
77                 return -EPERM;
78 #endif
79
80         switch (cmd) {
81         case VCMD_get_version:
82                 return vc_get_version(id);
83
84         case VCMD_dump_history:
85 #ifdef  CONFIG_VSERVER_HISTORY
86                 return vc_dump_history(id);
87 #else
88                 return -ENOSYS;
89 #endif
90
91 #ifdef  CONFIG_VSERVER_LEGACY
92         case VCMD_new_s_context:
93                 return vc_new_s_context(id, data);
94 #endif
95 #ifdef  CONFIG_VSERVER_LEGACYNET
96         case VCMD_set_ipv4root:
97                 return vc_set_ipv4root(id, data);
98 #endif
99
100         case VCMD_task_xid:
101                 return vc_task_xid(id, data);
102         case VCMD_vx_info:
103                 return vc_vx_info(id, data);
104
105         case VCMD_task_nid:
106                 return vc_task_nid(id, data);
107         case VCMD_nx_info:
108                 return vc_nx_info(id, data);
109
110         case VCMD_set_namespace_v0:
111                 return vc_set_namespace(-1, data);
112         case VCMD_set_namespace:
113                 return vc_set_namespace(id, data);
114         case VCMD_cleanup_namespace:
115                 return vc_cleanup_namespace(id, data);
116         }
117
118         /* those are allowed while in setup too */
119         if (!vx_check(0, VX_ADMIN|VX_WATCH) &&
120                 !vx_flags(VXF_STATE_SETUP,0))
121                 return -EPERM;
122
123 #ifdef  CONFIG_VSERVER_LEGACY
124         switch (cmd) {
125         case VCMD_set_cflags:
126         case VCMD_set_ccaps:
127                 if (vx_check(0, VX_WATCH))
128                         return 0;
129         }
130 #endif
131
132         switch (cmd) {
133 #ifdef  CONFIG_IA32_EMULATION
134         case VCMD_get_rlimit:
135                 return __COMPAT(vc_get_rlimit, id, data, compat);
136         case VCMD_set_rlimit:
137                 return __COMPAT(vc_set_rlimit, id, data, compat);
138 #else
139         case VCMD_get_rlimit:
140                 return vc_get_rlimit(id, data);
141         case VCMD_set_rlimit:
142                 return vc_set_rlimit(id, data);
143 #endif
144         case VCMD_get_rlimit_mask:
145                 return vc_get_rlimit_mask(id, data);
146
147         case VCMD_get_vhi_name:
148                 return vc_get_vhi_name(id, data);
149         case VCMD_set_vhi_name:
150                 return vc_set_vhi_name(id, data);
151
152         case VCMD_set_cflags:
153                 return vc_set_cflags(id, data);
154         case VCMD_get_cflags:
155                 return vc_get_cflags(id, data);
156
157         case VCMD_set_ccaps:
158                 return vc_set_ccaps(id, data);
159         case VCMD_get_ccaps:
160                 return vc_get_ccaps(id, data);
161
162         case VCMD_set_nflags:
163                 return vc_set_nflags(id, data);
164         case VCMD_get_nflags:
165                 return vc_get_nflags(id, data);
166
167         case VCMD_set_ncaps:
168                 return vc_set_ncaps(id, data);
169         case VCMD_get_ncaps:
170                 return vc_get_ncaps(id, data);
171
172         case VCMD_set_sched_v2:
173                 return vc_set_sched_v2(id, data);
174         /* this is version 3 */
175         case VCMD_set_sched:
176                 return vc_set_sched(id, data);
177
178         case VCMD_add_dlimit:
179                 return __COMPAT(vc_add_dlimit, id, data, compat);
180         case VCMD_rem_dlimit:
181                 return __COMPAT(vc_rem_dlimit, id, data, compat);
182         case VCMD_set_dlimit:
183                 return __COMPAT(vc_set_dlimit, id, data, compat);
184         case VCMD_get_dlimit:
185                 return __COMPAT(vc_get_dlimit, id, data, compat);
186         }
187
188         /* below here only with VX_ADMIN */
189         if (!vx_check(0, VX_ADMIN|VX_WATCH))
190                 return -EPERM;
191
192         switch (cmd) {
193         case VCMD_ctx_kill:
194                 return vc_ctx_kill(id, data);
195
196         case VCMD_wait_exit:
197                 return vc_wait_exit(id, data);
198
199         case VCMD_create_context:
200 #ifdef  CONFIG_VSERVER_LEGACY
201                 return vc_ctx_create(id, NULL);
202 #else
203                 return -ENOSYS;
204 #endif
205
206         case VCMD_get_iattr:
207                 return __COMPAT(vc_get_iattr, id, data, compat);
208         case VCMD_set_iattr:
209                 return __COMPAT(vc_set_iattr, id, data, compat);
210
211         case VCMD_enter_namespace:
212                 return vc_enter_namespace(id, data);
213
214         case VCMD_ctx_create_v0:
215 #ifdef  CONFIG_VSERVER_LEGACY
216                 if (id == 1) {
217                         current->xid = 1;
218                         return 1;
219                 }
220 #endif
221                 return vc_ctx_create(id, NULL);
222         case VCMD_ctx_create:
223                 return vc_ctx_create(id, data);
224         case VCMD_ctx_migrate_v0:
225                 return vc_ctx_migrate(id, NULL);
226         case VCMD_ctx_migrate:
227                 return vc_ctx_migrate(id, data);
228
229         case VCMD_net_create_v0:
230                 return vc_net_create(id, NULL);
231         case VCMD_net_create:
232                 return vc_net_create(id, data);
233         case VCMD_net_migrate:
234                 return vc_net_migrate(id, data);
235         case VCMD_net_add:
236                 return vc_net_add(id, data);
237         case VCMD_net_remove:
238                 return vc_net_remove(id, data);
239
240         }
241         return -ENOSYS;
242 }
243
244 extern asmlinkage long
245 sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
246 {
247         long ret = do_vserver(cmd, id, data, 0);
248
249         vxdprintk(VXD_CBIT(switch, 1),
250                 "vc: VCMD_%02d_%d[%d] = %08lx(%ld)",
251                 VC_CATEGORY(cmd), VC_COMMAND(cmd),
252                 VC_VERSION(cmd), ret, ret);
253         return ret;
254 }
255
256 #ifdef  CONFIG_COMPAT
257
258 extern asmlinkage long
259 sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
260 {
261         long ret = do_vserver(cmd, id, data, 1);
262
263         vxdprintk(VXD_CBIT(switch, 1),
264                 "vc: VCMD_%02d_%d[%d] = %08lx(%ld)",
265                 VC_CATEGORY(cmd), VC_COMMAND(cmd),
266                 VC_VERSION(cmd), ret, ret);
267         return ret;
268 }
269
270 #endif  /* CONFIG_COMPAT */