Process Resource Limits

 

36.2 — Process Resource Limits
Introduction: What Limits Are, Why They Matter, ulimit, /proc/PID/limits | EmbeddedPathashala

What Is a Resource Limit?

A resource limit is a per-process cap that the kernel enforces on how much of a particular resource a process may consume. When a process hits a resource limit, the kernel takes action — typically by sending a signal to the process or by causing a system call to fail with an error.

Resource limits are the operating system’s mechanism for protecting the system against greedy or buggy processes. Without them, a single runaway process could consume all available memory, open thousands of files, spawn infinite child processes, or run forever consuming all CPU — destroying the stability of every other process on the machine.

Why Resource Limits Are Important

System Stability

Without limits, one poorly written process can starve all others of memory (OOM killer), file descriptors (EMFILE), or CPU time. Limits enforce isolation.

Security Sandbox

Before exec()-ing untrusted code, a parent sets tight resource limits so the child cannot harm the system regardless of what the code does.

User Quotas

System administrators use shell limits (ulimit) to prevent any single user from monopolising the machine’s resources in a multi-user environment.

Embedded Reliability

In embedded Linux systems running 24×7, resource limits prevent gradual resource leaks (file descriptors, memory) from silently degrading the system over days or weeks.

Setting Limits from the Shell — ulimit

The shell provides a built-in command to set and view resource limits. In bash and the Korn shell this command is ulimit. In the C shell it is limit. These commands call setrlimit() internally. Limits set in the shell are inherited by every command the shell runs.

# View all current limits
$ ulimit -a

# View soft stack size limit
$ ulimit -s

# Set soft stack size to 16 MB (in KB for ulimit)
$ ulimit -s 16384

# Set hard core dump size (0 = disabled)
$ ulimit -H -c 0

# Set maximum open files to 4096
$ ulimit -n 4096

# Set CPU time limit to 60 seconds
$ ulimit -t 60

# View NPROC (max processes per user)
$ ulimit -u
⚠️ Unit mismatch: The shell’s ulimit command uses kilobytes for memory-related limits (stack, data, address space), but getrlimit() and setrlimit() work in bytes. Always check which unit you are in. For example, ulimit -s 8192 means 8 MB stack, but setrlimit(RLIMIT_STACK, …) would use 8388608 (bytes).

Viewing Limits in /proc/PID/limits

Since Linux kernel 2.6.24, you can view all resource limits for any process by reading its /proc/PID/limits file. This is a Linux-specific feature — not available on other UNIX systems.

# View your own process limits
$ cat /proc/self/limits

# Sample output:
Limit                     Soft Limit   Hard Limit   Units
Max cpu time              unlimited    unlimited    seconds
Max file size             unlimited    unlimited    bytes
Max data size             unlimited    unlimited    bytes
Max stack size            8388608      unlimited    bytes
Max core file size        0            unlimited    bytes
Max resident set          unlimited    unlimited    bytes
Max processes             3569         3569         processes
Max open files            1024         4096         files
Max locked memory         65536        65536        bytes
Max address space         unlimited    unlimited    bytes
Max file locks            unlimited    unlimited    locks
Max pending signals       3569         3569         signals
Max msgqueue size         819200       819200       bytes
Max nice priority         0            0
Max realtime priority     0            0
Max realtime timeout      unlimited    unlimited    us
Permissions: The /proc/PID/limits file is owned by the real user ID of the process. Only that user (or root) can read it.

Code Example — Reading /proc/self/limits Programmatically

#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

/* Print limits for a few key resources using getrlimit() */
void show_limit(const char *name, int resource)
{
    struct rlimit rl;
    if (getrlimit(resource, &rl) == -1) {
        perror("getrlimit"); return;
    }
    printf("%-25s soft=", name);
    if (rl.rlim_cur == RLIM_INFINITY) printf("unlimited");
    else printf("%-12lld", (long long)rl.rlim_cur);
    printf("  hard=");
    if (rl.rlim_max == RLIM_INFINITY) printf("unlimited");
    else printf("%lld", (long long)rl.rlim_max);
    printf("\n");
}

int main(void)
{
    printf("%-25s %-13s  %s\n", "Resource", "Soft Limit", "Hard Limit");
    printf("%s\n", "-----------------------------------------------------------");

    show_limit("RLIMIT_AS (virt mem)",  RLIMIT_AS);
    show_limit("RLIMIT_CORE",           RLIMIT_CORE);
    show_limit("RLIMIT_CPU (seconds)",  RLIMIT_CPU);
    show_limit("RLIMIT_DATA",           RLIMIT_DATA);
    show_limit("RLIMIT_FSIZE",          RLIMIT_FSIZE);
    show_limit("RLIMIT_NOFILE",         RLIMIT_NOFILE);
    show_limit("RLIMIT_NPROC",          RLIMIT_NPROC);
    show_limit("RLIMIT_STACK",          RLIMIT_STACK);

    return 0;
}

/*
 * Compile: gcc -o show_limits show_limits.c
 * Run:     ./show_limits
 *
 * This is more precise than reading /proc/self/limits because
 * it uses the exact API values in bytes, not kilobytes.
 */

Interview Questions

Q1. What is a resource limit and why does the kernel enforce it?

A resource limit is a per-process cap on how much of a system resource (CPU time, memory, file descriptors, etc.) a process may consume. The kernel enforces it to protect system stability, prevent monopolisation of shared resources, provide security sandboxing when exec()-ing untrusted code, and implement multi-user fairness policies.

Q2. What shell command is used to view and set resource limits, and what system call does it use internally?

ulimit in bash and the Korn shell (limit in C shell). Internally it calls setrlimit() to set limits and getrlimit() to read them. Limits set with ulimit are inherited by all processes the shell forks.

Q3. Since which kernel version can you view all resource limits for a process via /proc?

Since Linux 2.6.24. The file /proc/PID/limits shows all soft and hard limits for the process identified by PID. It is owned by the process’s real user ID and readable only by that user or root.

Q4. The shell ulimit command and getrlimit() use different units for memory limits. Explain.

ulimit (bash) expresses memory limits like stack size and data segment in kilobytes. The getrlimit() and setrlimit() system calls work in bytes. For example, ulimit -s 8192 sets 8 MB stack, which corresponds to 8388608 bytes in getrlimit(). You must be careful when converting between the two representations.

Leave a Reply

Your email address will not be published. Required fields are marked *