systemd tende a funcionar de forma ligeiramente diferente. Você configura o systemd para criar e escutar no socket, e se alguém quiser que o X tente se conectar, então o systemd inicia o Y para manipular a conexão, passando o socket para ele. Então X pode começar de forma tradicional antes de Y, mas isso não importará. As conexões posteriores serão tratadas por Y. (Você também pode configurá-lo para que Y seja reiniciado para cada conexão, mas presumo que esse não seja o seu caso).
As mudanças mínimas para Y são para aceitar o soquete pré-criado como seu descritor de arquivo stdin / stdout, em vez de criar / vincular-se.
Aqui está uma configuração de teste que você pode tentar, não como root. Você precisa de 3 arquivos de unidade.
~/.local/share/systemd/user/mysock.socket
diz ao systemd para criar o socket e como passá-lo:
# create listening socket. on 1st connect run mysock.service
[Socket]
ListenStream=5555
Accept=false
~/.local/share/systemd/user/mysock.service
(com o mesmo nome mysock
) é o serviço que será iniciado se alguém se conectar ao soquete. É aqui que você inicia o Y, que eu substituí por algum python.
[Unit]
Description=started from mysock.socket
[Service]
ExecStart=/home/meuh/bin/python/mysock.py
StandardInput=socket
Finalmente, o seu serviço X tem uma Unidade dizendo que requer o socket. Para X, estou usando uma socat que grava a data no soquete.
~/.local/share/systemd/user/mysockdepend.service
[Unit]
Description=dependent on socket listening
Requires=mysock.socket
[Service]
ExecStart=/usr/bin/socat -U tcp:localhost:5555 exec:/usr/bin/date
O python pega o socket em stdin, ou seja, descritor de arquivo 0, e o coloca em um objeto de soquete python adequado, faz um accept()
e pode ler / escrever nele:
~/bin/python/mysock.py
#!/usr/bin/python
# 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])
debug("start\n")
s = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
while True:
conn, addr = s.accept()
conn.send("hello\n")
while True:
try:
data = conn.recv(100)
debug("got "+data+"\n")
if len(data)<=0: break
except:
break
conn.close()
Após um systemctl --user daemon-reload
,
você deve ser capaz de executar o X com
systemctl --user start mysockdepend
e veja nos logs com journalctl
que Y foi iniciado e a saída de depuração com a data.
Leia sobre ativação de sockets e 2nd do homem que a inventou.