[systemd-devel] Ordering cycle when trying to use BindToDevice socket option

Dmitri Kourennyi dkour at mykolab.com
Fri Mar 31 22:12:11 UTC 2023


I have a homebrew router that includes multiple independent network 
devices. I manage these devices using systemd-networkd, which ultimately 
ends up with a `wan` device, and a `brlan` bridge that covers all the 
lan connections (possibly of importance, I use .link files so 
systemd-networkd creates devices with these names). I want to be able to 
ssh to the device on the brlan-side only, but I would also like to use 
both IPv4 and IPv6, as the brlan has both a static IPv4 address and a 
number of static fc00::/7 addresses that are advertised via mDNS. I'm 
using tiny-ssh, and it includes a systemd socket as part of the install 
that looks like this:
```
[Unit]
Description=TinySSH service (socket-activated)
Documentation=http://tinyssh.org
Wants=tinysshgenkeys.service

[Socket]
ListenStream=%i
Accept=true
KeepAlive=true
IPTOS=low-delay

[Install]
WantedBy=sockets.target
```

Since I want to bind to the entire brlan device to the ssh socket, I 
override the socket definition to add the following:
```
[Socket]
BindToDevice=brlan
BindIPv6Only=both
```

However, this makes the socket fail at startup because it times out 
waiting for /sys/subsystem/net/devices/brlan. Ok, I think this is a 
simple dependency issue, so I add
```
[Unit]
After=
After=iface-online-brlan.service
Wants=
Wants=iface-online-brlan.service
```
to the override, where that service just runs a bash script that waits 
for the brlan device to be up (this service in turn has 
After=systemd-networkd and Requires=systemd-networkd and 
Before=nertwork-online.target). However, this causes the socket to fail 
at startup due to an ordering cycle:
```
tinyssh at 22.socket: Found ordering cycle on 
iface-online-brlan.service/start
tinyssh at 22.socket: Found dependency on basic.target/start
tinyssh at 22.socket: Found dependency on sockets.target/start
tinyssh at 22.socket: Found dependency on tinyssh at 22.socket/start
tinyssh at 22.socket: Job iface-online-brlan.service/start deleted to break 
ordering cycle starting with tinyssh at 22.socket/start
```

Ok, I decide the problem is the WantedBy=sockets.target in the Install 
section, so I replace it by adding this to the override
```
[Install]
WantedBy=
WantedBy=multi-user.target
```

And it's still no good, with sockets.target still being in part of the 
dependency loop:
```
sockets.target: Found ordering cycle on tinyssh at 22.socket/start
sockets.target: Found dependency on iface-online-brlan.service/start
sockets.target: Found dependency on basic.target/start
sockets.target: Found dependency on sockets.target/start
sockets.target: Job tinyssh at 22.socket/start deleted to break ordering 
cycle starting with sockets.target/start
```

At this point, I'm pretty stumped, and nothing I've tried seems to fix 
this (including replacing the WantedBy to just be multi-user.target). 
The message seems to imply that systemd-networkd depends on 
sockets.target, which in turn depends on the tinyssh socket, but that in 
turn needs systemd-networkd to run to create the target device. I 
suspect the issue is that I'm depending on systemd-networkd to rename 
the device, and BindToDevice= normally works if the devices are already 
there. Is there no way to make a socket not be wanted by sockets.target? 
I could be overly clever and just create a service with the dependency 
ordering I want that just manually starts the socket, but that just 
doesn't feel right.

Thanks,
-Dmitri


More information about the systemd-devel mailing list