14

I have written a couple of systemd user service files which I want users to enable and which need a working network connection. I thought that would be as easy as:

Wants=network-online.target
After=network-online.target

However, the services seem to start too early, and in journalctl I see:

network-online.target: Cannot add dependency job, ignoring: Unit network-online.target failed to load: No such file or directory.

Then I searched more and tried

Wants=network.target
After=network.target

and did sudo systemctl enable systemd-networkd-wait-online.service.

Now I have in journalctl:

network.target: Cannot add dependency job, ignoring: Unit network.target failed to load: No such file or directory.

And again the service starts too early.

Is that message supposed to be there? How can I debug my problem?


EDIT: the reason is simple and specifically stated in the Arch Wiki:

systemd --user runs as a separate process from the systemd --system process. User units can not reference or depend on system units.

This forum post seems to suggest a simple solution: I should link the necessary system unit as a user, thus creating a symlink to it available on the unit search path.

After doing that, I don't see any No such file or directory messages, however, I still can't make the services actually run after the network is online. I have tried linking network.target, network-online.target and systemd-networkd-wait-online.service, setting my units to depend on each of them, with no success. When I check the linked unit's status in user mode, they are all some of them are dead, e.g.:

$ systemctl --user status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; linked; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
$ systemctl status network.target
● network.target - Network
   Loaded: loaded (/usr/lib/systemd/system/network.target; static; vendor preset: disabled)
   Active: active since Sat 2015-07-18 19:20:11 MSK; 3h 35min ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 18 19:20:11 calc-server systemd[1]: Reached target Network.
Jul 18 19:20:11 calc-server systemd[1]: Starting Network.

However, I can see network-online.target active in user mode after linking it:

$ systemctl --user status network-online.target
● network-online.target - Network is Online
   Loaded: loaded (/usr/lib/systemd/system/network-online.target; linked; vendor preset: enabled)
   Active: active since Sun 2015-07-19 00:35:38 MSK; 2min 48s ago
     Docs: man:systemd.special(7)
           http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget

Jul 19 00:35:38 calc-server systemd[469]: Reached target Network is Online.
Jul 19 00:35:38 calc-server systemd[469]: Starting Network is Online.
  • I hope you'll have an answer. – user123418 Jul 18 '15 at 16:41
  • @Deleteme Thanks, I think I found the cause of this (see update), but not how to solve the problem. – Lev Levitsky Jul 18 '15 at 19:59
  • Did you every find a solution to this problem? Also, I notice you emphasise that only some linked units are dead. Which are the ones that worked, and how do they differ? – Sparhawk Nov 2 '15 at 6:44
  • @Sparhawk unfortunately not. As a workaround, I just use timers set to several seconds after boot. The question has an example: network-online target is active after linking, and network target is not. – Lev Levitsky Nov 2 '15 at 8:55
  • Perhaps I misunderstand, but I'm looking for something to fire every time the network resumes, to check my email after resuming from suspend. I thought this would be the way to do it. I see the examples now. I thought you meant some custom services fired and some did not. However, I see now you are talking about the user versions of the network targets. – Sparhawk Nov 2 '15 at 9:07
3

Since you cannot depend on a system service, your only solution is to provide a user service that detects whether the network is online. (Or make your services system services.) Details for a "detect-online" user service would depend on your definition of "online". It could wait for a ping to 8.8.8.8 to succeed, for instance. Or for a DNS name resolution to succeed. For instance, in a similar situation with vpnc, I wait for a ping to a vpn IP to succeed.

Then you can make your user services depend on (After=) your detect-online user service.

#!/bin/sh

host="${1:-8.8.8.8}"

pingcheck() {
  ping -n -c 1 -w 5 $1 >/dev/null 2>&1
}

# Do you want a timeout ?
while :; do
  pingcheck ${host} && exit 0
  sleep 10
done
  • Thank you, this seems reasonable and simple enough. But if 10 users enable my user service, there will be 10 instances pinging the same server simultaneously, which seems a bit redundant. In practice this is probably not at issue, but I was asking this in the hope of getting a single "online flag" available to all user services. No better solutions have yet been suggested, though. – Lev Levitsky Dec 16 '15 at 0:25
1

I would recommend to test something like this:

# /etc/systemd/system/foo.service
[Unit]
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/logger -t foo "testing online target"

[Install]
WantedBy=multi-user.target

Followed by:

# systemctl daemon-reload && systemctl enable foo.service
  • 2
    But this is a system service, and I am trying to set up a user service. – Lev Levitsky Dec 3 '15 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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