Systemctl не может запустить службу, которая использует порт ttyACM0 после перезагрузки

Systemctl не может запустить службу, которая использует порт ttyACM0 после перезагрузки

Мне нужно запустить собственную службу (клиент SignalR), написанную на C# (.NET6) после того, как порт ttyACM0 станет доступен. Эта служба должна быть запущена после другой службы (Сервер SignalR).

Служба сервера запускается после перезагрузки нормально (без каких-либо проблем). Статус обслуживания клиентов предоставляет информацию:

● RfidHwSigRClient.service
Loaded: loaded (/etc/systemd/system/RfidHwSigRClient.service;
disabled; vendor preset: enabled)    Active: inactive (dead) since Mon
2023-03-06 22:20:58 CET; 2min 17s ago   Process: 1583
ExecStart=/usr/bin/dotnet
/home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
(code=exited, status=0/SUCCESS)   Process: 767 ExecStartPre=/bin/sleep
10 (code=exited, status=0/SUCCESS)  Main PID: 1583 (code=exited,
status=0/SUCCESS)

Mar 06 22:20:46 PredatorClient systemd[1]: Starting
RfidHwSigRClient.service... Mar 06 22:20:57 PredatorClient
dotnet[1583]: Microsoft.Hosting.Lifetime[0] Application started.
Hosting environment: Production; Content root path: / Mar 06 22:20:57
PredatorClient systemd[1]: Started RfidHwSigRClient.service. Mar 06
22:20:58 PredatorClient dotnet[1583]:
Microsoft.Extensions.Hosting.Internal.Host[9] BackgroundService failed
System.UnauthorizedAccessException: Access to the port '/dev/usb_rfid'
is denied.  ---> System.IO.IOException: Device or resource busy    ---
End of inner exception stack trace ---    at
System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)    at
System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate,
Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout,
Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean
rtsEnable, Boolean discardNull, Byte parityReplace)    at
System.IO.Ports.SerialPort.Open()    at
Predator.Hardware.RfIDCard.RfId.Connect() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\Hardware\RFIDCard\RfId.cs:line
159    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ConnectAsync() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
95    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ExecuteAsync(CancellationToken
stoppingToken) in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
77    at
Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService
backgroundService) Mar 06 22:20:58 PredatorClient dotnet[1583]:
Microsoft.Extensions.Hosting.Internal.Host[10] The
HostOptions.BackgroundServiceExceptionBehavior is configured to
StopHost. A BackgroundService has thrown an unhandled exception, and
the IHost instance is stopping. To avoid this behavior, configure this
to Ignore; however the BackgroundService will not be restarted.
System.UnauthorizedAccessException: Access to the port '/dev/usb_rfid'
is denied.  ---> System.IO.IOException: Device or resource busy    ---
End of inner exception stack trace ---    at
System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)    at
System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate,
Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout,
Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean
rtsEnable, Boolean discardNull, Byte parityReplace)    at
System.IO.Ports.SerialPort.Open()    at
Predator.Hardware.RfIDCard.RfId.Connect() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\Hardware\RFIDCard\RfId.cs:line
159    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ConnectAsync() in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
95    at
Predator.SignalRComm.RfidHwSigRClient.RfidBroker.ExecuteAsync(CancellationToken
stoppingToken) in
D:\Projects\PredatorDotNet\Source\PredatorClientDotNet\SignalRComm\Derived\RfidHwSigRClient\RfidHwSigRClient\RfidBroker.cs:line
77    at
Microsoft.Extensions.Hosting.Internal.Host.TryExecuteBackgroundServiceAsync(BackgroundService
backgroundService) Mar 06 22:20:58 PredatorClient dotnet[1583]:
Microsoft.Hosting.Lifetime[0] Application is shutting down...

Проблема в том, что порт недоступен.

Как только Ubuntu запускается, я могу перезапустить клиентскую службу ( systemctl restart service_name) из командной строки, и служба работает правильно (порт готов).

Я прочитал несколько форумов о том, как запустить службу start. К сожалению, безуспешно.

Мои правила udev выглядят так:

KERNEL=="ttyACM*", ATTRS{manufacturer}=="MOD elektronik*", ATTRS{product}=="MOD RFID reader", MODE="0666", SYMLINK+="usb_rfid", ENV{SYSTEMD_WANTS}+="RfidHwSigRClient.service"

Мой RfidHwSigRClient.service выглядит так:

[unit]
Description=RFId Card Reader SignalR Client Service
BindsTo=dev-usb_rfid.device
Requires=MainSigRServer.service
After=dev-usb_rfid.device MainSigRserver.service
StartLimitIntervalSec=300
StartLimitBurst=30

[Service]
User=predator
Group=predator
Type=notify
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/dotnet /home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
TimeoutStartSec=30s
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-use

Я также пробовал запустить службу на 10 секунд позже ( ExecStartPre=/bin/sleep 10), но безуспешно. Пользователь predator принадлежит к группе dialout. Ubuntu — 18.04 LTS.

Пожалуйста, кто-нибудь знает, что я делаю не так? Спасибо. Р.

решение1

Мне пришлось использовать сон примерно на 15 с, чтобы запустить клиентскую службу. Если сон составляет 10 с, порт не готов (доступ запрещен). Однако я все еще не знаю, как запустить клиентскую службу, как только будут готовы и порт, и серверная служба.

Моя временная конфигурация RfidHwSigRClient.service выглядит следующим образом:

[Unit]
Description=RFId Card Reader SignalR Client Service
BindsTo=dev-usb_rfid.device
After=dev-usb_rfid.device MainSigRServer.service
StartLimitIntervalSec=300
StartLimitBurst=30

[Service]
Type=notify
ExecStartPre=/bin/sleep 15
ExecStart=/usr/bin/dotnet /home/predator/Projects/VSLinuxDbg/RfidHwSigRClient/RfidHwSigRClient.dll
Restart=on-failure
RestartSec=5s
User=predator
Group=predator

[Install]
WantedBy=dev-usb_rfid.device

Правило Udev 99-usb-serial.rules выглядит следующим образом:

KERNEL=="ttyACM*", ATTRS{manufacturer}=="MOD elektronik*", ATTRS{product}=="MOD RFID reader", SYMLINK+="usb_rfid", MODE="0666", ACTION=="add", RUN+="/home/predator/Projects/Scripts/rfid_plugged.sh", TAG+="systemd" ENV{SYSTEMD_WANTS}+="MainSigRServer.service"

Спасибо..

Связанный контент