<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Dec 10, 2014 at 11:32 AM, Olaf Hering <span dir="ltr"><<a href="mailto:olaf@aepfle.de" target="_blank">olaf@aepfle.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
I wonder how systemd handles the startup time of a daemon once it did<br>
the execve (or whatever systemd does internally). Every daemon needs<br>
some time until it can service requests.<br></blockquote><div><br></div><div>It depends.</div><div><br></div><div>* 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.</div><div><br></div><div>* With socket-activated services, this doesn't matter at all, since the requests won't fail, just get queued by the kernel.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
In the following example a socket is provided, a daemon handles the<br>
socket and another tool will use the socket. How can I make sure tool B<br>
will always find an operational socket handled by A? There is the<br>
obvious startup time required within A until it can service requests.<br></blockquote><div><br></div><div>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!</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
What happens if B runs and tries to acces /path while A is still<br>
starting up?</blockquote><div><br></div><div>1) systemd will ensure that the socket is operational long before it starts any services;</div><div><br></div><div>2) when /bin/B attempts to connect, the kernel will make it wait in the "accept queue";</div><div><br></div><div>3) when A.service starts, it will inherit the already-operational socket fd from systemd;</div><div><br></div><div>4) when A finally enters its accept() loop, B's connection attempt will resume normally.</div><div><br></div><div>(The same mechanism is used by inetd/xinetd in its 'wait' mode, as well as launchd.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
A.socket:<br>
[Unit]<br>
DescriptionA socket<br>
[Socket]<br>
ListenStream=/path<br>
SocketMode=0600<br>
Service=A.service<br></blockquote><div><br></div><div>This "Service=" setting is redundant.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
B.service:<br>
[Unit]<br>
Description=B, a tool talking to A<br>
Requires=A.service<br></blockquote><div><br></div><div>Instead of this, use "Requires=A.socket" + "After=A.socket".</div></div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Mantas Mikulėnas <<a href="mailto:grawity@gmail.com" target="_blank">grawity@gmail.com</a>></div></div>
</div></div>