Add prlimit(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-08-30 23:55:09 +02:00
parent a6f38947f2
commit 13f09cc515
8 changed files with 125 additions and 1 deletions

View File

@ -309,6 +309,7 @@ sys/mman/mprotect.o \
sys/mman/munmap.o \
sys/readdirents/readdirents.o \
sys/resource/getpriority.o \
sys/resource/prlimit.o \
sys/resource/setpriority.o \
sys/select/select.o \
sys/socket/accept4.o \

View File

@ -31,8 +31,10 @@
__BEGIN_DECLS
@include(id_t.h)
@include(pid_t.h)
int getpriority(int, id_t);
int prlimit(pid_t, int, const struct rlimit*, struct rlimit*);
int setpriority(int, id_t, int);
__END_DECLS

View File

@ -0,0 +1,41 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2013.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
sys/resource/prlimit.cpp
Access and modify the resource limits of the given process.
*******************************************************************************/
#include <sys/resource.h>
#include <sys/syscall.h>
DEFN_SYSCALL4(int, sys_prlimit, SYSCALL_PRLIMIT,
pid_t,
int,
const struct rlimit*,
struct rlimit*);
extern "C"
int prlimit(pid_t pid,
int resource,
const struct rlimit* new_limit,
struct rlimit* old_limit)
{
return sys_prlimit(pid, resource, new_limit, old_limit);
}

View File

@ -26,6 +26,7 @@
#define INCLUDE_SORTIX_KERNEL_PROCESS_H
#include <sortix/fork.h>
#include <sortix/resource.h>
#include <sortix/kernel/clock.h>
#include <sortix/kernel/kthread.h>
@ -91,6 +92,10 @@ private:
Ref<MountTable> mtable;
Ref<DescriptorTable> dtable;
public:
kthread_mutex_t resource_limits_lock;
struct rlimit resource_limits[RLIMIT_NUM_DECLARED];
public:
void BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable);
void BootstrapDirectories(Ref<Descriptor> root);

View File

@ -26,6 +26,7 @@
#define INCLUDE_SORTIX_RESOURCE_H
#include <features.h>
#include <__/stdint.h>
__BEGIN_DECLS
@ -33,6 +34,31 @@ __BEGIN_DECLS
#define PRIO_PGRP 1
#define PRIO_USER 2
typedef __uintmax_t rlim_t;
#define RLIM_INFINITY __UINTMAX_MAX
#define RLIM_SAVED_CUR RLIM_INFINITY
#define RLIM_SAVED_MAX RLIM_INFINITY
struct rlimit
{
rlim_t rlim_cur;
rlim_t rlim_max;
};
#define RLIMIT_AS 0
#define RLIMIT_CORE 1
#define RLIMIT_CPU 2
#define RLIMIT_DATA 3
#define RLIMIT_FSIZE 4
#define RLIMIT_NOFILE 5
#define RLIMIT_STACK 6
#define __RLIMIT_NUM_DECLARED 7 /* index of highest constant plus 1. */
#if !__STDC_HOSTED__ && defined(SORTIX_KERNEL)
#define RLIMIT_NUM_DECLARED __RLIMIT_NUM_DECLARED
#endif
__END_DECLS
#endif

View File

@ -142,6 +142,7 @@
#define SYSCALL_MUNMAP 118
#define SYSCALL_GETPRIORITY 119
#define SYSCALL_SETPRIORITY 120
#define SYSCALL_MAX_NUM 121 /* index of highest constant + 1 */
#define SYSCALL_PRLIMIT 121
#define SYSCALL_MAX_NUM 122 /* index of highest constant + 1 */
#endif

View File

@ -32,6 +32,7 @@
#include <sortix/fcntl.h>
#include <sortix/fork.h>
#include <sortix/mman.h>
#include <sortix/resource.h>
#include <sortix/signal.h>
#include <sortix/stat.h>
#include <sortix/unistd.h>
@ -105,6 +106,12 @@ Process::Process()
umask = 0022;
nicelock = KTHREAD_MUTEX_INITIALIZER;
nice = 0;
resource_limits_lock = KTHREAD_MUTEX_INITIALIZER;
for ( size_t i = 0; i < RLIMIT_NUM_DECLARED; i++ )
{
resource_limits[i].rlim_cur = RLIM_INFINITY;
resource_limits[i].rlim_max = RLIM_INFINITY;
}
Time::InitializeProcessClocks(this);
alarm_timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
Put(this);
@ -649,6 +656,11 @@ Process* Process::Fork()
kthread_mutex_unlock(&groupchildlock);
// Initialize everything that is safe and can't fail.
kthread_mutex_lock(&resource_limits_lock);
for ( size_t i = 0; i < RLIMIT_NUM_DECLARED; i++ )
clone->resource_limits[i] = resource_limits[i];
kthread_mutex_unlock(&resource_limits_lock);
kthread_mutex_lock(&nicelock);
clone->nice = nice;
kthread_mutex_unlock(&nicelock);

View File

@ -29,6 +29,7 @@
#include <sortix/resource.h>
#include <sortix/kernel/copy.h>
#include <sortix/kernel/kernel.h>
#include <sortix/kernel/process.h>
#include <sortix/kernel/syscall.h>
@ -148,9 +149,44 @@ static int sys_setpriority(int which, id_t who, int prio)
}
}
static
int sys_prlimit(pid_t pid,
int resource,
const struct rlimit* user_new_limit,
struct rlimit* user_old_limit)
{
if ( pid < 0 )
return errno = EINVAL, -1;
if ( resource < 0 || RLIMIT_NUM_DECLARED <= resource )
return errno = EINVAL, -1;
// TODO: If pid isn't the current process, then it could self-destruct at
// any time while we use it; there is no safe way to do this yet.
Process* process = pid ? Process::Get(pid) : CurrentProcess();
if ( !process )
return errno = ESRCH, -1;
ScopedLock lock(&process->resource_limits_lock);
struct rlimit* limit = &process->resource_limits[resource];
if ( user_old_limit )
{
if ( !CopyToUser(user_old_limit, limit, sizeof(struct rlimit)) )
return -1;
}
if ( user_new_limit )
{
struct rlimit new_limit;
if ( !CopyFromUser(&new_limit, user_new_limit, sizeof(struct rlimit)) )
return -1;
if ( new_limit.rlim_max < new_limit.rlim_cur )
return errno = EINVAL, -1;
*limit = new_limit;
}
return 0;
}
void Init()
{
Syscall::Register(SYSCALL_GETPRIORITY, (void*) sys_getpriority);
Syscall::Register(SYSCALL_PRLIMIT, (void*) sys_prlimit);
Syscall::Register(SYSCALL_SETPRIORITY, (void*) sys_setpriority);
}