2. О службах и процессах

В большинстве современных Linux-систем количество одновременно работающих процессов обычно весьма значительно. Понять, откуда взялся и что делает тот или иной процесс, становится все сложнее и сложнее. Многие службы используют сразу несколько рабочих процессов, и это отнюдь не всегда можно легко распознать по выводу команды ps. Встречаются еще более сложные ситуации, когда демон запускает сторонние процессы — например, веб-сервер выполняет CGI-программы, а демон cron — команды, предписанные ему в crontab.
Немного помочь в решении этой проблемы может древовидная иерархия процессов, отображаемая по команде ps xaf. Именно «немного помочь», а не решить полностью. В частности, процессы, родители которых умирают раньше их самих, становят потомками PID 1 (процесса init), что сразу затрудняет процесс выяснения их происхождения. Кроме того, процесс может избавиться от связи с родителем через две последовательные операции fork() (в целом, эта возможность признается нужной и полезной, и является частью используемого в Unix подхода к разработке демонов). Также, не будем забывать, что процесс легко может изменить свое имя посредством PR_SETNAME, или задав значение argv[0], что также усложняет процесс его опознания.
(Прим. перев.: Стоит отметить, что перечисленные ситуации могут возникнуть не только вследствие ошибок в коде и/или конфигурации программ, но и в результате злого умысла. Например, очень часто встречается ситуация, когда установленный на взломанном сервере процесс-бэкдор маскируется под нормального демона, меняя себе имя, скажем, на httpd).
systemd предлагает простой путь для решения обсуждаемой задачи. Запуская новый процесс, systemd помещает его в отдельную контрольную группу с соответствующим именем. Контрольные группы Linux предоставляют очень удобный инструмент для иерархической структуризации процессов: когда какой-либо процесс порождает потомка, этот потомок автоматически включается в ту же группу, что и родитель. При этом, что очень важно, непривилегированные процессы не могут изменить свое положение в этой иерархии. Таким образом, контрольные группы позволяют точно установить происхождение конкретного процесса, вне зависимости от того, сколько раз он форкался и переименовывал себя — имя его контрольной группы невозможно спрятать или изменить. Кроме того, при штатном завершении родительской службы, будут завершены и все порожденные ею процессы, как бы они ни пытались сбежать. С systemd уже невозможна ситуация, когда после остановки web-сервера, некорректно форкнувшийся CGI-процесс продолжает исполняться вплоть до последних секунд работы системы.
В этой статье мы рассмотрим две простых команды, которые позволят вам наглядно оценить схему взаимоотношений systemd и порожденных им процессов. Первая из этих команд — все та же ps, однако на этот раз в ее параметры добавлено указание выводить сведения по контрольным группам, а также другую интересную информацию:




Данный листинг был сокращен за счет удаления из него строк, описывающих потоки ядра, так как они никак не относятся к обсуждаемой нами теме.

Обратите внимание на третий столбец, показывающий имя контрольной группы, в которую systemd поместил данный процесс. Например, процесс udev находится в группе name=systemd:/systemd-1/sysinit.service. В эту группу входят процессы, порожденные службой sysinit.service, которая запускается на ранней стадии загрузки.
Вы можете очень сильно упростить себе работу, если назначите для вышеприведенной команды какой-нибудь простой и короткий псевдоним, например:


alias psc=’ps xawf -eo pid,user,cgroup,args’


— теперь для получения исчерпывающей информации по процессам достаточно будет нажать всего четыре клавиши. Альтернативный способ получить ту же информацию — воспользоваться утилитой systemd-cgls, входящей в комплект поставки systemd. Она отображает иерархию контрольных групп в виде псевдографической диаграммы-дерева:





Как видно из листинга, данная команда наглядно показывает принадлежность процессов к их контрольным группам, а следовательно, и к службам, так как systemd именует группы в соответствии с названиями служб. Например, из приведенного листинга нетрудно понять, что служба системного аудита auditd.service порождает три отдельных процесса: auditd, audispd и sedispatch.
Наиболее внимательные читатели, вероятно, уже заметили, что некоторые процессы помещены в группу /user/lennart/1. Дело в том, что systemd занимается отслеживанием и группировкой не только процессов, относящихся к системным службам, но и процессов, запущенных в рамках пользовательских сеансов. В последующих статьях мы обсудим этот вопрос более подробно.

Содержание
Вперед - Преобразование SysV init-скрипта в systemd service-файл
Назад - Контроль процесса загрузки