Process descendants

containerforkprocesssignals

I'm trying to build a process container. The container will trigger other programs. For example – a bash script that launches running background tasks with '&' usage.

The important feature I'm after is this: when I kill the container, everything that has been spawned under it should be killed. Not just direct children, but their descendants too.

When I started this project, I mistakenly believed that when you killed a process its children were automatically killed too. I've sought advice from people who had the same incorrect idea. While it's possible to catch a signal and pass the kill on to children, that's not what I'm looking for here.

I believe what I want to be achievable, because when you close an xterm, anything that was running within it is killed unless it was nohup'd. This includes orphaned processes. That's what I'm looking to recreate.

I have an idea that what I'm loooking for involves unix sessions.

If there was a reliable way to identify all the descendants of a process, it would be useful to be able to send them arbitrary signals, too. e.g. SIGUSR1.

Best Answer

If you send a signal to a process, that process gets killed. I wonder how the rumor that killing a process also kills other processes got started, it seems particularly counter-intuitive.

There are, however, ways to kill more than one process. But you won't be sending a signal to one process. You can kill a whole process group by sending a signal to -1234 where 1234 is the PGID (process group ID), which is the PID of the process group leader. When you run a pipeline, the whole pipeline starts out as a process group (the applications may change this by calling setpgid or setpgrp).

When you start processes in the background (foo &), they are in their own process group. Process groups are used to manage access to the terminal; normally only the foreground process group has access to the terminal. The background jobs remain in the same session, but there's no facility to kill a whole session or even to enumerate the process groups or processes in a session, so that doesn't help much.

When you close a terminal, the kernel sends the signal SIGHUP to all processes that have it as their controlling terminal. These processes form a session, but not all sessions have a controlling terminal. For your project, one possibility is therefore to start all the processes in their own terminal, created by script, screen, etc. Kill the terminal emulator process to kill the contained processes (assuming they haven't seceded with setsid).

You can provide more isolation by running the processes as their own user, who doesn't do anything else. Then it's easy to kill all the processes: run kill (the system call or the utility) as that user and use -1 as the PID argument to kill, meaning “all of that user's processes”.

You can provide even more isolation, but with considerably more setup by running the contained processes in an actual container.

Related Question