Implement prlimit64() system call.

Differential Revision:	https://reviews.freebsd.org/D1050
Reviewed by:	emaste, trasz
This commit is contained in:
Dmitry Chagin 2015-05-24 15:18:19 +00:00
parent 737325a46d
commit c3978c7bb1
6 changed files with 82 additions and 6 deletions

View File

@ -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);

View File

@ -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); }

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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); }