mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add prlimit(2).
This commit is contained in:
parent
a6f38947f2
commit
13f09cc515
8 changed files with 125 additions and 1 deletions
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
41
libc/sys/resource/prlimit.cpp
Normal file
41
libc/sys/resource/prlimit.cpp
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue