X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Flimit.c;fp=kernel%2Fvserver%2Flimit.c;h=18dba6c70fa0bc84f49fb364ffa24e15b66b1276;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=0527afc672b4c90d6d27f6e4b733d20855c622cc;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/kernel/vserver/limit.c b/kernel/vserver/limit.c index 0527afc67..18dba6c70 100644 --- a/kernel/vserver/limit.c +++ b/kernel/vserver/limit.c @@ -9,7 +9,6 @@ * */ -#include #include #include #include @@ -46,18 +45,18 @@ static int is_valid_rlimit(int id) int valid = 0; switch (id) { - case RLIMIT_RSS: - case RLIMIT_NPROC: - case RLIMIT_NOFILE: - case RLIMIT_MEMLOCK: - case RLIMIT_AS: - - case VLIMIT_NSOCK: - case VLIMIT_OPENFD: - case VLIMIT_ANON: - case VLIMIT_SHMEM: - valid = 1; - break; + case RLIMIT_RSS: + case RLIMIT_NPROC: + case RLIMIT_NOFILE: + case RLIMIT_MEMLOCK: + case RLIMIT_AS: + + case VLIMIT_NSOCK: + case VLIMIT_OPENFD: + case VLIMIT_ANON: + case VLIMIT_SHMEM: + valid = 1; + break; } return valid; } @@ -72,53 +71,114 @@ static inline uint64_t vc_get_rlim(struct vx_info *vxi, int id) return limit; } -int vc_get_rlimit(uint32_t id, void __user *data) +static int do_get_rlimit(xid_t xid, uint32_t id, + uint64_t *minimum, uint64_t *softlimit, uint64_t *maximum) { struct vx_info *vxi; - struct vcmd_ctx_rlimit_v0 vc_data; - if (copy_from_user (&vc_data, data, sizeof(vc_data))) - return -EFAULT; - if (!is_valid_rlimit(vc_data.id)) - return -ENOTSUPP; + if (!is_valid_rlimit(id)) + return -EINVAL; - vxi = locate_vx_info(id); + vxi = lookup_vx_info(xid); if (!vxi) return -ESRCH; - vc_data.maximum = vc_get_rlim(vxi, vc_data.id); - vc_data.minimum = CRLIM_UNSET; - vc_data.softlimit = CRLIM_UNSET; + if (minimum) + *minimum = CRLIM_UNSET; + if (softlimit) + *softlimit = CRLIM_UNSET; + if (maximum) + *maximum = vc_get_rlim(vxi, id); put_vx_info(vxi); + return 0; +} + +int vc_get_rlimit(uint32_t id, void __user *data) +{ + struct vcmd_ctx_rlimit_v0 vc_data; + int ret; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = do_get_rlimit(id, vc_data.id, + &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); + if (ret) + return ret; if (copy_to_user (data, &vc_data, sizeof(vc_data))) return -EFAULT; return 0; } -int vc_set_rlimit(uint32_t id, void __user *data) +static int do_set_rlimit(xid_t xid, uint32_t id, + uint64_t minimum, uint64_t softlimit, uint64_t maximum) { struct vx_info *vxi; + + if (!is_valid_rlimit(id)) + return -EINVAL; + + vxi = lookup_vx_info(xid); + if (!vxi) + return -ESRCH; + + if (maximum != CRLIM_KEEP) + vxi->limit.rlim[id] = maximum; + + put_vx_info(vxi); + return 0; +} + +int vc_set_rlimit(uint32_t id, void __user *data) +{ struct vcmd_ctx_rlimit_v0 vc_data; if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) return -EPERM; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - if (!is_valid_rlimit(vc_data.id)) - return -ENOTSUPP; - vxi = locate_vx_info(id); - if (!vxi) - return -ESRCH; + return do_set_rlimit(id, vc_data.id, + vc_data.minimum, vc_data.softlimit, vc_data.maximum); +} - if (vc_data.maximum != CRLIM_KEEP) - vxi->limit.rlim[vc_data.id] = vc_data.maximum; - put_vx_info(vxi); +#ifdef CONFIG_IA32_EMULATION + +int vc_set_rlimit_x32(uint32_t id, void __user *data) +{ + struct vcmd_ctx_rlimit_v0_x32 vc_data; + + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE)) + return -EPERM; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + return do_set_rlimit(id, vc_data.id, + vc_data.minimum, vc_data.softlimit, vc_data.maximum); +} + +int vc_get_rlimit_x32(uint32_t id, void __user *data) +{ + struct vcmd_ctx_rlimit_v0_x32 vc_data; + int ret; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = do_get_rlimit(id, vc_data.id, + &vc_data.minimum, &vc_data.softlimit, &vc_data.maximum); + if (ret) + return ret; + + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + return -EFAULT; return 0; } +#endif /* CONFIG_IA32_EMULATION */ + + int vc_get_rlimit_mask(uint32_t id, void __user *data) { static struct vcmd_ctx_rlimit_mask_v0 mask = {