I have a service X that needs to connect to listening socket when it starts. That target socket is itself opened by another service Y started by systemd.
Is there any way to specify in the unit file (or otherwise) to only start service X after service Y has successfully started and opened the listening socket?
Note that I can not change service X to retry if the initial connect fails. Also fixed delays don't work well either because service Y takes varying amounts of time before it opens the listening socket.
Best Answer
systemd tends to work slightly differently. You configure systemd to create and listen on the socket, and should anyone like X try to connect, then systemd launches Y to handle the connection, passing it the socket. So X can start notionally before Y, but it will not matter. Later connections will be handled by Y. (You can also configure it so Y is restarted for each connection, but I presume that is not your case).
The minimal changes to Y are to have it accept the pre-created socket as its stdin/stdout file descriptor, instead of doing the create/bind itself.
Here's a test setup you can try, not as root. You need 3 unit files.
~/.local/share/systemd/user/mysock.socket
tells systemd to create the socket and how to pass it on:~/.local/share/systemd/user/mysock.service
(having the same namemysock
) is the service that will be started should anyone connect to the socket. This is where you start Y, which I have replaced by some python.Finally, your X service has a Unit saying it requires the socket. For X I am using a socat that writes the date to the socket.
~/.local/share/systemd/user/mysockdepend.service
The python takes the socket on stdin, i.e. file descriptor 0, and wraps it into a suitable python socket object, does an
accept()
and can read/write to it:~/bin/python/mysock.py
After a
systemctl --user daemon-reload
, you should be able to run X withand see in the logs with
journalctl
that Y was started, and the debug output with the date.Read about socket activation and 2nd from the man who invented it.