[systemd-devel] Ordering services issue. Trying to start ptp4l in bonding setup fails as bonding appears to take a while.

James Feeney james at nurealm.net
Wed Dec 1 18:12:41 UTC 2021


On 12/1/21 07:20, Brian Hutchinson wrote:
> ...
> In .system file I tried all I know to ensure the required interfaces were created before starting ptp4l in attempt to give bonding enough time to finish but binding to things like sys-subsystem-net-devices-bond1.device wasn't enough.
> 
> Is it also possible to use carrier state in .service file?
> 
> I see sys/devices/virtual/net/bond1/carrier but not sure how to only attempt to start my ptp4l service after carrier state is "1".
> 
> I welcome your ideas and suggestions on how to start a service after a bond interface is really up.

With systemd, the proper way to setup network bonding is to establish ordering with the use of "target" files, which can be added to /etc/systemd/system.

The target files themselves need not contain anything, though I have these with simply:

[Unit]
Documentation= man:systemd.target(5)

My configuration provides automatic bonding and bridging for removable/pluggable and fixed hardwired, wireless, and virtual interfaces, using hardlinked template files and a separate network configuration file, as /etc/conf.d/network, though you are only looking for bonding here.  The big advantage with using systemd as the network configuration system, compared to alternatives, is that it "just works", and doesn't break after someone else's "upgrade".

The essential idea with configuring virtual network interfaces using systemd target files derives from noting that network service clients and servers must run After bridge and bond master interfaces are working, which implies After configuration of their respective slave interfaces, and that hardware devices can only be enslaved After the master interfaces have been created.  These constraints imply the following ordering:

1) master interfaces
2) enslaved interfaces
3) network services

The systemd target files are then inferred between these three stages:

a) master interfaces
b) "go.target"
c) enslaved interfaces
d) "ll.target"
e) network services

The target file naming is arbitrary, of course.  I use these names from arbitrarily choosing the point of view from the template file used to configure each slave device to each master, where finally "ip link set %P master %I".

You could use the terminology "director" and "executive", from corporate structure lingo, instead of "master" and "slave", if preferred, but the ip command still uses the the terms "master" and "slave".

A hardware network device Requires go.target and the master interface service file "master at .service" runs Before go.target:

Requires= go.target
Before= go.target

Plugging network hardware, then, will trigger the entire chain of configuration events.

BindsTo= sys-subsystem-net-devices-%i.device

Similarly, for the enslaved interface service file "enslaved at .service":

Requires= go.target
After= go.target
Before= ll.target

And finally, for the various network services service template files:

PartOf= ll.target
Requires= ll.target
After= ll.target

That's the basic idea.  Of course, there are plenty of "housekeeping" details in practice.  In particular, "Requisite" fails to recognize device units, and instead,

ConditionPathExists= /sys/class/net/%I

is necessary.  This appears to me to be an unjustified bug with "Requisite", but - you know - Lennart.

Altogether, to trigger configuration of both master and slave devices from "enslaved at .service":

BindsTo= sys-subsystem-net-devices-%p.device
ConditionPathExists= /sys/class/net/%P
BindsTo= sys-subsystem-net-devices-%i.device

It is useful to impose an arbitrary but strict naming convention with these files, to allow use of systemd specifiers and template files.  In your case, you might simply hard-code what you want, if you are not looking for a generic solution, and all you want is bonding on a couple of interfaces.

Still, when properly setup, you can individually "start" and "stop" any of the target units or network service units and get correct behavior.


James


More information about the systemd-devel mailing list