Re: Bug#727708: init system thoughts
Steve Langasek wrote:
> So for a concrete example of where I think upstart's model lets us get
> things right at boot that systemd's dependency model does not (or at least,
> this hasn't been done yet in Debian), I'd like to direct your attention to
> /etc/network/if-up.d/upstart . Conceptually, there are certain kinds of
> services in a distro context that we don't want to start by default until
> "the network" is up - because they aren't set up for socket-based
> activation, or might need to bind to particular addresses/interfaces and not
> fall back gracefully, etc. Of course if we were writing all our services
> according to best practices, we wouldn't have to worry about this, as the
> service would just handle this gracefully (or maybe hand the complexity off
> to the init system for socket-based activation - but then what does init do
> with a request for a socket address that's not available? cycles within
> cycles, etc).
> But in the real world, we have a lot of services that we just want to start
> in runlevel 2 and be able to trust that the network and disk are sorted.
> This is the classic guarantee that sysvinit gave us pre-udev, but it's
> fallen apart since then because a fast system can get all the way through
> rcS before the kernel has even managed to enumerate all the network devices.
udev didn't break this assumption; this assumption became unreasonable
once people started wanting to dynamically change networks. If you have
a service that can't cope with network interfaces showing up later on,
that same service won't cope with connecting to a new wireless network,
or plugging or unplugging an Ethernet cable.
I've run into this *exact* problem with upstart, and I found it entirely
untenable. Full support for such a daemon would require not only
waiting to start it until a network becomes available, but also
reloading or restarting it every time the network changes in a way it
can't automatically cope with.
In any case, systemd does indeed "support" this case; simply make your
service depend on network-online.target, which will block for a
reasonable amount of time to see if a network interface comes online,
and eventually time out if that doesn't occur. This will actually work
even if your primary network is a wireless network managed by
NetworkManager, and even if that network doesn't actually work until the
user has logged in, assuming your service is not actually in the
dependency path of the user logging in.
Personally, I would automatically report a bug any time I found a
service depending on network-online.target or the upstart equivalent.
- Josh Triplett