[systemd-devel] when is a service ready to be used after startup?

2014-12-10 Thread Olaf Hering

I wonder how systemd handles the startup time of a daemon once it did
the execve (or whatever systemd does internally). Every daemon needs
some time until it can service requests. 

In the following example a socket is provided, a daemon handles the
socket and another tool will use the socket. How can I make sure tool B
will always find an operational socket handled by A? There is the
obvious startup time required within A until it can service requests.

What happens if B runs and tries to acces /path while A is still
starting up?

Olaf

A.socket:
[Unit]
DescriptionA socket
[Socket]
ListenStream=/path
SocketMode=0600
Service=A.service
[Install]
WantedBy=sockets.target


A.service:
[Unit]
Description=A service
Requires=A.socke
[Service]
Type=notify
ExecStart=/bin/A
[Install]
WantedBy=multi-user.target


B.service:
[Unit]
Description=B, a tool talking to A
Requires=A.service
[Service]
Type=oneshot
ExecStart=/bin/B
[Install]
WantedBy=multi-user.target
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] when is a service ready to be used after startup?

2014-12-10 Thread Mantas Mikulėnas
On Wed, Dec 10, 2014 at 11:32 AM, Olaf Hering o...@aepfle.de wrote:


 I wonder how systemd handles the startup time of a daemon once it did
 the execve (or whatever systemd does internally). Every daemon needs
 some time until it can service requests.


It depends.

* With regular services, systemd expects the daemon itself to announce that
it's ready. You use Type=forking, Type=notify, Type=dbus to choose
which event systemd will wait for.

* With socket-activated services, this doesn't matter at all, since the
requests won't fail, just get queued by the kernel.


 In the following example a socket is provided, a daemon handles the
 socket and another tool will use the socket. How can I make sure tool B
 will always find an operational socket handled by A? There is the
 obvious startup time required within A until it can service requests.


Keep in mind that socket is operational and daemon is ready to service
requests are two separate events. With regular services, the difference is
hard to notice. But in this example, you are using socket activation, and
making these events separate is the whole point of socket activation!

What happens if B runs and tries to acces /path while A is still
 starting up?


1) systemd will ensure that the socket is operational long before it starts
any services;

2) when /bin/B attempts to connect, the kernel will make it wait in the
accept queue;

3) when A.service starts, it will inherit the already-operational socket fd
from systemd;

4) when A finally enters its accept() loop, B's connection attempt will
resume normally.

(The same mechanism is used by inetd/xinetd in its 'wait' mode, as well as
launchd.)

A.socket:
 [Unit]
 DescriptionA socket
 [Socket]
 ListenStream=/path
 SocketMode=0600
 Service=A.service


This Service= setting is redundant.

B.service:
 [Unit]
 Description=B, a tool talking to A
 Requires=A.service


Instead of this, use Requires=A.socket + After=A.socket.

-- 
Mantas Mikulėnas graw...@gmail.com
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel