Шышел-мышел-вышел!
2012-01-20 10:45 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Давным-давно в компании М жил да был сервер. И было у него три сына два админа. Оба, что характерно, умных.
А на сервере жили-были процессы. Их там было много - с десяток, а может даже два. Все они были однотипными, и представляли из себя что-то вроде workflow processor-ов. Что именно они делали - не суть важно, так как история совсем не про это.
А история - про странную чертовщину, которая творилась с этими процессами. Время от времени, после смены конфигурации, какой-то из этих процессов надо было перезапускать. И админы всегда делали это очень неохотно. А все потому, что после перезапуска одного из процессов неприменно подыхало еще несколько. Иногда один, иногда два, иногда - все сразу, и админам, чертыхаясь, приходилось в спешке наводить порядок.
Однако же, если вскоре после подобного происшествия процесс снова необходимо было перезапустить, никакой подобной фигни не происходило.
Админы запаслись бубном побольше, и перед каждым перезапуском усердно стучали в него. Ну и, конечно, следили, чтобы все процессы были более-менее idle непосредственно перед перезапуском - если даже что и подохнет, то хоть без особых последствий.
Впрочем, со временем бубен пообтрепался, а терпение админов - поистощилось. И они стали разбираться. А это был самый что ни на есть Ынтерпрайз Софт, и все у него было большое - и админ. скрипты, и исходники, и руководство пользователя.
Ничего не найдя в руководстве (а вдруг есть "export DONT_KILL_OTHER=1"?), админы полезли в скрипты запуска и останова. Но и там не нашлось ни pkill, ни killall, ни прочего оружия массового уничтожения. Тогда админы полезли в исходники. Тридцать дней и три ночи лазили они по исходникам, и в конце концов нашли такое ...
Чтобы не оставлять после себя зомбей и детей-сирот, каждый процесс вел строгий учет порожденных подпроцессов. После каждого fork-а PID порожденного процесса записывался в специальный массив, а после завершения "ребенка" - удалялся из массива. Если же было необходимо выполнить перезапуск, то процесс добросовестно пытался всех своих "деток" придушить, чтобы они не достались злому init-у.
Да вот беда - в коде был баг, из-за которого PID-ы вычеркивались из списка только в случае завершения порожденного процесса с ошибкой.
В результате у каждого "родительского" процесса за время работы накапливался немерянный "черный список" когда-то кому-то принадлежавших PID-ов, которые они при завершении пытались добросовестно прибить.
Естественно, из-за переиспользования PID-ов на момент перезапуска вполне могли существовать какие-то другие, совершенно посторонние процессы, PID-ы которых были в "черном списке". И тут начиналась лотерея: как только перезапускаемый процесс пытался прибить что-то, что ему "не по зубам" (процесс root-а или какого-то другого пользователя), он получал EPERM и больше никого убивать не пытался. Но до прихода EPERM он вполне мог прибить пару-тройку процессов-родственников (так как все крутилось под одним пользователем).
А у каждого из убиенных родственничков был свой "черный список" ...
Мораль придумайте сами
А на сервере жили-были процессы. Их там было много - с десяток, а может даже два. Все они были однотипными, и представляли из себя что-то вроде workflow processor-ов. Что именно они делали - не суть важно, так как история совсем не про это.
А история - про странную чертовщину, которая творилась с этими процессами. Время от времени, после смены конфигурации, какой-то из этих процессов надо было перезапускать. И админы всегда делали это очень неохотно. А все потому, что после перезапуска одного из процессов неприменно подыхало еще несколько. Иногда один, иногда два, иногда - все сразу, и админам, чертыхаясь, приходилось в спешке наводить порядок.
Однако же, если вскоре после подобного происшествия процесс снова необходимо было перезапустить, никакой подобной фигни не происходило.
Админы запаслись бубном побольше, и перед каждым перезапуском усердно стучали в него. Ну и, конечно, следили, чтобы все процессы были более-менее idle непосредственно перед перезапуском - если даже что и подохнет, то хоть без особых последствий.
Впрочем, со временем бубен пообтрепался, а терпение админов - поистощилось. И они стали разбираться. А это был самый что ни на есть Ынтерпрайз Софт, и все у него было большое - и админ. скрипты, и исходники, и руководство пользователя.
Ничего не найдя в руководстве (а вдруг есть "export DONT_KILL_OTHER=1"?), админы полезли в скрипты запуска и останова. Но и там не нашлось ни pkill, ни killall, ни прочего оружия массового уничтожения. Тогда админы полезли в исходники. Тридцать дней и три ночи лазили они по исходникам, и в конце концов нашли такое ...
Чтобы не оставлять после себя зомбей и детей-сирот, каждый процесс вел строгий учет порожденных подпроцессов. После каждого fork-а PID порожденного процесса записывался в специальный массив, а после завершения "ребенка" - удалялся из массива. Если же было необходимо выполнить перезапуск, то процесс добросовестно пытался всех своих "деток" придушить, чтобы они не достались злому init-у.
Да вот беда - в коде был баг, из-за которого PID-ы вычеркивались из списка только в случае завершения порожденного процесса с ошибкой.
В результате у каждого "родительского" процесса за время работы накапливался немерянный "черный список" когда-то кому-то принадлежавших PID-ов, которые они при завершении пытались добросовестно прибить.
Естественно, из-за переиспользования PID-ов на момент перезапуска вполне могли существовать какие-то другие, совершенно посторонние процессы, PID-ы которых были в "черном списке". И тут начиналась лотерея: как только перезапускаемый процесс пытался прибить что-то, что ему "не по зубам" (процесс root-а или какого-то другого пользователя), он получал EPERM и больше никого убивать не пытался. Но до прихода EPERM он вполне мог прибить пару-тройку процессов-родственников (так как все крутилось под одним пользователем).
А у каждого из убиенных родственничков был свой "черный список" ...
Мораль придумайте сами
(no subject)
Date: 2012-01-20 11:16 pm (UTC)(пошёл переписывать парочку скриптов)
(no subject)
Date: 2012-01-20 11:22 pm (UTC)(no subject)
Date: 2012-01-20 11:54 pm (UTC)(no subject)
Date: 2012-01-21 02:09 am (UTC)(no subject)
Date: 2012-01-20 11:54 pm (UTC)(no subject)
Date: 2012-01-20 11:59 pm (UTC)(no subject)
Date: 2012-01-21 12:17 am (UTC)(no subject)
Date: 2012-01-21 12:20 am (UTC)(no subject)
Date: 2012-01-21 12:23 am (UTC)(no subject)
Date: 2012-01-21 12:25 am (UTC)(no subject)
Date: 2012-01-21 01:04 am (UTC)(no subject)
Date: 2012-01-21 05:23 pm (UTC)а ещё я не верил, что бывают системы без бекапов и логов. ан нет, бывают). и вот это осознание у меня приключилось на происшедший Новый 2012й Год). где-то так же я перестал верить в Деда Мороза.
(no subject)
Date: 2012-01-21 02:55 pm (UTC)(no subject)
Date: 2012-01-21 04:21 pm (UTC)LJournalist #1784
Date: 2012-01-28 08:15 am (UTC)LJournalist #1784
Date: 2012-01-28 08:15 am (UTC)