I have a couple questions about systemd. I'm having issues consistently getting my script to run once the network interface is up. I have tried Requires and After as seen below but is inconsistent with waiting for the network to be up. Am I using the right service and implementing it correctly? To by pass this right now I am running a ping check loop which is very inefficient and hackish. Any advice would be great. Thanks!

[Unit]
Description=PBU installer
Requires=network-online.service
After=network-online.service

[Service]
Type=oneshot
ExecStart=/home/pbu/current/scripts/pbu-unpack.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

I solved this problem by looking at the output of:

systemctl list-units --no-pager

That showed me many units that I didn't expect like all the network devices!

sys-devices-virtual-net-lan0.device loaded active plugged   /sys/devices/virtual/net/lan

So I added

BindsTo=sys-devices-virtual-net-lan0.device
After=sys-devices-virtual-net-lan0.device

to my unit service file and then my service didn't start until lan0 was available.

This seems to be incorrect. The correct name is network-online.target. network-online.service does not exist (tested on Fedora 26).

https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

I don't know specifically about systemd, but if you're using NetworkManager, you can use nm-online at the top of your script to wait until the network is up.

if nm-online; then 
    echo "Online"
    # do my stuff
else
    echo "Network error"
fi

By default, it'll wait 30 seconds for a network connection to become active, and return 0 (true) if it does, false otherwise.

That's at least better than pinging, I think.

  • Unfortunately systemd doesn't have this option. WIsh it did, would save me a lot of trouble. – sphchow Jan 27 '16 at 3:45

Have you tried including Requires=network-online.target? Both my Arch and CentOS installations have this target by default. Since it's a target, it indicates that the system has reached a particular milestone in the boot process as opposed to just a single service starting. If that doesn't do it try comparing against another service unit that you know requires a network connection.

  • I have tried it... I'll try it again. Would i insert it as a parameter for Requires and After? – sphchow Jan 27 '16 at 3:36
  • When using "Requires", all the listed service units will start together. When using "After", systemd will make sure that all other listed units will start before yours, but will not necessarily start yours with them. One or the other should be sufficient, seems to me that both would cause a conflict. – smokes2345 Jan 27 '16 at 3:41
  • I think the problem is when I use requires OR after, the service starts with or after, but I almost need the network service to finish or at least get to a certain point... or else my script will require the network before it is actually up... – sphchow Jan 27 '16 at 3:44
  • That's why I suggested using network.target. Targets indicate a particular milestone in the boot process or a group of units that work together, instead of an individual service. The idea behind using "After=network.target" is that all the units that are needed to provide network access should be activated before your unit is activated. – smokes2345 Jan 27 '16 at 3:57
  • Doesn't seem to work for me. My script can't ping once the service starts. And upon looping it my ping script it does reach the ability to ping but not for a duration. – sphchow Jan 27 '16 at 18:33

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.