Commit 54b32cb1 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

x86: Implement prlimit proxy

RHEL6 is shipped with libc 2.12 where no prlimit
helper provided (which was pushed into libc itself
since 2.13). So we implement own proxy for convenience.

Note, if libc does support prlimit itself we simply
don't use any proxy and call it directly.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent a5fcc8b0
......@@ -6,6 +6,7 @@ SYS-ASM := syscalls.S
syscalls-asm-y += $(SYS-ASM:.S=).o
crtools-obj-y += crtools.o
crtools-obj-y += cpu.o
crtools-obj-y += prlimit.o
SYS-DEF := syscall-x86-64.def
SYS-ASM-COMMON := syscall-common-x86-64.S
......
#ifndef __CR_PRLIMIT_H__
#define __CR_PRLIMIT_H__
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include "config.h"
#ifndef CONFIG_HAS_PRLIMIT
extern int prlimit(pid_t pid, int resource, const struct rlimit *new_rlimit, struct rlimit *old_rlimit);
#endif
#endif /* __CR_PRLIMIT_H__ */
......@@ -6,6 +6,7 @@
#include "asm/bitops.h"
#include "asm/int.h"
#include "asm/prlimit.h"
#include "protobuf/core.pb-c.h"
......
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "asm/types.h"
#include "asm/prlimit.h"
#include "compiler.h"
#include "syscall.h"
#include "config.h"
#ifndef CONFIG_HAS_PRLIMIT
#ifndef RLIM64_INFINITY
# define RLIM64_INFINITY (~0ULL)
#endif
int prlimit(pid_t pid, int resource, const struct rlimit *new_rlimit, struct rlimit *old_rlimit)
{
struct rlimit64 new_rlimit64_mem;
struct rlimit64 old_rlimit64_mem;
struct rlimit64 *new_rlimit64 = NULL;
struct rlimit64 *old_rlimit64 = NULL;
int ret;
if (old_rlimit)
old_rlimit64 = &old_rlimit64_mem;
if (new_rlimit) {
if (new_rlimit->rlim_cur == RLIM_INFINITY)
new_rlimit64_mem.rlim_cur = RLIM64_INFINITY;
else
new_rlimit64_mem.rlim_cur = new_rlimit->rlim_cur;
if (new_rlimit->rlim_max == RLIM_INFINITY)
new_rlimit64_mem.rlim_max = RLIM64_INFINITY;
else
new_rlimit64_mem.rlim_max = new_rlimit->rlim_max;
new_rlimit64 = &new_rlimit64_mem;
}
ret = sys_prlimit64(pid, resource, new_rlimit64, old_rlimit64);
if (ret == 0 && old_rlimit) {
old_rlimit->rlim_cur = old_rlimit64_mem.rlim_cur;
if (old_rlimit->rlim_cur != old_rlimit64_mem.rlim_cur) {
if (new_rlimit) {
errno = EOVERFLOW;
return -1;
}
old_rlimit->rlim_cur = RLIM_INFINITY;
}
old_rlimit->rlim_max = old_rlimit64_mem.rlim_max;
if (old_rlimit->rlim_max != old_rlimit64_mem.rlim_max) {
if (new_rlimit) {
errno = EOVERFLOW;
return -1;
}
old_rlimit->rlim_max = RLIM_INFINITY;
}
} else if (ret) {
errno = -ret;
ret = -1;
}
return ret;
}
#endif /* CONFIG_HAS_PRLIMIT */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment