Самый надежный способ завершить семейство процессов

Как лучше всего завершить семейство процессов в Linux, если предположить, что:

  1. произвольный процесс в семействе может быть убит/завершен до того, как мы сможем начать очистку; в результате, если дочерние процессы не завершатся, их PPID будет равен 1
  2. процессы могут изменять группы процессов

Конкретный сценарий, который я рассматриваю, — это Bash, но чем более общая техника, тем лучше.


person Tomek    schedule 22.06.2015    source источник


Ответы (1)


Возможно, вы захотите выполнить уничтожение (в конечном итоге с помощью сценария) в другой оболочке входа в систему, чтобы убедиться, что вы случайно не останавливаете/убиваете саму оболочку/скрипт, пытающийся выполнить полное уничтожение до того, как он завершит свою работу :)

Первая ключевая стратегия заключается в том, чтобы не завершать процесс напрямую, а:

  • просто сначала «заморозьте» его (с помощью kill -STOP <pid>), чтобы он не порождал других дочерних элементов (необходимо для надежного определения его дочерних элементов, иначе вы пропустите некоторые из них, как объясняется в этом вопросе и ответе: https://superuser.com/вопросы/927836/как-справиться-с-утечкой-разветвления-бомбы-памяти-на-linux/927967#927967)
  • добавить его в список процессов для завершения (позже)
  • найти список его детей
  • повторить всю историю о детях, затем повторить

Как только все дерево предков, основанное на ppid, будет заморожено, вы можете начать поиск и замораживание предков на основе групп процессов — вы по-прежнему можете надежно определять эти группы процессов, пока живы родительские процессы, которые изменили свою группу процессов (поскольку их ppid не изменяется) — добавьте эти группы в список pgids, которые нужно уничтожить, и заморозьте любые новые поддеревья процессов на основе ppid, которые вы можете найти в этих группах, как показано выше:

  • если их родители все еще живы, они уже должны быть заморожены, поскольку они находятся в замороженном дереве предков на основе ppid
  • если они сироты, их убьют, когда весь pgid будет взорван

Связанные процессы могут быть обнаружены по идентификатору сеанса способом, очень похожим на тот, который основан на идентификаторе группы (за исключением того, что уничтожение должно выполняться с помощью pid, поскольку команда уничтожения поддерживает идентификатор группы, но не идентификатор сеанса).

Другой способ найти потенциально связанные процессы — это их tty, если они есть. Но с осторожностью - они могут быть не потомками процесса, который вы хотите убить, а предками или братьями и сестрами. Вы по-прежнему можете заморозить найденные таким образом поддеревья и группы на основе ppid во время расследования — вы всегда можете «разморозить» их позже (с помощью kill -CONT), если их не нужно уничтожать.

Я не знаю, как найти поддеревья процессов-потомков, разделенных процессами, объявляющими себя лидерами сеансов (таким образом, меняя как их sid, так и pgid), если их родители умерли и у них нет pty.

Как только весь список поддеревьев заморожен, процессы могут быть остановлены (с помощью pid или pgid по мере необходимости) или разморожены для продолжения их работы, если это необходимо.

person Dan Cornilescu    schedule 23.06.2015
comment
Большое спасибо за совет! Я упустил тот факт, что некоторые процессы могут порождать новые, пока мы пытаемся их завершить. Вероятно, альтернативным способом завершения будет запуск интересующего дерева процессов в отдельном сеансе (через setsid) и уничтожение всех процессов в сеансе. Однако это не идеально, так как процесс может изменить свою сессию. У меня такое ощущение, что нужен какой-то цикл, который бы гарантировал, что все завершится из-за асинхронной природы сигналов. Большое спасибо за помощь! - person Tomek; 24.06.2015