Alexis Wilke Alexis Wilke - 1 year ago 38
C Question

Is there a programmatic way in C to determine the number of processes ever used in a group of processes under Linux?

I know of the

function that returns a
parameter representing the total number of processes currently running on your Linux system.

However, there is the
parameter to the
function that limit the number of child processes a process can have.

In order for the system to enforce that number, I would imagine it knows the current number of processes in that group. Is that number readily accessible?

Answer Source

To enforce the RLIMIT_NPROC limit, linux kernel reads &p->real_cred->user->processes field in copy_process function (on fork() for example)

 1371         if (atomic_read(&p->real_cred->user->processes) >=
 1372                         task_rlimit(p, RLIMIT_NPROC)) {

or in sys_execve (do_execveat_common in fs/exec.c):

1504    if ((current->flags & PF_NPROC_EXCEEDED) &&
1505        atomic_read(&current_user()->processes) > rlimit(RLIMIT_NPROC)) {
1506        retval = -EAGAIN;
1507        goto out_ret;

So, if the processes is larger than RLIMIT_NPROC, function will fail. This field is defined as part of struct user_struct (accessed with struct cred real_cred in sched.h as

 atomic_t processes;    /* How many processes does this user have? */

So the process count accounting is per-user.

There is decrement of the field in copy_process in case of fail:

1655 bad_fork_cleanup_count:
1656    atomic_dec(&p->cred->user->processes);

And increment of the field is in copy_cred:

313 /*
314 * Copy credentials for the new process created by fork()
315 *
316 * We share if we can, but under some circumstances we have to generate a new
317 * set.
318 *
319 * The new process gets the current process's subjective credentials as its
320 * objective and subjective credentials
321 */
322 int copy_creds(struct task_struct *p, unsigned long clone_flags)

339         atomic_inc(&p->cred->user->processes);

372 atomic_inc(&new->user->processes);

man page says that it is per-user limit:

          The maximum number of processes (or, more precisely on Linux,
          threads) that can be created for the real user ID of the
          calling process.  Upon encountering this limit, fork(2) fails
          with the error EAGAIN.