Ссылка для правильной обработки файла PID в Unix

Где я могу найти уважаемую ссылку, которая подробно описывает правильную обработку файлов PID в Unix?

В операционных системах Unix обычной практикой является "блокировка" программы (часто демона) с помощью специального файла блокировки: файла PID.

Это файл в предсказуемом месте, часто '/var/run/foo.pid'. Предполагается, что программа при запуске проверяет, существует ли файл PID, и, если файл существует, завершается с ошибкой. Так что это своего рода консультативный механизм совместной блокировки.

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

Чего я не могу найти, так это хорошего справочника об ожидаемом или "лучшем практическом" поведении для обработки файлов PID. Существуют различные нюансы: как на самом деле заблокировать файл (не беспокоиться? Использовать ядро? Как насчет несовместимости платформ?), Обрабатывать устаревшие блокировки (безмолвно удалять их? Когда проверять?), Когда именно получить и снять блокировку, и так далее.

Где я могу найти уважаемую, наиболее авторитетную ссылку (в идеале на уровне В. Ричарда Стивенса) для этой небольшой темы?

5 ответов

Решение

Насколько я знаю, PID-файлы - это соглашение, а не то, что вы можете найти уважаемый, в основном авторитетный источник. Наиболее близким я мог найти этот раздел Стандарта иерархии файловой системы.

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

Я считаю, что файлы в /var/run часто обрабатываются сопровождающими дистрибутива, а не авторами демонов, так как ответственные за дистрибутив отвечают за то, чтобы все сценарии инициализации хорошо играли вместе. Я проверил документацию разработчиков Debian и Fedora и не смог найти подробных рекомендаций, но вы могли бы получить больше информации в списках рассылки их разработчиков.

Во-первых, на всех современных UNIX /var/run не сохраняется при перезагрузках.

Общий метод обработки файла PID состоит в том, чтобы создать его во время инициализации и удалить его из любого выхода, обычного или обработчика сигнала.

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

См. Интерфейс программирования Linux Kerrisk, раздел 55.6 "Запуск только одного экземпляра программы", который основан на реализации pidfile в Unix Network Programming Стивенса, v2.

Также обратите внимание, что местоположение pid-файла обычно обрабатывается дистрибутивом (через скрипт init), поэтому хорошо написанный демон примет аргумент командной строки для указания pid-файла и не допустит случайного переопределения этого файла конфигурации. Он также должен изящно обрабатывать устаревший файл pid (O_EXCL не должен использоваться). Следует использовать блокировку файлов fcntl() - вы можете предположить, что pid-файл демона находится в локальной (не NFS) файловой системе.

В зависимости от дистрибутива, это фактически сценарий инициализации, который обрабатывает pid-файл. Он проверяет существование при запуске, удаляет при остановке и т. Д. Мне не нравится делать это таким образом. Я пишу свои собственные сценарии инициализации и обычно не использую стандартные функции инициализации.

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

Поэтому, если pid-файл уже существует при запуске, это очень хороший показатель для программы, что он ранее потерпел крах и должен предпринять какие-то усилия по восстановлению (если применимо). Вы как бы стреляете в эту логику, если у вас есть сам скрипт init, проверяющий наличие PID или отменяющий его связь.

Что касается пространства имен, оно должно следовать за именем программы. Если вы запускаете 'foo-daemon', это будет foo-daemon.pid

Вам также следует изучить /var/lock/subsys, однако он используется в основном в версиях Red Hat.

systemd пакет на Red Hat 7 предоставляет справочную страницу daemon(7) с заголовком строки "Написание и упаковка системы демонов".

На этой странице руководства обсуждается демонизация "старого стиля" (SysV) и "нового стиля" (systemd). В новом стиле systemd сама обрабатывает PID-файлы для вас (если так настроено). Тем не менее, в старом стиле, страница руководства имеет следующее:

  1. В процессе демона запишите PID демона (как возвращено getpid()) в файл PID, например /run/foobar.pid (для гипотетического демона "foobar"), чтобы гарантировать, что демон не может быть запущен более одного раза, Это должно быть реализовано в режиме без гонки, чтобы файл PID обновлялся только тогда, когда он проверяется одновременно с тем, что ранее сохраненный в файле PID PID больше не существует или принадлежит стороннему процессу.

Вы также можете прочитать эту справочную страницу онлайн.

Другие вопросы по тегам