PIDFile= в systemd: зачем нужен при Type=forking
Задаёт абсолютный путь к файлу, в который демонизирующаяся программа записывает номер своего главного процесса. systemd читает его, чтобы знать, за каким процессом следить.
Что делает
При Type=forking исходный процесс завершается, и systemd теряет след настоящего рабочего процесса. Файл с номером процесса — это способ его найти. Без файла включается угадывание (GuessMainPID=), и оно часто ошибается: служба работает, а статус показывает не тот процесс, остановка задевает не то, что нужно.
Современный подход — не использовать демонизацию вовсе. Почти у каждой программы есть ключ «не уходить в фон», и с ним берётся Type=simple или exec. Тогда файл с номером процесса не нужен ни systemd, ни вам.
Где ставится. В секции [Service], только для Type=forking. Путь обязательно абсолютный, обычно в /run.
Значения
| Значение | Что происходит |
|---|---|
/run/myapp.pid | обычное место: tmpfs, очищается при перезагрузке. |
/run/myapp/myapp.pid | в своём каталоге; создавать его лучше через RuntimeDirectory=. |
Пример
Демон с файлом номера процесса и своим каталогом в /run.
[Service]
Type=forking
RuntimeDirectory=myapp
PIDFile=/run/myapp/myapp.pid
ExecStart=/usr/sbin/myapp --daemon --pidfile /run/myapp/myapp.pid
Путь в параметре и в аргументе программы должен совпадать. Каталог создаёт systemd, поэтому права на него будут правильными.
Типичные ошибки
Относительный путь недопустим: unit не загрузится.
Устаревший файл с номером несуществующего процесса приводит к тому, что systemd считает службу работающей или наоборот.
Каталог в /run очищается при перезагрузке. Если программа не создаёт его сама, нужен RuntimeDirectory=.
Файл с номером процесса не нужен при Type=simple, exec и notify — там systemd и так знает главный процесс.
Связанные ошибки
- status=0/SUCCESS, но служба считается упавшейПрограмма завершилась успешно, а systemctl показывает inactive или failed. Разбор: Type=simple против forking, RemainAfterExit, демонизация.
- Failed with result 'protocol'Состояние protocol: служба нарушила договор со systemd. Обычно Type=notify без уведомления или Type=dbus без имени на шине.
- status=233/RUNTIME_DIRECTORY в systemdКод 233/RUNTIME_DIRECTORY: не удалось подготовить каталог службы в /run из RuntimeDirectory=. Права, режим, удаление при остановке.
Рядом стоящие параметры
Где важен на практике
Источники
- systemd.service(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)