Устаревший pid-файл мешает запуску
Программы, управляемые pid-файлом, при запуске проверяют его наличие. Файл, оставшийся после аварийного завершения, заставляет их думать, что экземпляр уже работает — и запуск не проходит.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Файл остался после аварийного завершения
При убийстве процесса сигналом KILL файл не удаляется. Следующий запуск видит его и отказывается.
-
Номер процесса занят другой программой
Номера переиспользуются. Устаревший файл может указывать на постороннюю программу, и проверка решит, что служба работает.
-
Путь файла не совпадает с параметром unit
Если
PIDFile=указывает не туда, где программа создаёт файл, systemd теряет процесс и считает службу упавшей.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Путь файла и номер процесса по мнению systemd.
systemctl show myapp.service -p PIDFile -p MainPIDСуществует ли процесс из файла.
ps -p "$(cat /run/myapp.pid 2>/dev/null)" 2>/dev/null || echo "процесса нет"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- При убийстве процесса сигналом KILL файл не удаляется. Следующий запуск видит его и отказывается.
- Как проверить
-
Проверьте, есть ли процесс с этим номером.
cat /run/myapp.pid 2>/dev/null ps -p "$(cat /run/myapp.pid 2>/dev/null)" 2>/dev/null || echo "процесса нет"
- Как исправить
-
Удалите устаревший файл и запустите службу. Чтобы это не повторялось, положите файл в каталог, который systemd очищает: объявите
RuntimeDirectory=.
- Почему происходит
- Номера переиспользуются. Устаревший файл может указывать на постороннюю программу, и проверка решит, что служба работает.
- Как проверить
-
Посмотрите, чей это процесс.
ps -p "$(cat /run/myapp.pid 2>/dev/null)" -o pid,comm,args 2>/dev/null
- Как исправить
- Удалите файл. Такой случай — хороший повод отказаться от pid-файлов: systemd следит за процессами сам.
- Почему происходит
- Если
PIDFile=указывает не туда, где программа создаёт файл, systemd теряет процесс и считает службу упавшей.
- Как проверить
-
Сравните путь в unit и фактический файл.
systemctl show myapp.service -p PIDFile sudo ls -l /run/*.pid | head
- Как исправить
-
Приведите пути к одному значению или откажитесь от демонизации: тип
simpleне требует pid-файла вовсе.
Пример вывода
Файл остался от убитого процесса. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[4400]: error: another instance is already running (pid 1200)
$ cat /run/myapp.pid
1200
$ ps -p 1200
PID TTY TIME CMD
# процесса нет
Связанные ошибки
- status=0/SUCCESS, но служба считается упавшей Программа завершилась успешно, а systemctl показывает inactive или failed. Разбор: Type=simple против forking, RemainAfterExit, демонизация.
- status=233/RUNTIME_DIRECTORY в systemd Код 233/RUNTIME_DIRECTORY: не удалось подготовить каталог службы в /run из RuntimeDirectory=. Права, режим, удаление при остановке.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Exec format error при запуске службы Ошибка формата исполняемого файла: не та архитектура, нет строки #!, повреждённый файл или попытка запустить не программу.
- Java-служба не запускается: не найдена среда исполнения Служба на JVM падает с кодом 203 или 127: путь к java неверен или среда исполнения не установлена.
- Job for … failed because a timeout was exceeded Задание на запуск прервано по таймауту. Как отличить медленный старт от заблокированного и правильно настроить TimeoutStartSec.
- Python-служба: ModuleNotFoundError при запуске Служба не находит модули: другое виртуальное окружение, неверный интерпретатор, отсутствующие зависимости.
- status=1/FAILURE в systemd Код 1/FAILURE означает, что программа запустилась и сама завершилась с ошибкой. Как найти настоящую причину в журнале службы.
Источники
-
systemd.service(5)
PIDFile= и слежение за процессом. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено убийством процесса сигналом KILL с оставшимся pid-файлом.