add rlimit file to /proc/PID
PATCH 1/1 add rlimit file to /proc/PID
Hi all,
with a friend i have made this patch that add rlimit file to /proc/PID directory.
Trought this file you can set and get rlimit of a running process.
rlimit file contains:
<resource> <Soft limit> <Hard limit>
Example:
cave 5933 # pwd/proc/5933
cave 5933 # echo "RLIMIT_NOFILE 3 10" > rlimit
cave 5933 # cat rlimitRLIMIT_CPU -1 -1RLIMIT_FSIZE -1 -1RLIMIT_DATA -1 -1RLIMIT_STACK 8388608 -1RLIMIT_CORE 0 -1RLIMIT_RSS -1 -1RLIMIT_NPROC 4095 4095RLIMIT_NOFILE 3 10RLIMIT_MEMLOCK 32768 32768RLIMIT_AS -1 -1RLIMIT_LOCKS -1 -1RLIMIT_SIGPENDING 4095 4095
cave 5933 #
This is my first patch,i hope it will be usefull
--- linux-2.6.13-rc3/fs/proc/base.c 2005-07-15 20:57:25.000000000 +0200
+++ linux-2.6.13-rc3/fs/proc/base.c.rlimit 2005-07-15 20:57:05.000000000 +0200
fs/proc/base.c.rlimit renamed from fs/proc/base.c +191 -0
@@ -86,6 +86,7 @@ PROC_TGID_FD_DIR, PROC_TGID_OOM_SCORE, PROC_TGID_OOM_ADJUST, + PROC_TGID_RLIMIT, PROC_TID_INO, PROC_TID_STATUS, PROC_TID_MEM,
@@ -123,6 +124,7 @@ PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ PROC_TID_OOM_SCORE, PROC_TID_OOM_ADJUST, + PROC_TID_RLIMIT, }; struct pid_entry {
@@ -166,6 +168,7 @@ #endif E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR), + E(PROC_TGID_RLIMIT, "rlimit", S_IFREG|S_IRUGO), #ifdef CONFIG_AUDITSYSCALL E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO), #endif
@@ -202,6 +205,7 @@ #endif E(PROC_TID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO), E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR), + E(PROC_TID_RLIMIT, "rlimit", S_IFREG|S_IRUGO), #ifdef CONFIG_AUDITSYSCALL E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO), #endif
@@ -582,6 +586,189 @@ .read = proc_info_read, }; +static int rlimit_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task = proc_task(file->f_dentry->d_inode); + int res = 0, i; + unsigned long len; + char buffer[2048]; + if(task){ + + for(i=0; i<RLIM_NLIMITS;i++) + switch(i){ + case RLIMIT_AS: + len = sprintf(buffer+res, "RLIMIT_AS %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_CORE: + len = sprintf(buffer+res, "RLIMIT_CORE %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_CPU: + len = sprintf(buffer+res, "RLIMIT_CPU %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_DATA: + len = sprintf(buffer+res, "RLIMIT_DATA %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_FSIZE: + len = sprintf(buffer+res, "RLIMIT_FSIZE %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_LOCKS: + len = sprintf(buffer+res, "RLIMIT_LOCKS %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_MEMLOCK: + len = sprintf(buffer+res, "RLIMIT_MEMLOCK %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_NOFILE: + len = sprintf(buffer+res, "RLIMIT_NOFILE %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_NPROC: + len = sprintf(buffer+res, "RLIMIT_NPROC %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_RSS: + len = sprintf(buffer+res, "RLIMIT_RSS %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_SIGPENDING: + len = sprintf(buffer+res, "RLIMIT_SIGPENDING %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + case RLIMIT_STACK: + len = sprintf(buffer+res, "RLIMIT_STACK %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break; + + } + } +return simple_read_from_buffer(buf, count, ppos, buffer, res); +} + +static ssize_t rlimit_write(struct file * file, const char * buffer, + size_t count, loff_t *ppos) +{ + struct task_struct *task = proc_task(file->f_dentry->d_inode); + unsigned long cur,max; + char *c; + char *endptr; + char *buf=NULL; + + + if (((current->uid != task->euid) || + (current->uid != task->suid) || + (current->uid != task->uid) || + (current->gid != task->egid) || + (current->gid != task->sgid) || + (current->gid != task->gid)) || !capable(CAP_SYS_RESOURCE) ){ + return -EPERM; + } + + + if( (buf=kmalloc(GFP_KERNEL,count))==NULL){ + return -ENOMEM; + } + + memcpy(buf,buffer,count); + + + c=strchr(buf,' '); + if(!c) goto out_err; + + *c='\0'; + int resource=-1; + + if(strcmp("RLIMIT_AS",buf)==0) + resource=RLIMIT_AS; + else if(strcmp("RLIMIT_CORE",buf)==0) + resource=RLIMIT_CORE; + else if(strcmp("RLIMIT_CPU",buf)==0) + resource=RLIMIT_CPU; + else if(strcmp("RLIMIT_DATA",buf)==0) + resource=RLIMIT_DATA; + else if(strcmp("RLIMIT_FSIZE",buf)==0) + resource=RLIMIT_FSIZE; + else if(strcmp("RLIMIT_LOCKS",buf)==0) + resource=RLIMIT_LOCKS; + else if(strcmp("RLIMIT_MEMLOCK",buf)==0) + resource=RLIMIT_MEMLOCK; + else if(strcmp("RLIMIT_NOFILE",buf)==0) + resource=RLIMIT_NOFILE; + else if(strcmp("RLIMIT_NPROC",buf)==0) + resource=RLIMIT_NPROC; + else if(strcmp("RLIMIT_RSS",buf)==0) + resource=RLIMIT_RSS; + else if(strcmp("RLIMIT_SIGPENDING",buf)==0) + resource=RLIMIT_SIGPENDING; + else if(strcmp("RLIMIT_STACK",buf)==0) + resource=RLIMIT_STACK; + + + if(resource==-1) + goto out_err; + + buf=c+1; + + cur=(unsigned long)simple_strtol(buf,&endptr,10); + + buf=endptr+1; + + max=(unsigned long)simple_strtol(buf,&endptr,10); + + + task->signal->rlim[resource].rlim_cur=cur; + task->signal->rlim[resource].rlim_max=max; + + + kfree(buf); + return count; + + out_err: + kfree(buf); + return EINVAL; + + + +} + + + +static struct file_operations proc_rlimit_file_operations = { + .read = rlimit_read, + .write = rlimit_write, +}; + + static int mem_open(struct inode* inode, struct file* file) { file->private_data = (void*)((long)current->self_exec_id);
@@ -1520,6 +1707,10 @@ inode->i_fop = &proc_info_file_operations; ei->op.proc_read = proc_pid_statm; break; + case PROC_TID_RLIMIT: + case PROC_TGID_RLIMIT: + inode->i_fop = &proc_rlimit_file_operations; + break; case PROC_TID_MAPS: case PROC_TGID_MAPS: inode->i_fop = &proc_maps_operations;
dierbro <[email protected]> :
[...]
Quoted 3 lines
with a friend i have made this patch that add rlimit file to
/proc/PIDdirectory.
Trought this file you can set and get rlimit of a running process.
I am not sure that new proc-functions will be welcome, anyway...
[...]
fs/proc/base.c.rlimit line 595
Quoted 9 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +7
-0+static int rlimit_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task = proc_task(file->f_dentry->d_inode); + int res = 0, i; + unsigned long len; + char buffer[2048];
^^^^
Ahem...
fs/proc/base.c.rlimit line 605
Quoted 10 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +10
-0+ if(task){ + + for(i=0; i<RLIM_NLIMITS;i++) + switch(i){ + case RLIMIT_AS: + len = sprintf(buffer+res, "RLIMIT_AS %d %d\n", + (int) task->signal->rlim[i].rlim_cur, + (int)task->signal->rlim[i].rlim_max); + res+=len; + break;
[generous code duplication deleted]
You want an initialized array for the strings "RLIMIT_AS", "RLIMIT_CORE", etc.
[...]
fs/proc/base.c.rlimit line 685
Quoted 8 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +8
-0+static ssize_t rlimit_write(struct file * file, const char * buffer, + size_t count, loff_t *ppos) +{ + struct task_struct *task = proc_task(file->f_dentry->d_inode); + unsigned long cur,max; + char *c; + char *endptr; + char *buf=NULL;
Unneeded initialization
[...]
fs/proc/base.c.rlimit line 698
Quoted 1 line
fs/proc/base.c.rlimit renamed from fs/proc/base.c +1
-0+ if( (buf=kmalloc(GFP_KERNEL,count))==NULL){
GFP_XXX must be the second arg.
fs/proc/base.c.rlimit line 706
Quoted 8 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +8
-0+ return -ENOMEM; + } + + memcpy(buf,buffer,count); + + + c=strchr(buf,' '); + if(!c) goto out_err;
CodingStyle (the whole patch is terrible).
fs/proc/base.c.rlimit line 716
Quoted 10 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +10
-0+ + *c='\0'; + int resource=-1; + + if(strcmp("RLIMIT_AS",buf)==0) + resource=RLIMIT_AS; + else if(strcmp("RLIMIT_CORE",buf)==0) + resource=RLIMIT_CORE; + else if(strcmp("RLIMIT_CPU",buf)==0) + resource=RLIMIT_CPU;
[...]
More code duplication. Use a loop instead.
[...]
fs/proc/base.c.rlimit line 758
Quoted 3 lines
fs/proc/base.c.rlimit renamed from fs/proc/base.c +3
-0+ out_err: + kfree(buf); + return EINVAL;
-EINVAL
--
Ueimor