vserver 2.0-pre4
[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/config.h>
18 #include <linux/linkage.h>
19 #include <linux/sched.h>
20 #include <linux/compat.h>
21 #include <asm/errno.h>
22
23 #include <linux/vserver/network.h>
24 #include <linux/vserver/switch.h>
25 #include <linux/vserver/debug.h>
26
27
28 static inline
29 int vc_get_version(uint32_t id)
30 {
31         return VCI_VERSION;
32 }
33
34 #include <linux/vserver/context_cmd.h>
35 #include <linux/vserver/cvirt_cmd.h>
36 #include <linux/vserver/limit_cmd.h>
37 #include <linux/vserver/network_cmd.h>
38 #include <linux/vserver/sched_cmd.h>
39 #include <linux/vserver/debug_cmd.h>
40 #include <linux/vserver/inode_cmd.h>
41 #include <linux/vserver/dlimit_cmd.h>
42 #include <linux/vserver/signal_cmd.h>
43
44 #include <linux/vserver/legacy.h>
45 #include <linux/vserver/namespace.h>
46 #include <linux/vserver/inode.h>
47 #include <linux/vserver/dlimit.h>
48
49
50 #ifdef  CONFIG_COMPAT
51 #define __COMPAT(name, id, data, compat)        \
52         (compat) ? name ## _x32 (id, data) : name (id, data)
53 #else
54 #define __COMPAT(name, id, data, compat)        \
55         name (id, data)
56 #endif
57
58
59 static inline
60 long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat)
61 {
62         vxdprintk(VXD_CBIT(switch, 0),
63                 "vc: VCMD_%02d_%d[%d], %d,%p,%d",
64                 VC_CATEGORY(cmd), VC_COMMAND(cmd),
65                 VC_VERSION(cmd), id, data, compat);
66
67 #ifdef  CONFIG_VSERVER_LEGACY
68         if (!capable(CAP_CONTEXT) &&
69                 /* dirty hack for capremove */
70                 !(cmd==VCMD_new_s_context && id==-2))
71                 return -EPERM;
72 #else
73         if (!capable(CAP_CONTEXT))
74                 return -EPERM;
75 #endif
76
77         switch (cmd) {
78         case VCMD_get_version:
79                 return vc_get_version(id);
80
81         case VCMD_dump_history:
82 #ifdef  CONFIG_VSERVER_HISTORY
83                 return vc_dump_history(id);
84 #else
85                 return -ENOSYS;
86 #endif
87
88 #ifdef  CONFIG_VSERVER_LEGACY
89         case VCMD_new_s_context:
90                 return vc_new_s_context(id, data);
91 #endif
92 #ifdef  CONFIG_VSERVER_LEGACYNET
93         case VCMD_set_ipv4root:
94                 return vc_set_ipv4root(id, data);
95 #endif
96
97         case VCMD_task_xid:
98                 return vc_task_xid(id, data);
99         case VCMD_vx_info:
100                 return vc_vx_info(id, data);
101
102         case VCMD_task_nid:
103                 return vc_task_nid(id, data);
104         case VCMD_nx_info:
105                 return vc_nx_info(id, data);
106
107         case VCMD_set_namespace:
108                 return vc_set_namespace(id, data);
109         case VCMD_cleanup_namespace:
110                 return vc_cleanup_namespace(id, data);
111         }
112
113         /* those are allowed while in setup too */
114         if (!vx_check(0, VX_ADMIN|VX_WATCH) &&
115                 !vx_flags(VXF_STATE_SETUP,0))
116                 return -EPERM;
117
118 #ifdef  CONFIG_VSERVER_LEGACY
119         switch (cmd) {
120         case VCMD_set_cflags:
121         case VCMD_set_ccaps:
122                 if (vx_check(0, VX_WATCH))
123                         return 0;
124         }
125 #endif
126
127         switch (cmd) {
128         case VCMD_get_rlimit:
129                 return vc_get_rlimit(id, data);
130         case VCMD_set_rlimit:
131                 return vc_set_rlimit(id, data);
132         case VCMD_get_rlimit_mask:
133                 return vc_get_rlimit_mask(id, data);
134
135         case VCMD_vx_get_vhi_name:
136                 return vc_get_vhi_name(id, data);
137         case VCMD_vx_set_vhi_name:
138                 return vc_set_vhi_name(id, data);
139
140         case VCMD_set_cflags:
141                 return vc_set_cflags(id, data);
142         case VCMD_get_cflags:
143                 return vc_get_cflags(id, data);
144
145         case VCMD_set_ccaps:
146                 return vc_set_ccaps(id, data);
147         case VCMD_get_ccaps:
148                 return vc_get_ccaps(id, data);
149
150         case VCMD_set_nflags:
151                 return vc_set_nflags(id, data);
152         case VCMD_get_nflags:
153                 return vc_get_nflags(id, data);
154
155         case VCMD_set_ncaps:
156                 return vc_set_ncaps(id, data);
157         case VCMD_get_ncaps:
158                 return vc_get_ncaps(id, data);
159
160         case VCMD_set_sched_v2:
161                 return vc_set_sched_v2(id, data);
162         /* this is version 3 */
163         case VCMD_set_sched:
164                 return vc_set_sched(id, data);
165
166         case VCMD_add_dlimit:
167                 return __COMPAT(vc_add_dlimit, id, data, compat);
168         case VCMD_rem_dlimit:
169                 return __COMPAT(vc_rem_dlimit, id, data, compat);
170         case VCMD_set_dlimit:
171                 return __COMPAT(vc_set_dlimit, id, data, compat);
172         case VCMD_get_dlimit:
173                 return __COMPAT(vc_get_dlimit, id, data, compat);
174         }
175
176         /* below here only with VX_ADMIN */
177         if (!vx_check(0, VX_ADMIN|VX_WATCH))
178                 return -EPERM;
179
180         switch (cmd) {
181         case VCMD_ctx_kill:
182                 return vc_ctx_kill(id, data);
183
184         case VCMD_wait_exit:
185                 return vc_wait_exit(id, data);
186
187         case VCMD_create_context:
188 #ifdef  CONFIG_VSERVER_LEGACY
189                 return vc_ctx_create(id, data);
190 #else
191                 return -ENOSYS;
192 #endif
193
194         case VCMD_get_iattr:
195                 return __COMPAT(vc_get_iattr, id, data, compat);
196         case VCMD_set_iattr:
197                 return __COMPAT(vc_set_iattr, id, data, compat);
198
199         case VCMD_enter_namespace:
200                 return vc_enter_namespace(id, data);
201
202         case VCMD_ctx_create:
203 #ifdef  CONFIG_VSERVER_LEGACY
204                 if (id == 1) {
205                         current->xid = 1;
206                         return 1;
207                 }
208 #endif
209                 return vc_ctx_create(id, data);
210         case VCMD_ctx_migrate:
211                 return vc_ctx_migrate(id, data);
212
213         case VCMD_net_create:
214                 return vc_net_create(id, data);
215         case VCMD_net_migrate:
216                 return vc_net_migrate(id, data);
217
218         }
219         return -ENOSYS;
220 }
221
222 extern asmlinkage long
223 sys_vserver(uint32_t cmd, uint32_t id, void __user *data)
224 {
225         return do_vserver(cmd, id, data, 0);
226 }
227
228 #ifdef  CONFIG_COMPAT
229
230 extern asmlinkage long
231 sys32_vserver(uint32_t cmd, uint32_t id, void __user *data)
232 {
233         return do_vserver(cmd, id, data, 1);
234 }
235
236 #endif  /* CONFIG_COMPAT */