While fixing some tests I realized that the racy nature of a service was caused by the concept of service readiness. Systemd considers a service ready when certain conditions are met. When a service is ready things like
systemctl start foo.service return, other services may start, etc.
When a daemon uses
simple (as in
daemon: simple) mode the service becomes ready as soon as the process is alive. This is usually okay but, well, not quite in practice. If a particular system service is really designed to wait for a certain UNIX signal to arrive it may be considered ready before it manages to establish signal actions for the set of signals it expects to handle.
This issue leads to racy behavior and has lead to the design of the
sd_notify(3) mechanism whereas a service may optionally let systemd explicitly know that it is ready. This is a simple and effective idea, solving the readiness issue in general. The mechanism has also other uses that I won’t go into here.
For some time now snapd has a snapd interface called
daemon-notify that, once connected, allows a service to interact with systemd over the said socket. Because of some past security issues where sending garbage over that socket could bring the whole system down the interface is not auto-connected today. We need to perform a security audio of systemd or consider the possibility of using snapd as a proxy (if such a proxy is at all possible). The interface can still be connected by the user, if desired, as with several other interfaces that are not blocked but also not auto-connected.
The problem with this arrangement is that it completely prevents the development of snaps using
daemon: notify. When systemd is told to expect a notification message it will fail to start the service in absence of said message. This will in turn cause the snap not to install and thus make the manual connection impossible.
In theory it is possible to develop a snap in devmode, upload it to the store in strict mode, get an assertion granting the auto connect so that the
daemon-notify interface connects on installation but this is perhaps a little bit difficult in practice.
This post is here so that we know the problem and remember about it. There are two possible ways forward mentioned above: security audit and auto-connection by default or a proxy mechanism. There are also some bigger topics we could explore like making it possible to indicate a given interface connection is required to use a snap (e.g. leaving the snap as installed but inactive or in some new similar state that we don’t have a name for yet).