systemd: starting service that depends on sockets does not work

1

I'm using systemd to start a WiFi and power monitor service script that scans for an SSID, brings up the network and an SSH tunnel and does a few other tasks.

Much to my surpise it doesn't always work on cold boot (but does on a warm boot). The initial "ifconfig mlan0 up" fails. This seems to be linked to a race condition with a dependency on sockets:

root@duovero:~# systemctl status wifipwrmon
....

Jan 01 00:00:08 duovero wifipwrmon.sh[415]: ifconfig: SIOCGIFFLAGS: No such ...e
Jan 01 00:00:17 duovero wifipwrmon.sh[415]: Searching for WiFi routers

This is a somewhat contrived example because I can just reissue the ifconfig. But I also have another service that depends on sockets for IPC. This totally fails on boot unless I put a long delay in before I start it.

This is what I use for wifipwrmon.service:

[Unit]
Description=WiFi power monitor service
Requires=getty@tty1.service
After=getty@tty1.service

[Service]
ExecStart=/home/root/i2c/monitor/wifipwrmon.sh

[Install]
WantedBy=multi-user.target

I admit that I am used to sysvinit and I am new to systemd and was short of time when I did this. As I wanted it started pretty late I put a dependency on getty starting (probably a newbie thing to do).

Can anyone tell me what the dependency should be in order to start a service that depends on socket communications? I was very surprised that it failed at all - I thought sockets are so critical it would be in the kernel.

carveone

Posted 2014-04-20T14:42:30.887

Reputation: 318

Somewhat hacky but I made a quick "wait_for_sane_socket.sh" script that loops around waiting for "ifconfig mlan0 > /dev/null" to not return an error (I'm sure "ifconfig lo" would work in the general case). That does fix it but it is still very strange. – carveone – 2014-04-20T20:10:07.643

Couldn't you use netctl instead of ifconfig? I would assume it would integrate better with systemd. If I understand correctly, an After=network.target dependency will make sure the service starts only after netctl finished its job. It doesn't really answer your question, but maybe that's a direction to try. – bonob – 2014-04-21T06:56:20.053

Answers

0

As far as I understand the problem is unrelated to sockets, but is related to device initialisation.

In systemd service startup and device initialisation run in paralel. What happens in your case is that on cold boot your wifi device takes longer to initialise and your service is started before it is available, resulting in the failing ifconfig

you could use something like:

[Unit]
BindTo=sys-subsystem-net-devices-wlan0.device
After=sys-subsystem-net-devices-wlan0.device

in your service file, to order your unit after the apearance of the wireless device.

SimonPe

Posted 2014-04-20T14:42:30.887

Reputation: 406

I don't think so in this particular case. I don't need WiFi, the sockets are purely process to process on localhost. The problem was that I assumed the network layer would be valid at login time. And it was when I tested it but not in front of the clients (cue absolute blind panic). We have solved the issue by messing with scripts that retry the interfaces before doing anything else and then depending on them in systemd. Something like: "After=network.target checknetup.service". – carveone – 2014-06-15T10:30:52.550