Jaki jest najlepszy sposób na posprzątanie po bombie widelca?

21
$ ls
bash: no more processes

O o. Wygląda na to, że ktoś zrobił bombę widelcową. Tam, gdzie kiedyś pracowałem, oznaczało to w zasadzie, że serwer współużytkowany musiałby być poddawany cyklom zasilania, ponieważ nawet sysadmini z rootem często nie potrafili rozwiązać problemu. Często nawet nie mogli uzyskać monitu.

Słyszałem kilka sztuczek (w szczególności wysyłanie sygnałów STOP zamiast sygnałów ZABÓJ, ponieważ te ostatnie pozwoliłyby pozostałym wątkom na natychmiastowe zastąpienie zabitych), ale nigdy nie widziałem wyczerpującego przewodnika zatytułowanego So, You Have Yourself widelec bomba?

Zróbmy jeden.

raldi
źródło

Odpowiedzi:

10

Zapobiec bombę widelca wyczerpaniu limitu procesu z rozsądnym na granicy proces użytkownika za pomocą ulimit .

W ten sposób pojedynczy użytkownik wyczerpie swój limit procesów na długo przed osiągnięciem limitu systemu.

Chris Smith
źródło
6

Pierwszą rzeczą do wypróbowania byłoby skłonienie zalogowanych użytkowników do wylogowania. Możliwe, że ich powłoka może być nadrzędnym procesem wykonującym wszystkie rozwidlenia, co może zakończyć problem.

Jeśli to nie zadziała, możesz spróbować uruchomić kill -STOP -2jako root, aby zamrozić wszystkie procesy uruchomione jako dowolny użytkownik inny niż root. Jeśli to zadziała, możesz użyć kill -CONT <pid>do odblokowania niektórych znanych procesów niezwiązanych z bombą widelcową i zabić je, aby wyeliminować problem z pełną tabelą procesów i dać ci trochę czasu na odnalezienie i zabicie pierwotnego źródła problemu. Sendmail byłby dobrym przykładem procesu systemowego do zabicia, ponieważ można go łatwo zidentyfikować za pomocą pliku .pid do identyfikacji pid. Na przykład kill -CONT $(< /var/run/sendmail.pid); kill $(< /var/run/sendmail.pid).


źródło
W jakim systemie operacyjnym widzisz opcję „-2” dla zabicia? Nie widzę tego na stronie podręcznika użytkownika w systemie Linux.
raldi
1
Powinno to działać w większości systemów operacyjnych, ponieważ określasz ujemną wartość dla pid. Jeśli <pid> jest mniejszy niż -1, to zabicie jest wysyłane do każdego procesu w grupie procesów - <pid>. Wysyłanie sig STOP do pid -2 powinno zatrzymać wszystkie procesy, które nie są specjalnymi procesami systemowymi lub procesami root.
Zobacz stronę manuala kill (2) za zabicie „negatywnego pid”, ale nadal nie wierzę, że to działa. Dlaczego wszystkie procesy niezainicjowane byłyby w grupie 2? Rozumiem, że chciałbyś uniknąć init, ponieważ skutki jego zatrzymania są często śmiertelne, ale ...
efhemient
@ephemient, 2 jest zbyt niski, aby być identyfikatorem grupy procesów, więc może jest to kolejna specjalna wartość.
joshudson
@Joshua Nie ma żadnych specjalnych wartości obok 0i -1, zgodnie z opengroup.org/onlinepubs/009695399/functions/kill.html opengroup.org/onlinepubs/000095399/utilities/kill.html
ephemient
3

Nie jestem pewien, jak można wysłać sygnał STOP, ponieważ odrodzenie killwymagałoby dostępnego uchwytu procesu. Poza tym z mojego doświadczenia wynika, że ​​systemy stają się przeciążone i bezużyteczne na długo przed wyczerpaniem się procesów.

Czy rozważałeś po prostu egzekwowanie limitów procesów na użytkownika ulimit? Uniemożliwiłoby to użytkownikom uruchomienie bomb widłowych (przypadkowo lub nie).

John Millikin
źródło
3
kill to wbudowana powłoka, przynajmniej w bash.
raldi
1
Myślę, że to kluczowy element - zidentyfikuj wbudowane opcje dla wybranej powłoki.
2
Jeśli nie jest wbudowany, możesz uruchomić „exec kill PID”, który nie rozwidla się. Ale jest to ryzykowne, ponieważ jeśli to nie zadziała, możesz nie być w stanie zdobyć innej powłoki. Pomyśl o tym jak o podejściu pszczół do administracji systemem!
Stephen Darlington
2

Niektóre systemy BSD mają możliwość zarezerwowania ostatnich 5 procesów dla rootowania. Może twój system ma tę zdolność.

Joshudson
źródło
3
Jak faktycznie skonfigurować system, aby to zrobić?
Nik Reiman