Служба ждёт устройство: device-unit не появляется
systemd создаёт unit для каждого устройства, о котором сообщило ядро. Зависимость от такого unit — надёжный способ дождаться диска или последовательного порта. Если устройство не появляется, зависимая служба не запускается вовсе.
Что это значит
Имя unit получается из пути устройства: /dev/ttyUSB0 превращается в dev-ttyUSB0.device. Проверить, видит ли его systemd, можно командой просмотра unit этого типа.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Устройство не подключено или не определилось
Если ядро не сообщило об устройстве, unit не создаётся, и зависимость не выполняется. Служба остаётся в ожидании.
-
Имя unit не соответствует пути устройства
Имя вычисляется из пути. Для устройств с составными путями его нужно получать преобразованием, а не собирать руками.
-
Устройство есть, но systemd не считает его готовым
Правила udev могут помечать устройство как неготовое для systemd. Тогда unit существует, но остаётся неактивным.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Какие устройства systemd вообще видит.
systemctl list-units --type=device --no-pager | head -20Свойства устройства, включая метки для systemd.
udevadm info /dev/ttyUSB0 | head -20Задания в ожидании: видно, чего ждёт служба.
systemctl list-jobsРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Если ядро не сообщило об устройстве, unit не создаётся, и зависимость не выполняется. Служба остаётся в ожидании.
- Как проверить
-
Посмотрите устройства и соответствующие unit.
ls -l /dev/ttyUSB* 2>/dev/null systemctl list-units --type=device --no-pager | grep -i ttyusb
- Как исправить
- Подключите устройство или проверьте, что нужный модуль ядра загружен: без него устройство не появится.
- Почему происходит
- Имя вычисляется из пути. Для устройств с составными путями его нужно получать преобразованием, а не собирать руками.
- Как проверить
-
Получите правильное имя.
systemd-escape -p --suffix=device /dev/disk/by-uuid/8f1c0a11
- Как исправить
-
Используйте имя из вывода команды. Для дисков удобнее зависеть не от устройства, а от точки монтирования через
RequiresMountsFor=.
- Почему происходит
- Правила udev могут помечать устройство как неготовое для systemd. Тогда unit существует, но остаётся неактивным.
- Как проверить
-
Посмотрите свойства устройства.
udevadm info /dev/ttyUSB0 | grep -iE "SYSTEMD|TAGS"
- Как исправить
- Добавьте правило udev с признаком готовности для systemd либо используйте другой способ ожидания.
Пример вывода
Служба ждёт последовательный порт, которого нет. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ systemctl status modem-watch.service --no-pager | head -5
○ modem-watch.service - Наблюдение за модемом
Loaded: loaded (/etc/systemd/system/modem-watch.service; enabled)
Active: inactive (dead)
$ systemctl list-jobs
JOB UNIT TYPE STATE
42 dev-ttyUSB0.device start waiting
Связанные ошибки
- Dependency failed for … и результат 'dependency' Сообщение Dependency failed for: служба не запускалась, потому что упала её зависимость. Как найти настоящего виновника.
- Mount process exited, code=exited, status=32: не найдено устройство Монтирование не проходит: устройство или UUID не найдены, неверная файловая система, недоступен сетевой ресурс. Код 32 от команды mount.
- Цель не достигнута: служба ждёт target, который не наступает Служба не запускается, потому что не достигнута цель из After= или Requires=. Разбор целей multi-user, network-online, graphical.
- Служба не останавливается при отключении устройства Устройство отключено, служба продолжает работать и сыпать ошибками: связь с устройством не объявлена.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Docker: демон не запускается без containerd docker.service падает, потому что не работает containerd.service. Разбор зависимости и сокета containerd.
- Found ordering cycle: циклическая зависимость при загрузке systemd нашёл цикл в порядке запуска и разорвал его, отбросив одну зависимость. Как найти цикл и правильно расставить After и Requires.
- Operation refused, unit may be requested by dependency only systemd отказывается запускать unit вручную из-за RefuseManualStart=yes. Что это значит и как запустить службу правильно.
Источники
-
device(5)
Unit устройств и их создание из событий ядра. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на отсутствующем последовательном порте: задание остаётся в ожидании.