support setrlimits/getrlimits, however this fix is these syscalls only.

checking resource process must implement it separately.

refs #330
This commit is contained in:
Tomoki Shirasawa
2015-01-27 10:35:58 +09:00
parent cf2166f830
commit 08cc31f9bf
9 changed files with 200 additions and 44 deletions

View File

@ -73,6 +73,7 @@ SYSCALL_HANDLED(131, sigaltstack)
SYSCALL_HANDLED(149, mlock)
SYSCALL_HANDLED(150, munlock)
SYSCALL_HANDLED(158, arch_prctl)
SYSCALL_HANDLED(160, setrlimit)
SYSCALL_HANDLED(186, gettid)
SYSCALL_DELEGATED(201, time)
SYSCALL_HANDLED(202, futex)

View File

@ -70,6 +70,7 @@ struct program_image_section {
};
#define SHELL_PATH_MAX_LEN 1024
#define MCK_RLIM_MAX 20
struct program_load_desc {
int num_sections;
@ -93,8 +94,7 @@ struct program_load_desc {
unsigned long args_len;
char *envs;
unsigned long envs_len;
unsigned long rlimit_stack_cur;
unsigned long rlimit_stack_max;
struct rlimit rlimit[MCK_RLIM_MAX];
unsigned long interp_align;
char shell_path[SHELL_PATH_MAX_LEN];
struct program_image_section sections[0];

View File

@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/resource.h>
#include "mcctrl.h"
//#define PROCFS_DEBUG

View File

@ -40,7 +40,6 @@
#include <ctype.h>
#include <sys/mman.h>
#include <asm/unistd.h>
#include "../include/uprotocol.h"
#include <sched.h>
#include <termios.h>
@ -57,6 +56,7 @@
#include <sys/syscall.h>
#include <pthread.h>
#include <signal.h>
#include "../include/uprotocol.h"
//#define DEBUG
@ -945,7 +945,75 @@ void init_worker_threads(int fd, int mcosid)
}
pthread_barrier_wait(&init_ready);
}
}
#define MCK_RLIMIT_AS 0
#define MCK_RLIMIT_CORE 1
#define MCK_RLIMIT_CPU 2
#define MCK_RLIMIT_DATA 3
#define MCK_RLIMIT_FSIZE 4
#define MCK_RLIMIT_LOCKS 5
#define MCK_RLIMIT_MEMLOCK 6
#define MCK_RLIMIT_MSGQUEUE 7
#define MCK_RLIMIT_NICE 8
#define MCK_RLIMIT_NOFILE 9
#define MCK_RLIMIT_NPROC 10
#define MCK_RLIMIT_RSS 11
#define MCK_RLIMIT_RTPRIO 12
#define MCK_RLIMIT_RTTIME 13
#define MCK_RLIMIT_SIGPENDING 14
#define MCK_RLIMIT_STACK 15
static int rlimits[] = {
#ifdef RLIMIT_AS
RLIMIT_AS, MCK_RLIMIT_AS,
#endif
#ifdef RLIMIT_CORE
RLIMIT_CORE, MCK_RLIMIT_CORE,
#endif
#ifdef RLIMIT_CPU
RLIMIT_CPU, MCK_RLIMIT_CPU,
#endif
#ifdef RLIMIT_DATA
RLIMIT_DATA, MCK_RLIMIT_DATA,
#endif
#ifdef RLIMIT_FSIZE
RLIMIT_FSIZE, MCK_RLIMIT_FSIZE,
#endif
#ifdef RLIMIT_LOCKS
RLIMIT_LOCKS, MCK_RLIMIT_LOCKS,
#endif
#ifdef RLIMIT_MEMLOCK
RLIMIT_MEMLOCK, MCK_RLIMIT_MEMLOCK,
#endif
#ifdef RLIMIT_MSGQUEUE
RLIMIT_MSGQUEUE,MCK_RLIMIT_MSGQUEUE,
#endif
#ifdef RLIMIT_NICE
RLIMIT_NICE, MCK_RLIMIT_NICE,
#endif
#ifdef RLIMIT_NOFILE
RLIMIT_NOFILE, MCK_RLIMIT_NOFILE,
#endif
#ifdef RLIMIT_NPROC
RLIMIT_NPROC, MCK_RLIMIT_NPROC,
#endif
#ifdef RLIMIT_RSS
RLIMIT_RSS, MCK_RLIMIT_RSS,
#endif
#ifdef RLIMIT_RTPRIO
RLIMIT_RTPRIO, MCK_RLIMIT_RTPRIO,
#endif
#ifdef RLIMIT_RTTIME
RLIMIT_RTTIME, MCK_RLIMIT_RTTIME,
#endif
#ifdef RLIMIT_SIGPENDING
RLIMIT_SIGPENDING,MCK_RLIMIT_SIGPENDING,
#endif
#ifdef RLIMIT_STACK
RLIMIT_STACK, MCK_RLIMIT_STACK,
#endif
};
char dev[64];
@ -1071,7 +1139,9 @@ int main(int argc, char **argv)
if (shell) {
argv[optind] = path;
}
for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2)
getrlimit(rlimits[i], &desc->rlimit[rlimits[i + 1]]);
desc->envs_len = envs_len;
desc->envs = envs;
//print_flat(envs);
@ -1106,8 +1176,8 @@ int main(int argc, char **argv)
rlim_stack.rlim_cur = lcur;
rlim_stack.rlim_max = lmax;
}
desc->rlimit_stack_cur = rlim_stack.rlim_cur;
desc->rlimit_stack_max = rlim_stack.rlim_max;
desc->rlimit[MCK_RLIMIT_STACK].rlim_cur = rlim_stack.rlim_cur;
desc->rlimit[MCK_RLIMIT_STACK].rlim_max = rlim_stack.rlim_max;
ncpu = ioctl(fd, MCEXEC_UP_GET_CPU, 0);
if(ncpu == -1){

View File

@ -368,8 +368,7 @@ static int process_msg_prepare_process(unsigned long rphys)
proc->vm->region.user_end = pn->user_end;
proc->vm->region.map_start = (USER_END / 3) & LARGE_PAGE_MASK;
proc->vm->region.map_end = proc->vm->region.map_start;
proc->rlimit_stack.rlim_cur = pn->rlimit_stack_cur;
proc->rlimit_stack.rlim_max = pn->rlimit_stack_max;
memcpy(proc->rlimit, pn->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX);
/* TODO: Clear it at the proper timing */
cpu_local_var(scp).post_idx = 0;

View File

@ -21,6 +21,7 @@
#include <signal.h>
#include <memobj.h>
#include <affinity.h>
#include <syscall.h>
#define VR_NONE 0x0
#define VR_STACK 0x1
@ -145,7 +146,6 @@
#include <waitq.h>
#include <futex.h>
#include <rlimit.h>
struct user_fpregs_struct
{
@ -343,7 +343,7 @@ struct process {
struct sig_shared *sigshared;
struct sig_handler *sighandler;
struct rlimit rlimit_stack;
struct rlimit rlimit[MCK_RLIM_MAX];
pgio_func_t *pgio_fp;
void *pgio_arg;

View File

@ -15,6 +15,7 @@
#include <ihk/context.h>
#include <ihk/memconst.h>
#include <rlimit.h>
#define NUM_SYSCALLS 255
@ -112,6 +113,24 @@ struct program_image_section {
};
#define SHELL_PATH_MAX_LEN 1024
#define MCK_RLIM_MAX 20
#define MCK_RLIMIT_AS 0
#define MCK_RLIMIT_CORE 1
#define MCK_RLIMIT_CPU 2
#define MCK_RLIMIT_DATA 3
#define MCK_RLIMIT_FSIZE 4
#define MCK_RLIMIT_LOCKS 5
#define MCK_RLIMIT_MEMLOCK 6
#define MCK_RLIMIT_MSGQUEUE 7
#define MCK_RLIMIT_NICE 8
#define MCK_RLIMIT_NOFILE 9
#define MCK_RLIMIT_NPROC 10
#define MCK_RLIMIT_RSS 11
#define MCK_RLIMIT_RTPRIO 12
#define MCK_RLIMIT_RTTIME 13
#define MCK_RLIMIT_SIGPENDING 14
#define MCK_RLIMIT_STACK 15
struct program_load_desc {
int num_sections;
@ -135,8 +154,7 @@ struct program_load_desc {
unsigned long args_len;
char *envs;
unsigned long envs_len;
unsigned long rlimit_stack_cur;
unsigned long rlimit_stack_max;
struct rlimit rlimit[MCK_RLIM_MAX];
unsigned long interp_align;
char shell_path[SHELL_PATH_MAX_LEN];
struct program_image_section sections[0];

View File

@ -235,7 +235,7 @@ struct process *clone_process(struct process *org, unsigned long pc,
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_STACK_POINTER, sp);
ihk_mc_modify_user_context(proc->uctx, IHK_UCR_PROGRAM_COUNTER, pc);
proc->rlimit_stack = org->rlimit_stack;
memcpy(proc->rlimit, org->rlimit, sizeof(struct rlimit) * MCK_RLIM_MAX);
proc->sigmask = org->sigmask;
proc->ftn = kmalloc(sizeof(struct fork_tree_node), IHK_MC_AP_NOWAIT);
@ -1453,7 +1453,7 @@ int init_process_stack(struct process *process, struct program_load_desc *pn,
/* create stack range */
minsz = PAGE_SIZE;
size = process->rlimit_stack.rlim_cur & PAGE_MASK;
size = process->rlimit[MCK_RLIMIT_STACK].rlim_cur & PAGE_MASK;
if (size > (USER_END / 2)) {
size = USER_END / 2;
}

View File

@ -2455,43 +2455,110 @@ SYSCALL_DECLARE(exit)
return 0;
}
SYSCALL_DECLARE(getrlimit)
static int rlimits[] = {
#ifdef RLIMIT_AS
RLIMIT_AS, MCK_RLIMIT_AS,
#endif
#ifdef RLIMIT_CORE
RLIMIT_CORE, MCK_RLIMIT_CORE,
#endif
#ifdef RLIMIT_CPU
RLIMIT_CPU, MCK_RLIMIT_CPU,
#endif
#ifdef RLIMIT_DATA
RLIMIT_DATA, MCK_RLIMIT_DATA,
#endif
#ifdef RLIMIT_FSIZE
RLIMIT_FSIZE, MCK_RLIMIT_FSIZE,
#endif
#ifdef RLIMIT_LOCKS
RLIMIT_LOCKS, MCK_RLIMIT_LOCKS,
#endif
#ifdef RLIMIT_MEMLOCK
RLIMIT_MEMLOCK, MCK_RLIMIT_MEMLOCK,
#endif
#ifdef RLIMIT_MSGQUEUE
RLIMIT_MSGQUEUE,MCK_RLIMIT_MSGQUEUE,
#endif
#ifdef RLIMIT_NICE
RLIMIT_NICE, MCK_RLIMIT_NICE,
#endif
#ifdef RLIMIT_NOFILE
RLIMIT_NOFILE, MCK_RLIMIT_NOFILE,
#endif
#ifdef RLIMIT_NPROC
RLIMIT_NPROC, MCK_RLIMIT_NPROC,
#endif
#ifdef RLIMIT_RSS
RLIMIT_RSS, MCK_RLIMIT_RSS,
#endif
#ifdef RLIMIT_RTPRIO
RLIMIT_RTPRIO, MCK_RLIMIT_RTPRIO,
#endif
#ifdef RLIMIT_RTTIME
RLIMIT_RTTIME, MCK_RLIMIT_RTTIME,
#endif
#ifdef RLIMIT_SIGPENDING
RLIMIT_SIGPENDING,MCK_RLIMIT_SIGPENDING,
#endif
#ifdef RLIMIT_STACK
RLIMIT_STACK, MCK_RLIMIT_STACK,
#endif
};
SYSCALL_DECLARE(setrlimit)
{
int ret;
int rc;
int resource = ihk_mc_syscall_arg0(ctx);
struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
struct process *proc = cpu_local_var(current);
int i;
int mcresource;
switch (resource) {
case RLIMIT_STACK:
dkprintf("[%d] getrlimit() RLIMIT_STACK\n", ihk_mc_get_processor_id());
if(copy_to_user(proc, &rlm->rlim_cur, &proc->rlimit_stack.rlim_cur, sizeof rlm->rlim_cur))
return -EFAULT;
if(copy_to_user(proc, &rlm->rlim_max, &proc->rlimit_stack.rlim_max, sizeof rlm->rlim_max))
return -EFAULT;
ret = 0;
switch(resource){
case RLIMIT_FSIZE:
case RLIMIT_NOFILE:
rc = syscall_generic_forwarding(__NR_setrlimit, ctx);
if(rc < 0)
return rc;
break;
case RLIMIT_FSIZE:
case RLIMIT_LOCKS:
case RLIMIT_NOFILE:
/* just forward */
ret = syscall_generic_forwarding(n, ctx);
/* return one less than the actual value to make sure mcexec can open
* its temporary synchronization pipe when a new process is forked */
if (resource == RLIMIT_NOFILE) {
ret -= 1;
}
break;
default:
return -ENOSYS;
}
return ret;
for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2)
if(rlimits[i] == resource){
mcresource = rlimits[i + 1];
break;
}
if(i >= sizeof(rlimits) / sizeof(int))
return -EINVAL;
if(copy_from_user(proc, proc->rlimit + mcresource, rlm, sizeof(struct rlimit)))
return -EFAULT;
return 0;
}
SYSCALL_DECLARE(getrlimit)
{
int resource = ihk_mc_syscall_arg0(ctx);
struct rlimit *rlm = (struct rlimit *)ihk_mc_syscall_arg1(ctx);
struct process *proc = cpu_local_var(current);
int i;
int mcresource;
for(i = 0; i < sizeof(rlimits) / sizeof(int); i += 2)
if(rlimits[i] == resource){
mcresource = rlimits[i + 1];
break;
}
if(i >= sizeof(rlimits) / sizeof(int))
return -EINVAL;
// TODO: check limit
if(copy_to_user(proc, rlm, proc->rlimit + mcresource, sizeof(struct rlimit)))
return -EFAULT;
return 0;
}
extern int ptrace_traceme(void);