summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/linux32/linux32_dummy.c2
-rw-r--r--sys/amd64/linux32/syscalls.master5
-rw-r--r--sys/compat/linux/linux_misc.c73
-rw-r--r--sys/compat/linux/linux_misc.h1
-rw-r--r--sys/i386/linux/linux_dummy.c2
-rw-r--r--sys/i386/linux/syscalls.master5
6 files changed, 82 insertions, 6 deletions
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c
index ccc6845..c14711c 100644
--- a/sys/amd64/linux32/linux32_dummy.c
+++ b/sys/amd64/linux32/linux32_dummy.c
@@ -133,8 +133,6 @@ DUMMY(perf_event_open);
DUMMY(recvmmsg);
DUMMY(fanotify_init);
DUMMY(fanotify_mark);
-/* linux 2.6.36: */
-DUMMY(prlimit64);
/* later: */
DUMMY(name_to_handle_at);
DUMMY(open_by_handle_at);
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 53fd315..a6e19f0 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -554,7 +554,10 @@
338 AUE_NULL STD { int linux_fanotify_init(void); }
339 AUE_NULL STD { int linux_fanotify_mark(void); }
; linux 2.6.36:
-340 AUE_NULL STD { int linux_prlimit64(void); }
+340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \
+ l_uint resource, \
+ struct rlimit *new, \
+ struct rlimit *old); }
; later:
341 AUE_NULL STD { int linux_name_to_handle_at(void); }
342 AUE_NULL STD { int linux_open_by_handle_at(void); }
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index f745298..8a6db39 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -2034,6 +2034,79 @@ linux_sched_setaffinity(struct thread *td,
return (sys_cpuset_setaffinity(td, &csa));
}
+struct linux_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
+
+int
+linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args)
+{
+ struct rlimit rlim, nrlim;
+ struct linux_rlimit64 lrlim;
+ struct proc *p;
+ u_int which;
+ int flags;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(prlimit64))
+ printf(ARGS(prlimit64, "%d, %d, %p, %p"), args->pid,
+ args->resource, (void *)args->new, (void *)args->old);
+#endif
+
+ if (args->resource >= LINUX_RLIM_NLIMITS)
+ return (EINVAL);
+
+ which = linux_to_bsd_resource[args->resource];
+ if (which == -1)
+ return (EINVAL);
+
+ if (args->new != NULL) {
+ /*
+ * Note. Unlike FreeBSD where rlim is signed 64-bit Linux
+ * rlim is unsigned 64-bit. FreeBSD treats negative limits
+ * as INFINITY so we do not need a conversion even.
+ */
+ error = copyin(args->new, &nrlim, sizeof(nrlim));
+ if (error != 0)
+ return (error);
+ }
+
+ flags = PGET_HOLD | PGET_NOTWEXIT;
+ if (args->new != NULL)
+ flags |= PGET_CANDEBUG;
+ else
+ flags |= PGET_CANSEE;
+ error = pget(args->pid, flags, &p);
+ if (error != 0)
+ return (error);
+
+ if (args->old != NULL) {
+ PROC_LOCK(p);
+ lim_rlimit(p, which, &rlim);
+ PROC_UNLOCK(p);
+ if (rlim.rlim_cur == RLIM_INFINITY)
+ lrlim.rlim_cur = LINUX_RLIM_INFINITY;
+ else
+ lrlim.rlim_cur = rlim.rlim_cur;
+ if (rlim.rlim_max == RLIM_INFINITY)
+ lrlim.rlim_max = LINUX_RLIM_INFINITY;
+ else
+ lrlim.rlim_max = rlim.rlim_max;
+ error = copyout(&lrlim, args->old, sizeof(lrlim));
+ if (error != 0)
+ goto out;
+ }
+
+ if (args->new != NULL)
+ error = kern_proc_setrlimit(td, p, which, &nrlim);
+
+ out:
+ PRELE(p);
+ return (error);
+}
+
int
linux_sched_rr_get_interval(struct thread *td,
struct linux_sched_rr_get_interval_args *uap)
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index 71d8f1b..d15c7e5 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -130,6 +130,7 @@ extern int stclohz;
#define LINUX_P_PID 1
#define LINUX_P_PGID 2
+#define LINUX_RLIM_INFINITY (~0UL)
int linux_common_wait(struct thread *td, int pid, int *status,
int options, struct rusage *ru);
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 742f6d4..7e68f5e 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -129,8 +129,6 @@ DUMMY(perf_event_open);
DUMMY(recvmmsg);
DUMMY(fanotify_init);
DUMMY(fanotify_mark);
-/* linux 2.6.36: */
-DUMMY(prlimit64);
/* later: */
DUMMY(name_to_handle_at);
DUMMY(open_by_handle_at);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index b7eb462..a947e5a 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -562,7 +562,10 @@
338 AUE_NULL STD { int linux_fanotify_init(void); }
339 AUE_NULL STD { int linux_fanotify_mark(void); }
; linux 2.6.36:
-340 AUE_NULL STD { int linux_prlimit64(void); }
+340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \
+ l_uint resource, \
+ struct rlimit *new, \
+ struct rlimit *old); }
; later:
341 AUE_NULL STD { int linux_name_to_handle_at(void); }
342 AUE_NULL STD { int linux_open_by_handle_at(void); }
OpenPOWER on IntegriCloud