Method based on Linux system call getrlimit of and setrlimit of function

  • 2020-04-02 00:44:30
  • OfStack

Function description:
Gets or sets resource usage limits. Each resource has its associated soft and hard limits. The soft limit is the limit value imposed by the kernel on the corresponding resource, and the hard limit is the maximum of the soft limit. An unauthorized calling process can only specify its soft limit as a value in the range of 0 to hard limits, while irreversibly reducing its hard limit. The authorization process can change its hard and soft limits at will. The value of RLIM_INFINITY indicates no resource constraints.
Usage:

#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);

Parameters:
Resource: there are possible options
Maximum virtual memory space of RLIMIT_AS // process in bytes.
RLIMIT_CORE // maximum length of kernel save files.
RLIMIT_CPU // maximum allowed CPU usage in seconds. When a process reaches the soft limit, the kernel sends it a SIGXCPU signal, which by default terminates the execution of the process. However, the signal can be captured and the processing handle can return control to the main program. If the process continues to consume CPU time, the core sends a SIGXCPU signal to it once per second until the hard limit is reached, at which point it sends a SIGKILL signal to the process to terminate its execution.
RLIMIT_DATA // maximum value of the process data segment.
RLIMIT_FSIZE // maximum length of files that a process can create. If a process tries to exceed this limit, the core sends it a SIGXFSZ signal, which by default terminates the process.
RLIMIT_LOCKS // maximum number of locks and leases a process can establish.
RLIMIT_MEMLOCK // process can lock the maximum amount of data in memory in bytes.
The maximum number of bytes that the RLIMIT_MSGQUEUE // process can allocate to the POSIX message queue.
RLIMIT_NICE // process can be set to a maximum perfect value with a setpriority() or nice() call.
RLIMIT_NOFILE // specifies a value larger than the maximum file descriptor that the process can open. Exceeding this value will result in an EMFILE error.
RLIMIT_NPROC // the maximum number of processes a user can have.
The maximum real-time priority that the RLIMIT_RTPRIO // process can set through the sched_setscheduler and sched_setparam.
RLIMIT_SIGPENDING // the maximum number of pending signals a user can have.
RLIMIT_STACK // maximum process stack in bytes.
Rlim: describes the structure of the resource's hard and soft constraints, with the following prototype

struct rlimit {
  rlim_t rlim_cur;
  rlim_t rlim_max;
};

Return instructions:
On successful execution, 0 is returned. Failure returns -1, and errno is set to one of the following values
EFAULT: the space the rlim pointer points to is not accessible
EINVAL: the parameter is invalid
EPERM: power is not allowed when increasing resource limit

Extended reading:
Ulimit and setrlimit easily modify the task process resource upper limit
In Linux systems, the Resouce limit is the limit on the resources available to a process during its execution, such as the maximum value of the process's core file, the maximum value of virtual memory, and so on.
The size of the Resouce limit can directly affect the execution of a process. There are two most important concepts: Soft limit and The hard limit.

struct rlimit {
  rlim_t rlim_cur;  //soft limit
  rlim_t rlim_max;  //hard limit
};

Soft limit is the resource limit that the kernel can support. For example, for RLIMIT_NOFILE(the maximum number of files a process can open, the kernel default is 1024), soft limit is limited to 1024. For RLIMIT_CORE, soft limit can be unlimited.
The hard limit in a resource is only the limit of the soft limit. When you set the hard limit, you can only set the soft limit to be less than the hard limit. To be clear, the hard limit applies only to non-privileged processes, i.e., processes whose effective user ID is not 0. Processes with a privileged level (with the property CAP_SYS_RESOURCE) and soft limit have only a kernel upper limit.
We can look at the output of the following two commands.

sishen@sishen:~$ ulimit -c -n -s
core file size (blocks, -c) 0
open files (-n) 1024
stack size (kbytes, -s) 8192
sishen@sishen:~$ ulimit -c -n -s -H
core file size (blocks, -c) unlimited
open files (-n) 1024
stack size (kbytes, -s) unlimited

-h indicates that the hard limit is displayed. The result shows the difference between soft limit and hard limit. Unlimited represents no limit, the maximum value of the kernel.
There are two methods for reading changes to the resouce limit.
* use the shell built-in command ulimit
* use the getrlimit and setrlimit apis
Ulimit is the resouce limit that changes the shell and achieves the resouce limit effect (child process inheritance) that changes the process that the shell starts.

usage : ulimit [-SHacdefilmnpqrstuvx [limit]]

When you do not specify limit, the command displays the current value. The important thing to note here is that when you want to modify limit, if you don't specify -s or -h, the default is to set both soft limit and hard limit. That is, you can only subtract and not increase when you set it later. Therefore, it is recommended to use ulimit to set the limit parameter to plus -s.
getrlimit and setrlimit Is also very simple to use, manpage has a very clear description.

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);

Note that you are in the setrlimit and need to check for success to see if the new value exceeds the hard limit. In the following example, in the process of application running in the Linux system, the program will often encounter a sudden crash, which indicates that the Segmentation fault is caused by the SIGSEGV signal received by the application. This signal indicates that when the process has an invalid memory access, the default action upon receiving this signal is: terminate w/core. To terminate w/core is to generate a core file in the current directory of the process and copy the process's memory image into the core file, whose default name is "core" (an age-old feature of unix-like systems).

In fact, not only the SIGSEGV signal produces coredump, but also the following signals produce coredump: SIGABRT (abnormal termination), SIGBUS (hardware fault), SIGEMT (hardware fault), SIGFPE (arithmetic exception), SIGILL (illegal hardware instruction), SIGIOT (hardware fault), SIGQUIT, SIGSYS (invalid system call), SIGTRAP (hardware fault), etc. In the process of application running, the Linux system often encounters a sudden crash of the program, which indicates that the Segmentation fault is caused by the SIGSEGV signal received by the application. This signal indicates that when the process has an invalid memory access, the default action upon receiving this signal is: terminate w/core. To terminate w/core is to generate a core file in the current directory of the process and copy the process's memory image into the core file, whose default name is "core" (an age-old feature of unix-like systems).

In fact, not only the SIGSEGV signal produces coredump, but also the following signals produce coredump: SIGABRT (abnormal termination), SIGBUS (hardware fault), SIGEMT (hardware fault), SIGFPE (arithmetic exception), SIGILL (illegal hardware instruction), SIGIOT (hardware fault), SIGQUIT, SIGSYS (invalid system call), SIGTRAP (hardware fault), etc. For the resouce limit There are two ways to read a modification.
* use the shell built-in command ulimit
* use the getrlimit and setrlimit APIsetrlimit:

if (getrlimit(RLIMIT_CORE, &rlim)==0) {
  rlim_new.rlim_cur = rlim_new.rlim_max = RLIM_INFINITY;
  if (setrlimit(RLIMIT_CORE, &rlim_new)!=0) {
    rlim_new.rlim_cur = rlim_new.rlim_max = rlim.rlim_max;
    (void) setrlimit(RLIMIT_CORE, &rlim_new);
  }
}


Related articles: