On Sat, Dec 28, 2013 at 10:31:32PM -0800, Russ Allbery wrote:
> Uoti Urpala <uoti.urp...@pp1.inet.fi> writes:

> > Adding the mentioned Requires=lbcd.socket line should ensure that the
> > service is never started without the socket running. I'm quite sure that
> > daemons intended to run under systemd should have no need to implement
> > any socket-opening code themselves (unless they do something special
> > like opening a socket in the middle of operation); anything which would
> > contradict that should be a misunderstanding or a bug.

> Oh, good point, yes.  That's pretty clear from daemon(7), now that you
> mention it in that light.

> Okay, I'll take this approach in the next upload, after I get a chance to
> do some more experimentation with what that does with start and stop
> (probably tomorrow).

> Thank you for the review.  This was really helpful.

However, I think this gets to the heart of why upstart upstream has avoided
ever recommending the use of socket-based activation.  There are some fairly
fundamental problems that basically halted development of socket-based
activation in upstart (beyond merging of Scott's original implementation,
which is rudimentary, as has been noted), and a look at systemd usage on
Fedora led me to believe that systemd had not overcome these problems at
all.

If I'm not mistaken (no references to hand - sorry), systemd upstream has
claimed in the course of discussions on debian-devel that lazy activation is
not the purpose of socket-based activation, and that using socket-based
activation does not require you to pay the service startup penalty at the
time of first connection.  However, this is not borne out by my experiments
with systemd on Fedora (which I would presume to be the go-to source for
best practices of systemd service activation).

On Fedora 20, after enabling the sshd and rsync service+socket units (both
installed but disabled by default on Fedora per their policies on running
services out-of-the-box) and rebooting, I find that both port 22 and port
873 are bound by pid 1.  Only upon connecting to the socket does systemd
actually spawn the server (in the case of sshd, it spawns it as 'sshd
-i', so has to start up the server anew on each connection; in the case of
rsyncd, the .service definition is completely incompatible with socket-based
activation and any attempt to connect results in the rsyncd.socket unit
landing in a 'failed' state).

If what one is trying to accomplish here is to provide a replacement for
inetd, then this is perfectly sufficient.  But if one is trying to use
socket-based activation for the claimed purpose of ensuring service startup
ordering without the need to declare explicit dependencies, then you must
accept the penalty of lazy activation - which is almost never acceptable in
a server context (where the purpose of the machine is to run the services
that you have configured, and they should therefore not be started lazily),
and suboptimal even in a client context (since not starting services that
are on the critical path for boot until the client requests them will
potentially lead to a significant boot-time slowdown, if all the services
are doing this).

As far as I've been able to tell, the only solutions that would allow
non-lazy socket-based-activation of services in systemd all introduce
significant boot-time races, whereby it is no longer assured that systemd
will bind to the socket (and passing the socket information via the
environemnt) before starting the service.  Indeed, when I looked at this
problem on an earlier version of Fedora, I found what I believe to be a
latent security problem in the cups units, because it was nondeterministic
whether the service would start with sockets passed from systemd, or a
different set of sockets as defined in the cups config!

When I mentioned this to Lennart at DebConf this year, his response was that
"cups was special".  Well, after further investigation, I don't think it's
true that cups is special.  I think systemd socket-based activation is snake
oil, that does not do what was promised without introducing hidden
trade-offs which no one has been forced to acknowledge because too few
developers are making use of this feature today to expose the integration
problems.

Of course, it's entirely possible that I've misunderstood something here, so
I welcome your investigations with lbcd.  I'm very interested to see if your
understanding of systemd socket-based activation best practices matches my
own, and to have an opportunity to experiment with socket-based activation
in the more relevant environment of Debian unstable rather than Fedora.

FWIW, if indeed socket-based activation in systemd can't actually be used
for anything besides a glorified inetd, I think that has implications for
the discussion about daemon readiness protocols.  The argument for systemd
seems to be "use sd_notify, or if you don't like having a library dependency
then just use socket-based activation which is better anyway".  But I'm sure
there will be upstreams who don't want lazy initialization any more than
they want an external library dependency.

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slanga...@ubuntu.com                                     vor...@debian.org

Attachment: signature.asc
Description: Digital signature

Reply via email to