9 ms·
The history of sending signals to Unix process groups
- killpg 4y agokillpg is my favorite syscall
- ur-whale 4y agoAll I ever wanted was to type ^C (or perhaps ^\) in my terminal and kill in one fell swoop all the shite that my previous shell-typed command spawned directly or indirectly. This, IIRC used to be the standard behavior back in the days, but in recent years, for some reasons, things have not been so simple. Looking at the man page of ps(1) sort of starts to elucidate the effing mess that the name "group" summons the in unix process world. Are we talking about the real group id (RGID), the effective group id (EGID), the controlling progress group id (TPGID), the control group (CGROUP) the textual group id (EGROUP), the filesystem group id (FGID), the textual filesystem group id (FGID), the process id of the process group leader (PGID), the saved group id (SGID), the session id (SID), the supplementary group id (SUPGID), the thread group id (TGID) ? I'm pretty sure I'm missing some. What an effing mess.
- yrro 4y agoSee https://man7.org/linux/man-pages/man7/credentials.7.html https://man7.org/linux/man-pages/man7/credentials.7.html and https://www.gnu.org/software/libc/manual/html_node/Job-Control.html https://www.gnu.org/software/libc/manual/html_node/Job-Contr...
- ur-whale 4y agoI rest my case.
- throwawaylinux 4y ago> This, IIRC used to be the standard behavior back in the days, Catching SIGINT and detaching from the controlling terminal are pretty old concepts.
- bandie91 4y ago> kill [...] shell-typed command spawned directly or indirectly are you sure? let's assume you typed "service httpd start". it starts the init script which starts the httpd in the background. IMO most in use-cases you don't want to kill everything ever forked from the current shell.
- JdeBP 4y agoAs well as getting how "service" commands operate wrong, you are conflating a "background" process associated with a TTY with a daemon. Some "service" commands work the way that you describe. But that is actually a bug. A properly designed "service" command does not execute as some direct or indirect parent process of the eventual "httpd" process. The "service" command runs in a login session. A daemon has (at least as an intention) no association with a TTY. The daemon process runs in a context that has never been tainted by any of the various things associated with login sessions. * http://jdebp.info./Softwares/nosh/bsd-service-command.html http://jdebp.info./Softwares/nosh/bsd-service-command.html
- Kinrany 4y agoThe word "group" smells of an anti-pattern in any context to me.
- smilliken 4y agoI agree in spirit, but here's one of the most successful abstractions of all time: https://en.m.wikipedia.org/wiki/Group_(mathematics) https://en.m.wikipedia.org/wiki/Group_(mathematics)
- oconnor663 4y agoIf anyone can suggest an update to https://github.com/oconnor663/duct.py/blob/master/gotchas.md#killing-grandchild-processes https://github.com/oconnor663/duct.py/blob/master/gotchas.md..., please let me know. As far as I'm aware, there's still no reliable way to kill a tree of processes on Unix that's suitable for library code.
- teddyh 4y ago> Linux is in the middle of adding new APIs like pidfd_send_signal, but none of them are aimed at improving the situation with grandchildren. Maybe Linux should implement something like pidfd_getpfd() (returning the PID FD of the parent process) and pidfd_fork() (returning the PID FD of the child process).
- teddyh 4y agoWhen killing an entire cgroup, you might avoid the PID reuse race by getting a list of PIDs in a cgroup, then for each PID, first opening a PIDFD to that PID, check via that PIDFD whether it’s a member of the correct cgroup, and then killing the PIDFD using pidfd_send_signal(). This way, no process can be killed inadvertently by PID reuse. There may be a better way to do this, but one way might be to open() /proc/<PID> and use the resulting FD to both to check /proc/<PID>/cgroup (using openat(FD, "cgroup", O_RDONLY|O_NOCTTY)) and then use the same FD as a PIDFD when calling pidfd_send_signal(). ISTM that systemd should use this method if its current method is just looping over PIDs.
- Arnavion 4y agoMight be easier to freeze the cgroup, send the signals, then unfreeze. Only danger there is that it needs to not be reentrant. Edit: Indeed both your and my methods were proposed to systemd: https://github.com/systemd/systemd/issues/13101 https://github.com/systemd/systemd/issues/13101 It's just waiting for someone to implement it.
- deleted 4y ago[deleted]
- tych0 4y ago
- ddevault 4y agoProcess groups and job control is a huge fucking mess on Unix. Process groups, job control, and signals are probably the biggest mistakes of Unix's design. Arguably fork(2) as well, but that'll probably raise some eyebrows. The blame for Berkley sockets and ioctls can't entirely be laid at Unix's feet, but they're also quite the mess.
- roblabla 4y agoHuh, I can understand labeling all of those are messes, but what's wrong with Berkeley sockets? The API seems fairly straightforward, and has managed to withstand the test of time pretty well. I'm curious what grievances you have with it?
- HowardStark 4y agoThe fact that strict aliasing has to be broken to use the API shows that, amongst other things, the API is from a different era of practicality over correctness. In the past, people have popped up to say “but that’s only in the bind() implementation side” (when talking about `sockaddr`, for instance) but I find this argument amusing. At the end of the day, if something breaks because of this, that nuance is lost amidst the mass of frustration.
- gnubison 4y agoAre you sure? My impression from e.g. https://stackoverflow.com/questions/13210239/can-a-c-compiler-add-padding-before-the-first-element-in-a-structure https://stackoverflow.com/questions/13210239/can-a-c-compile... is that it’s alright to cast between a pointer to a struct and a pointer to its first member.
- roblabla 4y agoAh, I hadn't considered the whole sockaddr/sockaddr_storage/sockaddr_in/sockaddr_un... thing, yeah that's a mess. I guess a more modern API would either use opaque pointers or an union (though that has its own share of disadvantages). Thanks for bringing this up!
- 4y ago
- bluetomcat 4y agoIt’s a mess that originates from the dated concept of terminals and that users are necessarily bound with interactive sessions from them. Without the notion of terminals and special control sequences, process hierarchy control can be much simpler and more orthogonal. A “signal” would be sent to the leaf processes in the hierarchy first, then they terminate, notifying their parent and so on.
- zozbot234 4y ago> It’s a mess that originates from the dated concept of terminals and that users are necessarily bound with interactive sessions from them. The concept has been revived (in a notoriously clunky way that's likely not directly compatible with previous facilities) via multiseat support in more recent Linux distributions.
- JdeBP 4y agoIf one is familiar with POSIX and why it is how it is, one knows that the reason that POSIX has both sessions and process groups is that "sessions" pretty much descend from AT&T System 3 process groups and "process groups" descend from BSD process groups; so one would indeed have expected that there were two separate ideas of "process group". Things that this history does not cover include System 5 Release 2 "shell layers". Shell layers multiplexed virtual terminals onto a single physical terminal, preceding its obvious successors screen by somewhere around three years, and tmux by about quarter of a century. The popularity of tmux and screen nowadays shows that the BSD job control mechanism did not entirely kill off the vision of shell layers, as I recall people thinking it had at the time.
- amelius 4y agoQuestion: can we control a Linux process (with all its threads, signal handlers etc.) in a completely deterministic way, e.g. by using ptrace() on it?
- rollcat 4y agoSorry for no references, it's off the top of my head. There were past attempts at confining / "jailing" processes based on ptrace, it ended up being racey and/or escapeable. If you're relying on cooperation for isolation, you're back to square 1.
- sporksmith 4y agoYes. Though I'm not sure I see the connection to the OP...? The example I'm most familiar with, because I work on it, is Shadow. We used ptrace for a bit but now use seccomp. https://github.com/shadow/shadow/ https://github.com/shadow/shadow/