Saturday, September 13, 2014

Unix Prog: Process Resource Limit

1. getrlimit, setrlimit
System Calls "getrlimit" , "setrlimit" can be used to retrieve and setup resources limit of current process.

Definition:
The first argument of getrlimit and setrlimit identifies what kind of resource it will retrieve or setup, and it should be one of macros defined at /usr/ci
 ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/sys/resource.h  
 ......  
 extern int getrlimit (__rlimit_resource_t __resource,  
            struct rlimit *__rlimits) __THROW;  
 ......  
 extern int setrlimit (__rlimit_resource_t __resource,  
            const struct rlimit *__rlimits) __THROW;  
 ......  
 ubuntu@ip-172-31-23-227:~$ less /usr/include/asm-generic/resource.h  
 ......  
 #define RLIMIT_CPU       0    /* CPU time in sec */  
 #define RLIMIT_FSIZE      1    /* Maximum filesize */  
 #define RLIMIT_DATA       2    /* max data size */  
 #define RLIMIT_STACK      3    /* max stack size */  
 #define RLIMIT_CORE       4    /* max core file size */  
   
 #ifndef RLIMIT_RSS  
 # define RLIMIT_RSS       5    /* max resident set size */  
 #endif  
   
 #ifndef RLIMIT_NPROC  
 # define RLIMIT_NPROC      6    /* max number of processes */  
 #endif  
   
 #ifndef RLIMIT_NOFILE  
 # define RLIMIT_NOFILE     7    /* max number of open files */  
 #endif  
   
 #ifndef RLIMIT_MEMLOCK  
 # define RLIMIT_MEMLOCK     8    /* max locked-in-memory address space */  
 #endif  
   
 #ifndef RLIMIT_AS  
 # define RLIMIT_AS       9    /* address space limit */  
 #endif  
   
 #define RLIMIT_LOCKS      10   /* maximum file locks held */  
 #define RLIMIT_SIGPENDING    11   /* max number of pending signals */  
 #define RLIMIT_MSGQUEUE     12   /* maximum bytes in POSIX mqueues */  
 #define RLIMIT_NICE       13   /* max nice prio allowed to raise to  
                       0-39 for nice level 19 .. -20 */  
 #define RLIMIT_RTPRIO      14   /* maximum realtime priority */  
 #define RLIMIT_RTTIME      15   /* timeout for RT tasks in us */  
 #define RLIM_NLIMITS      16  
 ......  

second argument of getrlimit, setrlimit:
struct rlimit definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/linux/resource.h  
 ......  
 struct rlimit {  
     unsigned long  rlim_cur;  
     unsigned long  rlim_max;  
 };  
   
 #define RLIM64_INFINITY     (~0ULL)  
 ......  

rlim_cur is the soft limit for one resource
rlim_max is the hard limit for one resource

Rules:
1) A process can change its soft limit to a value equal to or less than its hard limit
2) A process can reduce its hard limit to a value equal to or larger than its soft limit. and we can't increase the hard limit unless we are the super user
3) only super user can raise the hard limit

Note: the resource limit will be inherited from parents if children process are called. So the shell need to have all resources limits built in, since it needs to create all processes.

2. Example:
proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<sys/resource.h>  
   
 //"#name" will make it be parsed as string  
 //"name" will just replace the name with specified string in code  
 #define doit(name) pr_limit(#name, name)  
   
 static void pr_limit(char *name, int resource)  
 {  
  struct rlimit limit;  
   
  if(getrlimit(resource, &limit) < 0) {  
   printf("getrlimit error!\n");  
   exit(1);  
  }  
   
  printf("%-14s:", name);  
  if(limit.rlim_cur == RLIM_INFINITY)  
   printf("(infinite)  ");  
  else  
   printf("%lu  ", limit.rlim_cur);  
   
  if(limit.rlim_max == RLIM_INFINITY)  
   printf("(infinite)\n");  
  else  
   printf("%lu\n", limit.rlim_max);  
   
 }  
   
 int main(int argc, char* argv[])  
 {  
  doit(RLIMIT_CPU);  
  doit(RLIMIT_FSIZE);  
  doit(RLIMIT_DATA);  
  doit(RLIMIT_STACK);  
  doit(RLIMIT_CORE);  
  doit(RLIMIT_NPROC);  
  doit(RLIMIT_NOFILE);  
  doit(RLIMIT_AS);  
   
  exit(0);  
 }  

shell:
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 RLIMIT_CPU  :(infinite)  (infinite)  
 RLIMIT_FSIZE :(infinite)  (infinite)  
 RLIMIT_DATA  :(infinite)  (infinite)  
 RLIMIT_STACK :8388608  (infinite)  
 RLIMIT_CORE  :0  (infinite)  
 RLIMIT_NPROC :7862  7862  
 RLIMIT_NOFILE :1024  4096  
 RLIMIT_AS   :(infinite)  (infinite)  

No comments:

Post a Comment