You are not logged in.
[SOLVED]. Tl;dr:
To make a service wait until a device is available on system startup, use After=your.device
To stop a service on device loss, use BindsTo=your.device
To start a service at any time on device rediscovery, use an udev rule (systemd does not provide for this)
To start a service at any time on device rediscovery, use an /etc/systemd/system/your.device.wants directory containing a symlink to /usr/lib/systemd/system/your.service
Working udev rule for this particular case:
/etc/udev/rules.d/50-net-wlan0_start-hostapd.rules
# Start hostapd.service when wlan0 is discovered
SUBSYSTEM=="net", KERNEL=="wlan0", TAG+="systemd", ENV{SYSTEMD_WANTS}="hostapd.service"
==========================================
I have a wireless access point using hostapd.
To prevent hostapd.service from starting before the wireless device is available I have a systemd drop-in snippet for hostapd.service:
/etc/systemd/system/hostapd.service.d/requiresdevice.conf
[Unit]
After=sys-subsystem-net-devices-wlan0.device
BindsTo=sys-subsystem-net-devices-wlan0.device
For minimum maintenance (read: maximum laziness) I also want to have the hostapd.service unit restarted when something undesired happens to it, so I have another drop-in snippet:
/etc/systemd/system/hostapd.service.d/restart.conf
[Service]
Restart=always
RestartSec=15
This seems to work all right when I e.g. kill the hostapd process.
However today I woke up to find my wireless network gone.
The system itself was fine. It was just that the wireless USB dongle apparently became disconnected for a short time, and then was re-attached, as far as dmesg told me.
On device loss systemd seemed to have stopped hostapd.service as per the BindsTo= directive, however it wasn't restarted automatically.
Now, "man systemd.service" tells me,
When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restarted.
Therefore I assume hostapd.service was not restarted because it was stopped by systemd itself.
So, my question is:
Is it possible, with the features systemd brings to the table, to have a service that was terminated due to device loss be restarted automatically once said device becomes available again?
I ask this because I imagine many people run wireless access points or generally have similar requirements for a systemd service that depend on devices being available.
Therefore, as a not-that-exotic-at-all real-world scenario, systemd hopefully provides for things like this, and I just haven't found out how to set it up properly.
I have tried it without the BindsTo= directive, but it doesn't do any good because hostapd cannot handle it when its wireless device is lost and re-attached. So I need hostapd to be restarted when the device reappears.
I would hate to have to write an udev trigger or something the like, especially seeing that systemd has the capability to watch for devices built right into it (otherwise After=xyz.device and BindsTo= wouldn't work at all, would they?)
Last edited by eomanis (2016-08-19 18:07:29)
Offline
Keep in mind that if the wireless interface can go away and come back by itself then it can also go away and not come back. I would focus on addressing this.
Hardware instability is very difficult to account for in software due to the many forms it can take. It often turns into a game of whack a mole.
Offline
Keep in mind that if the wireless interface can go away and come back by itself then it can also go away and not come back. I would focus on addressing this.
Granted, the hardware situation could arguably be better.
Still it would be awesome if the hostapd service would be restarted automatically if e.g. somebody stepped on the USB cable, or generally if the device was detached by accident for a short time.
This would definitely beat having to power cycle the wireless access point for lack of SSH knowledge/access.
Anyway, I filed a bug for this:
https://github.com/systemd/systemd/issues/2824
Offline
How is that a bug? It looks like it is completely effective - it does exactly what it's supposed to. It sounds like you just don't want the BindsTo behavior, so remove that line:
BindsTo=
... declares that this unit is stopped when any of the units listed suddenly disappears. Units can suddenly, unexpectedly disappear if a ... a device is unplugged
EDIT: sorry - I missed part of your original post. I need to read more thoroughly.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
(...) It sounds like you just don't want the BindsTo behavior, so remove that line: (...)
Tried that, did not work:
I have tried it without the BindsTo= directive, but it doesn't do any good because hostapd cannot handle it when its wireless device is lost and re-attached. So I need hostapd to be restarted when the device reappears.
Offline
I ran into a similar need and discovered that instead of manually creating the symlink you can just add
WantedBy=multi-user.target sys-subsystem-net-devices-wlan0.device
to your service file under the [Install] section and systemd will create the symlink for that device when you enable (install) the service.
In my case had a daemon that needed to be killed if a network filesystem became unmounted for any reason.
Offline