ターゲットソケットがリッスンしている*後*にのみsystemdサービスを開始しますか?

ターゲットソケットがリッスンしている*後*にのみsystemdサービスを開始しますか?

起動時にリスニングソケットに接続する必要があるサービスXがあります。ターゲットソケット自体は、systemdによって開始された他のサービスYによって開きます。

サービスYが正常に起動し、リスニングソケットを開いた後にのみサービスXを起動するように単位ファイル(または他の手段)に割り当てる方法はありますか?

初期接続が失敗した場合、再試行するようにサービス X を変更することはできません。さらに、固定遅延は、サービスYがリスニングソケットを開く前に他の時間がかかるため、正しく動作しない。

ベストアンサー1

systemdは少し異なる動作をする傾向があります。ソケットを作成して受信するように systemd を設定し、X などの人が接続しようとすると、systemd は Y を起動して接続を処理し、ソケットを渡します。したがって、名目上、XはYの前に開始できますが、それは問題ではありません。後で接続は Y によって処理されます。 (各接続ごとにYを再起動するように設定することもできますが、あなたの場合ではないようです。)

Yに対する最小限の変更は、独自に作成/バインドするのではなく、事前に生成されたソケットをstdin / stdoutファイル記述子として許可することです。

これは、rootで試すことなく試すことができるテスト設定です。 3つのユニットファイルが必要です。 ~/.local/share/systemd/user/mysock.socketソケットを作成して渡す方法をsystemdに指示します。

# create listening socket. on 1st connect run mysock.service
[Socket]
ListenStream=5555
Accept=false

~/.local/share/systemd/user/mysock.service(同じ名前を持つmysock)は、誰もがソケットに接続したときに開始されるサービスです。ここがYを始めるところです。私はこれをPythonに置き換えました。

[Unit]
Description=started from mysock.socket
[Service]
ExecStart=/home/meuh/bin/python/mysock.py
StandardInput=socket

最後に、Xサービスにはソケットが必要であることを示す単位があります。 XI の場合、 socat を使用してソケットに日付を書き込みます。 ~/.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

Pythonは標準入力(ファイルディスクリプタ0など)からソケットを取得し、それを適切なPythonソケットオブジェクトにラップし、操作を実行し、読み書きaccept()できます。 ~/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()

その後systemctl --user daemon-reload、Xを実行できるはずです。

systemctl --user start mysockdepend

ログでjournalctlYが開始されたことを確認し、日付とともに出力をデバッグします。

読むソケットの有効化そして2位それを発明した人から。

おすすめ記事