0

I have the following situation: (The following functions are ones taken from python)

I have a process A which is running and has a cgroup memory limit set on it.

I fork a child process from A using os.fork(). Let us call it B. Then I execute os.execvp to load a shell script inside B. As per http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/exec.html this process runs in the same address space as the caller (i.e. B).

The shell script running in B creates a Java program which runs idefinitely with a given heap size and automatic kill on OOM. This is achieved by passing -XX:OnOutOfMemoryError='kill -9 %p' to the java command. This creates another process C as child of B.

Looking from top, I see B as child of A and C as child of B as expected.

Below are the doubts:

  1. Does the cgroup limit apply on only A or (A+B) or (A+B+C)?

  2. If memory limit is reached, which all process are killed: A or (A+B) or (A+B+C)? And why? Is it identified using process pids or addresses space of the process on which limit is applied?

  3. If in the above point, not all the process are killed is there a way to fine-tune cgroup setting to kill all the child processes as well since we would be left with orphaned processes in such cases?

I am working on Centos7 as the underlying operating system.

  • One clarification, you say "As per ... this process runs in the same address space as the caller (i.e. A)." That's not correct. If B execs a shell to run a script, then the shell replaces B in B's address space, not A's. – Andy Dalton Nov 27 '19 at 3:44
  • Got it. Thanks for the clarification @AndyDalton – likecs Nov 28 '19 at 5:20
1

I'll address each of your questions:

  1. The cgroup applies to A and any descendants of A. You can experiment to verify this behavior. Consider:
Create a new memory cgroup
# mkdir /sys/fs/cgroup/memory/example

Note the shell's PID:
# echo $$
679

Put the running shell into the new cgroup
# echo $$ > /sys/fs/cgroup/memory/example/cgroup.procs

Examine what processes are in the cgroup.  Here 679 was the
shell's PID; 723 is the pid of cat
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
723

Start a new shell and note its PID
# bash
# echo $$
726

Examine what processes are in the cgroup.  679 was the original
shell.  726 is the second shell.  731 is cat:
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
726
731
  1. According to the memory cgroup documentation:

When a cgroup goes over its limit, we first try to reclaim memory from the cgroup so as to make space for the new pages that the cgroup has touched. If the reclaim is unsuccessful, an OOM routine is invoked to select and kill the bulkiest task in the cgroup.

Based on that, it doesn't kill all the processes in the cgroup; it picks the one consuming the most memory.

  1. I don't see a way to tune which process gets killed to match what you're asking here. There is a way to have some control over the OOM killer; see for example this Linux Weekly News Article. That said, if one of the parent processes gets killed, any child processes it had get reparented to the process with PID = 1 (by default).
| improve this answer | |
  • Thanks a lot of the example. – likecs Nov 28 '19 at 5:20
  • I don't know the details but /proc/$PID/oom* allow you to configure the order in which processes get killed. – Hauke Laging Apr 24 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.