Вводная проста. Имеем самописную службу, которая висит на CAN и что-то отдает из CAN в mqtt.
Имеем файл, который запускает службу. И после долгих мучений подгоняем параметр
ExecStartPre=/bin/sleep 80
к значение в 80 секунд! 60 секунд мало! При 60 секундах утилита запускается, но данных с шины can еще не видит. И по прошествии времени так и не начинает видеть. Помогает или перезагрузка службы, или отложенный на 80 сек запуск службы при рестарте контроллера.
Я согласен, что и код надо посмотреть у утилиты, но все же хотелось бы понять, от какой службы зависит доступность интерфейса can?
Что надо поставить параметр After= ?
Картинка с графиком загрузки служб контроллера на ЯД.
От After=wb-hwconf-manager.service, но, насколько я понимаю, это не зависимость от сервиса в чистом виде. Т.е. ждать нужно пока сервис wb-hwconf-manager закончит работать, а не просто стартует.
Вижу два решения:
в systemd написать зависимость от появления интерфейса can0
Приветствую!
Не ясно, что означают понятия интерфейс “появляется” и “живёт”. Прошу описать симптомы.
Немного о том, как всё работает внутри:
Когда в веб-интерфейсе в настройках RS485-2 выставлен CAN, включается CAN-трансивер и ядро загружает нужный драйвер. Это можно увидеть, посмотрев в /sys/class/net/ или же - увидев
[ 24.294722] CAN device driver interface
[ 24.352888] 2094000.flexcan supply xceiver not found, using dummy regulator
[ 24.510496] flexcan 2094000.flexcan: device registered (reg_base=e2578000, irq=219)
в логе загрузки контроллера. Соответственно, это сохраняется при перезагрузках (после выполнения wb-hwconf-manager.service (запускается перед multi-user.target)). На данный момент, интерфейс доступен, но не настроен.
2) Для передачи данных интерфейс надо настраивать руками ip link set can0 up type can bitrate 125000 или можно автоматизировать, вставив
auto can0
iface can0 inet manual
pre-up /sbin/ip link set $IFACE type can bitrate 125000
up /sbin/ifconfig $IFACE up
down /sbin/ifconfig $IFACE down
в /etc/network/interfaces.
Мы провели в офисе небольшой эксперимент: прописали то, что выше в /etc/network/interfaces и перезагрузили контроллер.
CAN работает сразу после перезагрузки (53c, пока станет доступен терминал).
Резюмирую:
Кажется, из текущего systemd-юнита можно убрать все After=, кроме mosquitto
Попробуйте поднимать CAN через /etc/network/interfaces
Если проблема сохранится - скорее всего, виноват canmqttd
далее systemctl enable candumpd
и reboot
смотрим /var/log/candump.log - пусто. ps ax | grep can
тоже пусто.
однако service candumpd start
из терминала, и все работает!
Провели ещё один эксперимент в офисе с Вашим конфигом /etc/network/interfaces (предполагаю, в нём не указана строчка auto can0) и Вашим же systemd-юнитом.
Действительно, CAN ничего не принимает. systemctl status candumpd после перезагрузки говорит нам, в чём проблема:
Тестовый сервис candumpd стартует и пытается слушать CAN до того, как интерфейс can0 оказывается поднят и сконфигурирован (через /etc/network/interfaces). Если дёрнуть сервис candumpd руками после загрузки, данные пойдут, т.к. интерфейсы-то подняты!
Интересное наблюдение: похоже, текущая реализация настроек сети (debian-овский networking (/etc/network/interfaces) + systemd) не позволяет нам отследить момент поднятия сетевых интерфейсов и запустить наш сервис после этого.
Другими словами, что-то вроде After=network-online.target сейчас работать не будет.
Предлагаю решение: в ExecStartPre ждать, пока сетевые интерфейсы (прописанные в /etc/network/interfaces) не поднимутся. Прилагаю сервис, заработавший у нас. candumpd.service (618 Байт). Получается некоторый апгрейд вашего sleep 80.
Подозреваю, также можно выкинуть настроку CAN из /etc/network/interfaces и прописать её в ExecStartPre сервиса вместо того, что есть сейчас (не проверял).
Таким образом, перед работой с CAN нужно иметь:
Стартовавший wb-hwconf-manager.service (включает трансивер и дёргает линуксовый драйвер)
UPD: проверили вторую гипотезу. Кажется, действительно, проще настраивать интерфейс в ExecStartPre вместо /etc/network/interfaces
[Unit]
Description=CANDUMP service daemon
Requires=wb-hwconf-manager.service
After=wb-hwconf-manager.service
ConditionPathExists=/sys/class/net/can0/
[Service]
Type=simple
ExecStartPre=/sbin/ip link set can0 up type can bitrate 125000
ExecStart=/bin/bash -c 'exec /usr/bin/candump can0 >> /var/log/candump.log'
[Install]
WantedBy=multi-user.target
Логика следующая: запускаемся после wb-hwconf-manager и смотрим, что can0 появился в sysfs.
Возникает вопрос, как работать с контроллерами, у которых может быть как 1 так и 2 интерфейса CAN. И они могут работать на разных скоростях. Писать свой конфигурационный файл под службу?