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.

  • 1
    Can Y be programmed to use the systemd interface and notify systemd when it is ready?
    – thrig
    Oct 30, 2016 at 15:31
  • Y is open source, so I guess anything is possible but I was hoping to find a way to do this without modifying programs. Thx.
    – bigjosh
    Oct 30, 2016 at 15:50

2 Answers 2


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:

# create listening socket. on 1st connect run mysock.service

~/.local/share/systemd/user/mysock.service (having the same name mysock) 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.

Description=started from mysock.socket

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

Description=dependent on socket listening
ExecStart=/usr/bin/socat -U tcp:localhost:5555 exec:/usr/bin/date

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

# started from /home/meuh/.local/share/systemd/user/mysock.service
# with socket on stdin/stdout
import sys, time, socket, subprocess

def debug(msg):
#    time.sleep(3)
    subprocess.call(["/usr/bin/logger", msg])

s = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
while True:
    conn, addr = s.accept()
    while True:
            data = conn.recv(100)
            debug("got "+data+"\n")
            if len(data)<=0: break

After a systemctl --user daemon-reload, you should be able to run X with

systemctl --user start mysockdepend

and 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.


systemd handles this case with socket files.

A systemd unit file named some-socket.socket would be created to represent the socket.

Then your Service X service file can include a After= directive which references the socket.

The official systemd documentation on socket files should be helpful.

  • 3
    This does not mention the modifications to service Y that have to be made, given the behaviour of service Y that is described in the question. Apply socket units to an unmodified service Y, and one ends up with multiple listening sockets only one of which works. Ironically, the socket that doesn't work will be the one that service X will try to connect to, and the actual goal of the exercise will not be achieved.
    – JdeBP
    Oct 31, 2016 at 9:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .