叉炸弹清理后的最佳方法是什么?


21
$ ls
bash: no more processes

哦哦 好像有人制造了叉子炸弹。在我以前工作的地方,这几乎意味着共享服务器需要重新启动,因为即使具有root用户的sysadmin管理员也常常无法解决问题。通常,他们甚至无法获得提示。

我听说过一些技巧(值得注意的是,发送STOP信号而不是KILL信号,因为后者可以使其余线程立即替换被杀死的线程),但是我从未见过全面的指南,标题为“ So,You Have Yourself”一个叉子炸弹?

让我们做一个。

Answers:


10

使用ulimit防止每个用户使用合理的进程限制来限制fork炸弹耗尽进程限制。

这样,单个用户将在达到系统限制之前就用尽他们的进程配额。


6

要尝试的第一件事是让已登录的用户注销。他们的shell可能是执行所有派生的流程的父流程,这可能会解决问题。

如果这不起作用,则可以尝试kill -STOP -2以root身份运行以冻结以root以外的任何用户身份运行的所有进程。如果可行,则可以kill -CONT <pid>用来解冻与分叉炸弹无关的某些已知进程,并杀死它们以消除整个进程表的问题,并为您提供喘息的空间来查找并消除问题的原始来源。Sendmail将是杀死系统进程的一个很好的例子,因为通过使用.pid文件标识pid可以很容易地确定它。例如,kill -CONT $(< /var/run/sendmail.pid); kill $(< /var/run/sendmail.pid)


您在哪个操作系统上看到“ -2”选项可以杀死?我在Linux的手册页中没有看到它。
raldi

1
当您为pid指定一个负值时,这应该适用于大多数操作系统。如果<pid>小于-1,则将kill发送到进程组-<pid>中的每个进程。向pid -2发送STOP信号,它应该停止所有不是特殊系统进程或root拥有的进程的进程。

有关杀死“负pid”的信息,请参见kill(2)联机帮助页,但我仍然不相信这可行。为什么所有非初始化进程都在组2中?我知道您想避免使用init,因为停止它的结果通常是非常致命的,但是……
短暂的

@ ephemient,2太低而不能成为进程组标识,因此它可能是另一个特殊值。
joshudson


3

不确定如何发送STOP信号,因为生成kill将需要可用的进程句柄。此外,以我的经验,系统早在进程耗尽之前就已变得过载且无法使用。

您是否考虑过通过强制执行每个用户的流程限制ulimit?这将阻止您的用户(意外地或不正确地)发射叉炸弹。


3
kill是至少在bash中内置的shell。
raldi

1
我认为这是一个关键组件-确定您选择的shell的内建函数。

2
如果不是内置的,则可以运行“ exec kill PID”,它不会派生。但这是有风险的,因为如果不起作用,您可能将无法获得另一个外壳。可以将其视为系统管理的“蜂刺”方法!
斯蒂芬·达灵顿,

2

一些BSD系统具有为根保留最后5个左右进程的能力。也许您的系统具有该功能。


3
您如何实际配置系统来执行此操作?
Nik Reiman,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.