7 #include <linux/kernel.h>
8 #include <linux/sched.h>
10 #include "vserver/context.h"
11 #include "vserver/limit.h"
12 #include "vserver/cvirt.h"
15 #define vxdprintk(x...) printk("vxd: " x)
17 #define vxdprintk(x...)
22 void free_vx_info(struct vx_info *);
24 extern int proc_pid_vx_info(struct task_struct *, char *);
27 #define get_vx_info(i) __get_vx_info(i,__FILE__,__LINE__)
29 static __inline__ struct vx_info *__get_vx_info(struct vx_info *vxi,
30 const char *_file, int _line)
34 vxdprintk("get_vx_info(%p[#%d.%d])\t%s:%d\n",
35 vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_refcount):0,
37 atomic_inc(&vxi->vx_refcount);
41 #define put_vx_info(i) __put_vx_info(i,__FILE__,__LINE__)
43 static __inline__ void __put_vx_info(struct vx_info *vxi, const char *_file, int _line)
47 vxdprintk("put_vx_info(%p[#%d.%d])\t%s:%d\n",
48 vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_refcount):0,
50 if (atomic_dec_and_lock(&vxi->vx_refcount, &vxlist_lock)) {
51 list_del(&vxi->vx_list);
52 spin_unlock(&vxlist_lock);
57 #define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__)
59 static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
60 const char *_file, int _line)
65 vxdprintk("set_vx_info(%p[#%d.%d])\t%s:%d\n",
66 vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_refcount):0,
68 *vxp = __get_vx_info(vxi, _file, _line);
71 #define clr_vx_info(p) __clr_vx_info(p,__FILE__,__LINE__)
73 static inline void __clr_vx_info(struct vx_info **vxp,
74 const char *_file, int _line)
76 struct vx_info *vxo = *vxp;
78 vxdprintk("clr_vx_info(%p[#%d.%d])\t%s:%d\n",
79 vxo, vxo?vxo->vx_id:0, vxo?atomic_read(&vxo->vx_refcount):0,
83 __put_vx_info(vxo, _file, _line);
87 #define task_get_vx_info(i) __task_get_vx_info(i,__FILE__,__LINE__)
89 static __inline__ struct vx_info *__task_get_vx_info(struct task_struct *p,
90 const char *_file, int _line)
95 vxi = __get_vx_info(p->vx_info, _file, _line);
101 #define vx_verify_info(p,i) \
102 __vx_verify_info((p)->vx_info,i,__FILE__,__LINE__)
104 static __inline__ void __vx_verify_info(
105 struct vx_info *vxa, struct vx_info *vxb,
106 const char *_file, int _line)
110 printk(KERN_ERR "vx bad assumption (%p==%p) at %s:%d\n",
111 vxa, vxb, _file, _line);
115 #define vx_task_xid(t) ((t)->xid)
117 #define vx_current_xid() vx_task_xid(current)
119 #define vx_check(c,m) __vx_check(vx_current_xid(),c,m)
121 #define vx_weak_check(c,m) ((m) ? vx_check(c,m) : 1)
125 * check current context for ADMIN/WATCH and
126 * optionally agains supplied argument
128 static __inline__ int __vx_check(xid_t cid, xid_t id, unsigned int mode)
130 if (mode & VX_ARG_MASK) {
131 if ((mode & VX_IDENT) &&
135 if (mode & VX_ATR_MASK) {
136 if ((mode & VX_DYNAMIC) &&
137 (id >= MIN_D_CONTEXT) &&
138 (id <= MAX_S_CONTEXT))
140 if ((mode & VX_STATIC) &&
141 (id > 1) && (id < MIN_D_CONTEXT))
144 return (((mode & VX_ADMIN) && (cid == 0)) ||
145 ((mode & VX_WATCH) && (cid == 1)));
149 #define __vx_flags(v,m,f) (((v) & (m)) ^ (f))
151 #define __vx_task_flags(t,m,f) \
152 (((t) && ((t)->vx_info)) ? \
153 __vx_flags((t)->vx_info->vx_flags,(m),(f)) : 0)
155 #define vx_current_flags() \
156 ((current->vx_info) ? current->vx_info->vx_flags : 0)
158 #define vx_flags(m,f) __vx_flags(vx_current_flags(),(m),(f))
161 #define vx_current_ccaps() \
162 ((current->vx_info) ? current->vx_info->vx_ccaps : 0)
164 #define vx_ccaps(c) (vx_current_ccaps() & (c))
166 #define vx_current_bcaps() \
167 (((current->vx_info) && !vx_flags(VXF_STATE_SETUP, 0)) ? \
168 current->vx_info->vx_bcaps : cap_bset)
171 #define VX_DEBUG_ACC_RSS 0
172 #define VX_DEBUG_ACC_VM 0
173 #define VX_DEBUG_ACC_VML 0
176 #if (VX_DEBUG_ACC_RSS) || (VX_DEBUG_ACC_VM) || (VX_DEBUG_ACC_VML)
177 #define vxdprintk(x...) printk("vxd: " x)
179 #define vxdprintk(x...)
182 #define vx_acc_page(m, d, v, r) \
183 __vx_acc_page(&(m->v), m->mm_vx_info, r, d, __FILE__, __LINE__)
185 static inline void __vx_acc_page(unsigned long *v, struct vx_info *vxi,
186 int res, int dir, char *file, int line)
196 atomic_inc(&vxi->limit.res[res]);
198 atomic_dec(&vxi->limit.res[res]);
203 #define vx_acc_pages(m, p, v, r) \
204 __vx_acc_pages(&(m->v), m->mm_vx_info, r, p, __FILE__, __LINE__)
206 static inline void __vx_acc_pages(unsigned long *v, struct vx_info *vxi,
207 int res, int pages, char *file, int line)
209 if ((res == RLIMIT_RSS && VX_DEBUG_ACC_RSS) ||
210 (res == RLIMIT_AS && VX_DEBUG_ACC_VM) ||
211 (res == RLIMIT_MEMLOCK && VX_DEBUG_ACC_VML))
212 vxdprintk("vx_acc_pages [%5d,%2d]: %5d += %5d in %s:%d\n",
213 (vxi?vxi->vx_id:-1), res,
214 (vxi?atomic_read(&vxi->limit.res[res]):0),
221 atomic_add(pages, &vxi->limit.res[res]);
226 #define vx_acc_vmpage(m,d) vx_acc_page(m, d, total_vm, RLIMIT_AS)
227 #define vx_acc_vmlpage(m,d) vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
228 #define vx_acc_rsspage(m,d) vx_acc_page(m, d, rss, RLIMIT_RSS)
230 #define vx_acc_vmpages(m,p) vx_acc_pages(m, p, total_vm, RLIMIT_AS)
231 #define vx_acc_vmlpages(m,p) vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
232 #define vx_acc_rsspages(m,p) vx_acc_pages(m, p, rss, RLIMIT_RSS)
234 #define vx_pages_add(s,r,p) __vx_acc_pages(0, s, r, p, __FILE__, __LINE__)
235 #define vx_pages_sub(s,r,p) __vx_pages_add(s, r, -(p))
237 #define vx_vmpages_inc(m) vx_acc_vmpage(m, 1)
238 #define vx_vmpages_dec(m) vx_acc_vmpage(m,-1)
239 #define vx_vmpages_add(m,p) vx_acc_vmpages(m, p)
240 #define vx_vmpages_sub(m,p) vx_acc_vmpages(m,-(p))
242 #define vx_vmlocked_inc(m) vx_acc_vmlpage(m, 1)
243 #define vx_vmlocked_dec(m) vx_acc_vmlpage(m,-1)
244 #define vx_vmlocked_add(m,p) vx_acc_vmlpages(m, p)
245 #define vx_vmlocked_sub(m,p) vx_acc_vmlpages(m,-(p))
247 #define vx_rsspages_inc(m) vx_acc_rsspage(m, 1)
248 #define vx_rsspages_dec(m) vx_acc_rsspage(m,-1)
249 #define vx_rsspages_add(m,p) vx_acc_rsspages(m, p)
250 #define vx_rsspages_sub(m,p) vx_acc_rsspages(m,-(p))
254 #define vx_pages_avail(m, p, r) \
255 __vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)
257 static inline int __vx_pages_avail(struct vx_info *vxi,
258 int res, int pages, char *file, int line)
260 if ((res == RLIMIT_RSS && VX_DEBUG_ACC_RSS) ||
261 (res == RLIMIT_AS && VX_DEBUG_ACC_VM) ||
262 (res == RLIMIT_MEMLOCK && VX_DEBUG_ACC_VML))
263 printk("vx_pages_avail[%5d,%2d]: %5ld > %5d + %5d in %s:%d\n",
264 (vxi?vxi->vx_id:-1), res,
265 (vxi?vxi->limit.rlim[res]:1),
266 (vxi?atomic_read(&vxi->limit.res[res]):0),
270 if (vxi->limit.rlim[res] == RLIM_INFINITY)
272 if (atomic_read(&vxi->limit.res[res]) + pages < vxi->limit.rlim[res])
277 #define vx_vmpages_avail(m,p) vx_pages_avail(m, p, RLIMIT_AS)
278 #define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
279 #define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)
283 #define VX_DEBUG_ACC_FILE 0
284 #define VX_DEBUG_ACC_OPENFD 0
287 #if (VX_DEBUG_ACC_FILE) || (VX_DEBUG_ACC_OPENFD)
288 #define vxdprintk(x...) printk("vxd: " x)
290 #define vxdprintk(x...)
294 #define vx_acc_cres(v,d,r) \
295 __vx_acc_cres((v), (r), (d), __FILE__, __LINE__)
297 static inline void __vx_acc_cres(struct vx_info *vxi,
298 int res, int dir, char *file, int line)
301 if ((res == RLIMIT_NOFILE && VX_DEBUG_ACC_FILE) ||
302 (res == RLIMIT_OPENFD && VX_DEBUG_ACC_OPENFD))
303 printk("vx_acc_cres[%5d,%2d]: %5d%s in %s:%d\n",
304 (vxi?vxi->vx_id:-1), res,
305 (vxi?atomic_read(&vxi->limit.res[res]):0),
306 (dir>0)?"++":"--", file, line);
308 atomic_inc(&vxi->limit.res[res]);
310 atomic_dec(&vxi->limit.res[res]);
314 #define vx_files_inc(f) vx_acc_cres(current->vx_info, 1, RLIMIT_NOFILE)
315 #define vx_files_dec(f) vx_acc_cres(current->vx_info,-1, RLIMIT_NOFILE)
317 #define vx_openfd_inc(f) vx_acc_cres(current->vx_info, 1, RLIMIT_OPENFD)
318 #define vx_openfd_dec(f) vx_acc_cres(current->vx_info,-1, RLIMIT_OPENFD)
320 #define vx_cres_avail(v,n,r) \
321 __vx_cres_avail((v), (r), (n), __FILE__, __LINE__)
323 static inline int __vx_cres_avail(struct vx_info *vxi,
324 int res, int num, char *file, int line)
326 if ((res == RLIMIT_NOFILE && VX_DEBUG_ACC_FILE) ||
327 (res == RLIMIT_OPENFD && VX_DEBUG_ACC_OPENFD))
328 printk("vx_cres_avail[%5d,%2d]: %5ld > %5d + %5d in %s:%d\n",
329 (vxi?vxi->vx_id:-1), res,
330 (vxi?vxi->limit.rlim[res]:1),
331 (vxi?atomic_read(&vxi->limit.res[res]):0),
335 if (vxi->limit.rlim[res] == RLIM_INFINITY)
337 if (vxi->limit.rlim[res] < atomic_read(&vxi->limit.res[res]) + num)
342 #define vx_files_avail(n) \
343 vx_cres_avail(current->vx_info, (n), RLIMIT_NOFILE)
345 #define vx_openfd_avail(n) \
346 vx_cres_avail(current->vx_info, (n), RLIMIT_OPENFD)
350 #define vx_sock_inc(f) vx_acc_cres(current->vx_info, 1, VLIMIT_SOCK)
351 #define vx_sock_dec(f) vx_acc_cres(current->vx_info,-1, VLIMIT_SOCK)
353 #define vx_sock_avail(n) \
354 vx_cres_avail(current->vx_info, (n), VLIMIT_SOCK)
358 #define FIOC_GETXFLG _IOR('x', 5, long)
359 #define FIOC_SETXFLG _IOW('x', 6, long)
361 /* utsname virtualization */
363 static inline struct new_utsname *vx_new_utsname(void)
365 if (current->vx_info)
366 return ¤t->vx_info->cvirt.utsname;
367 return &system_utsname;
370 #define vx_new_uts(x) ((vx_new_utsname())->x)
372 /* generic flag merging */
374 #define vx_mask_flags(v,f,m) (((v) & ~(m)) | ((f) & (m)))
376 #define vx_mask_mask(v,f,m) (((v) & ~(m)) | ((v) & (f) & (m)))
379 /* socket accounting */
381 #include <linux/socket.h>
383 static inline int vx_sock_type(int family)
387 if (family > 0 && family < 3)
389 else if (family == PF_INET6)
394 #define vx_acc_sock(v,f,p,s) \
395 __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)
397 static inline void __vx_acc_sock(struct vx_info *vxi,
398 int family, int pos, int size, char *file, int line)
401 int type = vx_sock_type(family);
403 atomic_inc(&vxi->cacct.sock[type][pos].count);
404 atomic_add(size, &vxi->cacct.sock[type][pos].total);
408 #define vx_sock_recv(sk,s) \
409 vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))
410 #define vx_sock_send(sk,s) \
411 vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))
412 #define vx_sock_fail(sk,s) \
413 vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))
416 #define sock_vx_init(s) do { \
418 (s)->sk_vx_info = NULL; \
422 /* pid faking stuff */
425 #define vx_map_tgid(v,p) \
426 __vx_map_tgid((v), (p), __FILE__, __LINE__)
428 static inline int __vx_map_tgid(struct vx_info *vxi, int pid,
429 char *file, int line)
431 if (vxi && __vx_flags(vxi->vx_flags, VXF_INFO_INIT, 0)) {
432 vxdprintk("vx_map_tgid: %p/%llx: %d -> %d in %s:%d\n",
433 vxi, vxi->vx_flags, pid,
434 (pid == vxi->vx_initpid)?1:pid,
436 if (pid == vxi->vx_initpid)
442 #define vx_rmap_tgid(v,p) \
443 __vx_rmap_tgid((v), (p), __FILE__, __LINE__)
445 static inline int __vx_rmap_tgid(struct vx_info *vxi, int pid,
446 char *file, int line)
448 if (vxi && __vx_flags(vxi->vx_flags, VXF_INFO_INIT, 0)) {
449 vxdprintk("vx_rmap_tgid: %p/%llx: %d -> %d in %s:%d\n",
450 vxi, vxi->vx_flags, pid,
451 (pid == 1)?vxi->vx_initpid:pid,
453 if ((pid == 1) && vxi->vx_initpid)
454 return vxi->vx_initpid;
460 #define vxdprintk(x...)