Каких демонов перезапускать после обновления?

    •     , ,

В лучших традициях блоггинга, выношу из личной переписки то, что рассказываю уже не в первый раз — теперь буду просто ссылаться сюда.

Как вы, наверное, знаете, в *nix, в отличие от Windows1, можно удалить открытый кем-то файл; при этом имя из файловой системы пропадает сразу, а место, занятое данными, освободится лишь после закрытия файла всеми процессами.

При обновлении системы ситуацию с уже удалёнными, но всё ещё кем-то используемыми файлами можно встретить сплошь и рядом: при обновлении библиотеки старый .so может быть удалён, а на его место под тем же именем помещена новая сборка. При этом процессы, использующие старую версию, будут продолжать ею пользоваться, а новые будут запускаться уже с обновлённой. Это может привести к проблемам: к примеру, в случае с Heartbleed одного только обновления libssl мало, нужно ещё и перезапустить sshd, Nginx, Apache и вообще всё-всё-всё, что работало с SSL.

В Debian есть готовое решение, работающее с любым демоном — checkrestart (пакет debian-goodies). Он показывает, какие из демонов пользуются устаревшими файлами, и объясняет, как их перезапустить.

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

$ sudo lsof / | grep DEL | cut -f1 -d' ' | sort -u

Что он делает:

  1. lsof показывает все-все-все открытые файлы и сокеты. lsof / показывает только файлы. При запущенном торрент-клиенте, постоянно плодящем соединения, вывод сокетов занимает кучу времени, поэтому я отсеиваю их на этом этапе;

  2. в выводе lsof присутствует колонка TYPE, показывающая тип открытого ресурса: файл (REG), директория (DIR), сокет (IPv4 или IPv6) и, наконец, файлы, которые были удалены (DEL). Есть ещё целая куча других типов, читайте lsof(8). В общем, grep DEL выдирает строки с удалёнными файлами;

  3. в получившемся списке меня интересуют только имена процессов (первая колонка), поэтому я вырезаю её (cut) и сортирую, удаляя повторяющиеся строки (sort -u);

  4. voilà: теперь у нас есть список процессов, которые нужно перезапустить. Эту часть я всё никак не соберусь автоматизировать.

Некоторые процессы могут перезапускаться не самостоятельно, а вместе с другими, например:

Некоторые другие процессы перезапустить вообще нельзя (например, systemd — там хоть и есть daemon-reexec, но у меня он почему-то никогда не работает).

И, конечно же, не следует забывать про ядро — в списке процессов его не видно, но обновления придти могут. Тут уже только ребут поможет (или ksplice, но ребутнуться проще :)


  1. Мой читатель ForNeVeR подсказывает, что в Windows на самом деле можно удалить открытый кем-то файл, если только открывший потрудился указать в вызове fopen флаг FILE_SHARE_DELETE.↩︎

Your thoughts are welcome by email
(here’s why my blog doesn’t have a comments form)