Служба запускается раньше монтирования своих данных
systemd не догадывается, какие пути нужны службе. Если данные лежат на отдельном диске, службу нужно связать с его точкой монтирования явно. Иначе служба стартует раньше и падает на отсутствующих файлах — а после ручного перезапуска работает, что сильно запутывает разбор.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Зависимость от точки монтирования не объявлена
Служба стартует одновременно с монтированием. Кто успеет первым, зависит от скорости диска.
-
Зависимость указана на unit вручную и с ошибкой
Имя unit монтирования выводится из пути по особым правилам. Написанное вручную имя легко ошибочно.
-
Служба падает только при загрузке, а вручную работает
Признак гонки: при ручном запуске диск уже смонтирован. Это сбивает с толку и заставляет искать причину не там.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Объявленные зависимости от путей и порядок запуска.
systemctl show myapp.service -p RequiresMountsFor -p AfterВерное имя unit монтирования для пути.
systemd-escape -p --suffix=mount /srv/dataЧто было при загрузке: успел ли диск смонтироваться.
journalctl -u myapp.service -b --no-pager | head -20Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Служба стартует одновременно с монтированием. Кто успеет первым, зависит от скорости диска.
- Как проверить
-
Посмотрите зависимости службы и точку монтирования данных.
systemctl show myapp.service -p RequiresMountsFor -p After findmnt -T /srv/data -o TARGET,SOURCE
- Как исправить
-
Объявите нужные пути параметром зависимости от монтирования: systemd сам выведет нужные unit и порядок.
[Unit] RequiresMountsFor=/srv/data
- Почему происходит
- Имя unit монтирования выводится из пути по особым правилам. Написанное вручную имя легко ошибочно.
- Как проверить
-
Посмотрите верное имя unit для пути.
systemd-escape -p --suffix=mount /srv/data systemctl show myapp.service -p After
- Как исправить
- Используйте зависимость от пути вместо ручного имени unit: имя вычислит systemd. Так не получится ошибки при переносе.
- Почему происходит
- Признак гонки: при ручном запуске диск уже смонтирован. Это сбивает с толку и заставляет искать причину не там.
- Как проверить
-
Сравните поведение при загрузке и после неё.
journalctl -u myapp.service -b --no-pager | head -20 systemctl status myapp.service --no-pager | head -6
- Как исправить
- Объявите зависимость от монтирования. Перезапуск при сбое с задержкой маскирует гонку, но не устраняет её.
Пример вывода
Служба стартовала раньше монтирования данных. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
systemd[1]: Started myapp.service - My application.
myapp[900]: fatal: open /srv/data/db.sqlite: no such file or directory
systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: Mounting /srv/data...
Связанные ошибки
- No such file or directory в журнале службы Служба не находит файл или каталог. Разбор: путь, момент запуска, изоляция unit-файла, символические ссылки, приватный /tmp.
- Имя mount-unit не соответствует точке монтирования systemd отказывается загружать .mount: имя файла должно быть получено из пути через systemd-escape. Как назвать unit правильно.
- Служба не запускается вместе с зависимостью After= без Wants= не запускает зависимость. Разбор частой путаницы между порядком и необходимостью.
- Automount: каталог монтируется не вовремя или отваливается Автомонтирование через .automount: как работает TimeoutIdleSec, почему ресурс отваливается и когда лучше обычный .mount.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Dependency failed for … и результат 'dependency' Сообщение Dependency failed for: служба не запускалась, потому что упала её зависимость. Как найти настоящего виновника.
- Device or resource busy при операции с файлом Ошибка 16: файл или устройство заняты. Разбор для точек монтирования, устройств и файлов конфигурации.
- Found ordering cycle: циклическая зависимость при загрузке systemd нашёл цикл в порядке запуска и разорвал его, отбросив одну зависимость. Как найти цикл и правильно расставить After и Requires.
Источники
-
systemd.unit(5)
RequiresMountsFor= и автоматический вывод зависимостей от путей. -
systemd-escape(1)
Преобразование пути в имя unit. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на systemd 255: без зависимости порядок не гарантирован.