Hello all! I'm about to write quite a long-ish email, but I provide a small summary first for the "busy". :) == Quick summary The context is simple: * the developer wants to write a C application (call it a "controller") that spawns other child processes, which in their turn spawn other processes and so on; * some of these spawned processes might double fork (i.e. they daemonize); * these child processes are not written by the developer in question; (thus we can't "fix" them...) * the controller will run with no special privileges (i.e. non-root, no capabilities, etc.); * (for purely practical reasons, thus let's not start a flame war) we can assume a Linux-only environment, thus portability is not an issue; (the developer is also not scared in applying patches to the kernel...) The problem I try to find a solution to is again quite simple, how can the developer write the "controller" application such that the following happens: (A) any orphaned child of a sub-process (i.e. double forking ones, ones whose parent has exited, etc.) are reparented to the controller; (this is already solved in 3.4;) (B) the controller should be able to kill all its subprocesses (and their subprocesses, recursively); (C) if the controller dies (segfault, killed, etc.) all its subprocesses are terminated (and recursively so); Thus, what "magic" :) should one invoke to obtain the above? == Use cases To better put the problem into a context, the previous features would allow one to implement something like: * "personal" service control systems (like `systemd`, `runit`, `daemon-tools`, etc.); * constrain badly written `sh` scripts that if terminated leak processes; or build systems (like `make`), or SSH sessions, or cron jobs, etc.; * a building block in a PaaS underlaying; But certainly NOT for "security" purposes... == Existing primitives I've really tried thinking about this for the last year or so, and I've not managed to get a "good" enough solution... But I've found the following partial solutions, but all of them have issues... (1) `clone (CLONE_NEWPID)` -> solves all the problems, but has major drawbacks: * it requires special rights (root or capability); * it creates an alternative process namespace thus will confuse the hell out of scripts assuming PID equivalence... (2) `prctl (PR_SET_CHILD_SUBREAPER)` -> solves the issue (A) (reparenting), but that's it. (3) `prctl (PR_SET_PDEATHSIG)` -> solves the issue (C) (forced termination), but it has the following issues: * it works only for the first level of sub-processes, as it must be explicitly set after each `fork`; * thus it is not "inheritable" by new children; * it doesn't work for `setuid` processes (due to possible security issue); (4) `killpg (group)` -> solves the issue (B), but: * any child could choose to change its process group; * if the controller uses its own group it kills itself; Have I missed something? == Brainstorming It would have been nice if either of the following would happen (in order of preference): (a) maybe an additional `PR_SET_CHILD_SUBREAPER`-like flag that would make the controller process really behave like a sub-init, that is on its termination terminate all its children recursively; (b) `PR_SET_PDEATHSIG` would be inheritable at least for non `setuid` processes; (maybe even better if the signal is `SIGKILL` keep it even for `setuid` processes as I don't see too much harm there...) (c) have some way to send a signal to all a process children; (d) (last resort solution we have today) iterate through `/proc/$PID` and find all the controller children, SIGKILL them, and continue until no process is found, then die; but it doesn't solve (C)... Something else? Hope I find some solution to this... (If this is not the mailing list to send it to, please point me in the right direction.) Thanks in advance for feedback, Ciprian. _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies