2 * linux/kernel/vserver/limit.c
4 * Virtual Server: Context Limits
6 * Copyright (C) 2004-2005 Herbert Pƶtzl
8 * V0.01 broken out from vcontext V0.05
12 #include <linux/module.h>
13 #include <linux/vs_base.h>
14 #include <linux/vs_context.h>
15 #include <linux/vs_limit.h>
16 #include <linux/vserver/switch.h>
17 #include <linux/vserver/limit_cmd.h>
19 #include <asm/errno.h>
20 #include <asm/uaccess.h>
23 const char *vlimit_name[NUM_LIMITS] = {
26 [RLIMIT_NPROC] = "NPROC",
27 [RLIMIT_NOFILE] = "NOFILE",
28 [RLIMIT_MEMLOCK] = "VML",
30 [RLIMIT_LOCKS] = "LOCKS",
31 [RLIMIT_SIGPENDING] = "SIGP",
32 [RLIMIT_MSGQUEUE] = "MSGQ",
34 [VLIMIT_NSOCK] = "NSOCK",
35 [VLIMIT_OPENFD] = "OPENFD",
36 [VLIMIT_ANON] = "ANON",
37 [VLIMIT_SHMEM] = "SHMEM",
40 EXPORT_SYMBOL_GPL(vlimit_name);
43 static int is_valid_rlimit(int id)
64 static inline uint64_t vc_get_rlim(struct vx_info *vxi, int id)
68 limit = vxi->limit.rlim[id];
69 if (limit == RLIM_INFINITY)
70 return CRLIM_INFINITY;
74 static int do_get_rlimit(xid_t xid, uint32_t id,
75 uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum)
79 if (!is_valid_rlimit(id))
82 vxi = lookup_vx_info(xid);
87 *minimum = CRLIM_UNSET;
89 *softlimit = CRLIM_UNSET;
91 *maximum = vc_get_rlim(vxi, id);
96 int vc_get_rlimit(uint32_t id, void __user *data)
98 struct vcmd_ctx_rlimit_v0 vc_data;
101 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
104 ret = do_get_rlimit(id, vc_data.id,
105 &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
109 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
114 static int do_set_rlimit(xid_t xid, uint32_t id,
115 uint64_t minimum, uint64_t softlimit, uint64_t maximum)
119 if (!is_valid_rlimit(id))
122 vxi = lookup_vx_info(xid);
126 if (maximum != CRLIM_KEEP)
127 vxi->limit.rlim[id] = maximum;
133 int vc_set_rlimit(uint32_t id, void __user *data)
135 struct vcmd_ctx_rlimit_v0 vc_data;
137 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE))
139 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
142 return do_set_rlimit(id, vc_data.id,
143 vc_data.minimum, vc_data.softlimit, vc_data.maximum);
146 #ifdef CONFIG_IA32_EMULATION
148 int vc_set_rlimit_x32(uint32_t id, void __user *data)
150 struct vcmd_ctx_rlimit_v0_x32 vc_data;
152 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE))
154 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
157 return do_set_rlimit(id, vc_data.id,
158 vc_data.minimum, vc_data.softlimit, vc_data.maximum);
161 int vc_get_rlimit_x32(uint32_t id, void __user *data)
163 struct vcmd_ctx_rlimit_v0_x32 vc_data;
166 if (copy_from_user (&vc_data, data, sizeof(vc_data)))
169 ret = do_get_rlimit(id, vc_data.id,
170 &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum);
174 if (copy_to_user (data, &vc_data, sizeof(vc_data)))
179 #endif /* CONFIG_IA32_EMULATION */
182 int vc_get_rlimit_mask(uint32_t id, void __user *data)
184 static struct vcmd_ctx_rlimit_mask_v0 mask = {
191 (1 << RLIMIT_NPROC) |
192 (1 << RLIMIT_NOFILE) |
193 (1 << RLIMIT_MEMLOCK) |
194 (1 << RLIMIT_LOCKS) |
200 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE))
202 if (copy_to_user(data, &mask, sizeof(mask)))
208 void vx_vsi_meminfo(struct sysinfo *val)
210 struct vx_info *vxi = current->vx_info;
213 v = vxi->limit.rlim[RLIMIT_RSS];
214 if (v != RLIM_INFINITY)
215 val->totalram = min(val->totalram, v);
216 v = atomic_read(&vxi->limit.rcur[RLIMIT_RSS]);
217 val->freeram = (v < val->totalram) ? val->totalram - v : 0;
224 void vx_vsi_swapinfo(struct sysinfo *val)
226 struct vx_info *vxi = current->vx_info;
229 v = vxi->limit.rlim[RLIMIT_RSS];
230 w = vxi->limit.rlim[RLIMIT_AS];
231 if (w != RLIM_INFINITY)
232 val->totalswap = min(val->totalswap, w -
233 ((v != RLIM_INFINITY) ? v : 0));
234 w = atomic_read(&vxi->limit.rcur[RLIMIT_AS]);
235 val->freeswap = (w < val->totalswap) ? val->totalswap - w : 0;