[systemd-devel] network consuming user services

Alex Elsayed eternaleye+usenet at gmail.com
Tue Jun 26 03:57:30 PDT 2012


Sebastian Tramp wrote:

> On Fri, May 04, 2012 at 10:23:25AM +0200, Sebastian Tramp wrote:
>> On Thu, May 03, 2012 at 12:29:04AM +0200, Lennart Poettering wrote:
>> > On Wed, 02.05.12 22:19, Sebastian Tramp (mail at sebastian.tramp.name)
>> > wrote:
>> > 
>> > > Hi,
>> > > 
>> > > I want to start some user services which need a working network
>> > > connection. This includes services as
>> > > 
>> > > * "fetchmail --idle" to receive mails
>> > > * ssh tunnel with autossh
>> > > * dyndns update
>> > > 
>> > > I recently switched to systemd 44 on arch linux but after one day of
>> > > try and error as well as manpage reading I am not sure that this is
>> > > in the scope of systemd.
>> > > 
>> > > The best solution could be to hear on dbus, if the NetworkManager
>> > > sends an "online event". The services need to be finished if the
>> > > network is down and started again if we are online again.
>> > > 
>> > > Are there existing service files which solve a similar or the same
>> > > issue?
>> > 
>> > Ideally services like yours would just listen to netlink events so that
>> > they can properly handle connectivity coming and going. In today's
>> > dynamic world having daemons that fail if the network isn't up is
>> > backwards, in particular since the definition of "network is up" is
>> > hard on machines with multiple network interfaces, or machines
>> > connected indirectly to the internet. i.e. link beat or pingability
>> > might matter more.
>> > 
>> > In summary: we think the only correct way to handle network
>> > connectivity is to make the daemons watch netlink. To provide
>> > compatibility with services that currently not do it we provide the
>> > generic "network.target" which can be used as synchronization point for
>> > all services that only care for "network is up", for whatever
>> > definition this might be. Depending on the specific installation this
>> > can then be filled with different definitions. One option for example
>> > is to enable the "NetworkManager-wait-online.service", which hooks into
>> > NM and waits until a network configuration is applied and is subject to
>> > a timeout. Just run "systemctl enable
>> > NetworkManager-wait-online.service" and it will order itself before
>> > network.target, thus exposing the desired behaviour.
>> 
>> Thank you for this answer. Unfortunately, this blocks my boot procedure
>> in the case of no network.
>> 
>> Is there a way to describe the units in a way that they are started after
>> network managers ok signal?
> 
> ok, did not read davids response before that. a better way is to let start
> the target from network manager site. this works fine for me.
> 
> Best regards
> 
> Sebastian Tramp
> 
>> 
>> My use case is strongly laptop driven:
>> - most of the time I'm working in a docking station with cable network
>> available - Sometimes I'm in a wlan area
>>   (but to connect I need to unlock my keystore so it is not on boot time)
>>   and
>> - sometimes I'm totally offline.
>> 
>> In all cases I wish that my user demons wait until network manager says
>> ok.
>> 
>> Currently I start my demons manually but hoped that systemd can help me
>> with that. Before systemd, I re-run them every 10min with cron (so they
>> failed on no network). In the worst case I could do the same with timer
>> units but this is definitely not the systemd way :-)
>> 
>> Best regards
>> 
>> Sebastian Tramp
>> 

Apologies for the thread necromancy, but I just wanted to share my solution 
for this. I chose to set it up this way so that if I want to switch from 
NetworkManager to, say, wicd in the future I could just write a second 
connection-manager-specific check-online service and hook for that. This 
allows me to select between them using systemctl enable.

Any service that needs to start only when actually connected (ssh tunnels, 
network backup .timer units, and so on) .include's the needs-network.unit.in 
file, and the fact that the dispatcher script just starts a oneshot that 
tests for connectivity avoids issues with multi-home (since if at least one 
is connected, the oneshot succeeds).

With regard to Lennart's comment of pingability, there are two solutions. 
One is using NetworkManager's built-in pingability test, which may be 
sufficient if you simply want to make sure you aren't on a paywalled 
network. If that is enabled, such networks are not counted as 'online' 
unless the configured ping address responds. The more targeted option is to 
introduce another set of oneshot-and-target combinations like this for the 
hosts you care about, with the oneshot command being ping -c 1 <host>. Heck, 
the oneshots could even be triggered by timers so they check periodically. 
The timer would .include the needs-network unit, have a Unit=check-
pingable@<host>.service line along with the timer interval, and you're set.

Lennart: I agree that for daemons, listening to netlink is preferable, but 
fetchmail and others are periodic programs that only make sense to run while 
connected. Most of them do make the most sense with a pingability test, but 
I like having systemd be the one doing that.

One question, however: What are the effects of an enabled systemd user unit 
having a WantedBy= on a system unit? One thing I'd like to do is, when I 
start using systemd user sessions, have these only activate when the user 
session is active.

Hope this helps!

==> /etc/systemd/system/online.target <==
[Unit]
Description=The system is currently online
Requires=check-online.service

==> /etc/systemd/system/NetworkManager-check-online.service <==
[Unit]
Description=Test whether the system is currently online via NetworkManager
Wants=online.target
Before=online.target
Requires=dbus-org.freedesktop.NetworkManager.service
After=dbus-org.freedesktop.NetworkManager.service

[Service]
Type=oneshot
ExecStart=/usr/bin/nm-online -q -x

[Install]
Alias=check-online.service

==> /etc/NetworkManager/dispatcher.d/systemd-online <==
#!/bin/sh

systemctl restart check-online.service

==> needs-network.unit.in <==
[Unit]
Requires=online.target
After=online.target

[Install]
WantedBy=online.target
StopWhenUnneeded=true




More information about the systemd-devel mailing list