Live data from Hacker News

Killing a process and all of its descendants

morningcoffee.io

11–20 of 76 posts

Re: Killing a process and all of its descendants

#12
post #8

Earlier quoted context omitted.

That is getting considerably easier with the addition of pidfds, though: https://lwn.net/SubscriberLink/794707/93ffb35438fd3710/

Posted 1 week ago! Do you know what took them so long to realize this is the correct way to do it? Windows has had it for some two decades...

Unfortunately, as Linux has matured, many of its developers refuse to adapt technologies for the sole reason that it "stinks" of Microsoft.

Cutler and his team were pretty forward thinking given that NT is over 30 years old. See also: the async i/o headaches and the inability to WaitForSingleObject()/WaitForMultipleObjects() (or an analogue) in Linux.

It's a shame really.

Re: Killing a process and all of its descendants

#13
post #9
post #3

This is why cgroups were invented. They solve this problem. Start a process in its own cgroup, and you can later confidently kill the process and all of its descendants. Container "technologies" use cgroups extensively, as does systemd service management.

That's definitely the correct way to do this today. But even then `kill -9 $(< /sys/fs/cgroup/systemd/tasks)` is not enough if your goal is to reliably kill all processes because that's not atomic. Instead you'll have to freeze all processes, send SIGKILL and then unfreeze.

Can freezing be done atomically?

Re: Killing a process and all of its descendants

#14
post #8
post #2

Even waiting for a process to exit is surprisingly hard (impossible?) in Linux, unless it's your child.

That is getting considerably easier with the addition of pidfds, though: https://lwn.net/SubscriberLink/794707/93ffb35438fd3710/

> Beyond the ability to unambiguously specify which process should be waited for, this change will eventually enable another interesting feature: it will make it possible to wait for a process that is not a child — something that waitid() cannot do now. Since a pidfd is a file descriptor, it can be passed to another process via an SCM_RIGHTS datagram in the usual manner. The recipient of a pidfd will, once this functionality is completed, be able to use it in most of the ways that the parent can to operate on (or wait for) the associated process.

So, to wait for a process that is not your child, do you have to get the relevant pidfd from its parent? In which case, this doesn't help all that much. Or is there some other way to get pidfds for arbitrary processes?

Re: Killing a process and all of its descendants

#15
post #14
post #8

Earlier quoted context omitted.

That is getting considerably easier with the addition of pidfds, though: https://lwn.net/SubscriberLink/794707/93ffb35438fd3710/

> Beyond the ability to unambiguously specify which process should be waited for, this change will eventually enable another interesting feature: it will make it possible to wait for a process that is not a child — something that waitid() cannot do now. Since a pidfd is a file descriptor, it can be passed to another process via an SCM_RIGHTS datagram in the usual manner. The recipient of a pidfd will, once this funct…

Perhaps pidfd_open(pid, ...)? https://lwn.net/Articles/789023/

I find it bizarre they called it "pidfd_" rather than just "process_" or "proc_"... almost seems like they deliberately avoided the obvious?

Re: Killing a process and all of its descendants

#16
post #13
post #9

Earlier quoted context omitted.

That's definitely the correct way to do this today. But even then `kill -9 $(< /sys/fs/cgroup/systemd/tasks)` is not enough if your goal is to reliably kill all processes because that's not atomic. Instead you'll have to freeze all processes, send SIGKILL and then unfreeze.

Can freezing be done atomically?

Not sure to be honest. From the documentation: "Writing "FROZEN" to the state file will freeze all tasks in the cgroup". Even if not, it should still be sufficient once all tasks are frozen: If you then send SIGKILL to all processes in the group, no fork bomb or similar process kerfuffle will be able to avoid being killed once they get unfrozen.

Re: Killing a process and all of its descendants

#17
post #13
post #9

Earlier quoted context omitted.

That's definitely the correct way to do this today. But even then `kill -9 $(< /sys/fs/cgroup/systemd/tasks)` is not enough if your goal is to reliably kill all processes because that's not atomic. Instead you'll have to freeze all processes, send SIGKILL and then unfreeze.

Can freezing be done atomically?

Semantically it shouldn't be necessary I think?

Re: Killing a process and all of its descendants

#20

Earlier quoted context omitted.

Posted 1 week ago! Do you know what took them so long to realize this is the correct way to do it? Windows has had it for some two decades...

Unfortunately, as Linux has matured, many of its developers refuse to adapt technologies for the sole reason that it "stinks" of Microsoft. Cutler and his team were pretty forward thinking given that NT is over 30 years old. See also: the async i/o headaches and the inability to WaitForSingleObject()/WaitForMultipleObjects() (or an analogue) in Linux. It's a shame really.

re: WaitForMultipleObjects, finally something like that is likely coming to Linux:

https://www.reddit.com/r/linux/comments/ck77gm/valve_propose...

> It's a shame really.

Well, yes, and of course, yet at the same time it's FOSS, so ... if someone really needed it, they should have proposed a patch. ¯\_(ツ)_/¯

Post reply on HN