web-dev-qa-db-ja.com

systemd notifyの使用方法

Systemd notifyの使い方を学んでいます。プロセスが別のプロセスに通知を送信できるメカニズムのようなものだと思います。

そこで、systemd-notify --ready --status="hello"。次に、エラーが発生しました:No status data could be sent: $NOTIFY_SOCKET was not set。ソケットのようにリスナーが必要なようです。しかし、この通知を受け取るようにリスナーを作成する方法がわかりません。

また、systemdのサービスにはいくつかの異なるタイプがあることを知っています。そのうちの1つはnotifyです。博士は言った、Type=notify: identical to Type=simple, but with the stipulation that the daemon will send a signal to systemd when it is ready.。つまり、タイプがnotifyのサービスでも通知を送信できるようですが、使い方もわかりません。

6
Yves

_systemd-notify_ツールは、_Type=notify_を使用してsystemdサービスとして実行されるシェルによって使用されることを特に意図しています。

_Type=notify_を使用してサービスをセットアップすると、systemdは自動的に通信ソケットをsystemdにセットアップし、そのパスを_$NOTIFY_SOCKET_でサービスにエクスポートします。

また、サービスの準備ができているかどうか(初期化が完了しているため、systemdがステータスstartedに移行する)や、サービスの自己報告ステータスなど、そのソケットで特別なメッセージをリッスンします、これは_systemctl status mytest.service_の出力でも報告されます(mytestというサービスを想定しています)。

すべての詳細については (_systemd-notify_ のマニュアルページ)を読むことができます。ただし、そこには多くの複雑さがあります...おそらく、最後の例は、それがどのように機能するかを示すのに役立ちます。


その例を実際の実験に使用しましょう!

_/usr/local/bin/mytest.sh_など、システム内のどこかに次のようなスクリプトを作成します。

_#!/bin/bash

mkfifo /tmp/waldo
sleep 10
systemd-notify --ready --status="Waiting for data…"

while : ; do
        read a < /tmp/waldo
        systemd-notify --status="Processing $a"

        # Do something with $a …
        sleep 10

        systemd-notify --status="Waiting for data…"
done
_

_sleep 10_の出力を見て、何が起こっているかを確認できるように、いくつかの_systemctl status mytest.service_ sを追加しました。

スクリプトを実行可能にします。

_$ Sudo chmod +x /usr/local/bin/mytest.sh
_

次に、内容を含む_/etc/systemd/system/mytest.service_を作成します。

_[Unit]
Description=My Test

[Service]
Type=notify
ExecStart=/usr/local/bin/mytest.sh

[Install]
WantedBy=multi-user.target
_

次にsystemdをリロードし(ユニットについて学習するため)、それを起動します。

_$ Sudo systemctl daemon-reload
$ Sudo systemctl start mytest.service
_

次に、ステータス出力を時々監視します。

_$ systemctl status mytest.service
_

最初の10秒間はstartingであることがわかります。その後、startedになり、ステータスは「データを待機しています...」になります。

FIFOにデータを書き込みます(ルートとして実行するにはteeを使用する必要があります):

_$ echo somedata | Sudo tee /tmp/waldo
_

そしてステータスを見てください:

_$ systemctl status mytest.service
_

サービスのステータスが「データの処理中」として10秒間表示され、「データの待機中...」に戻ります。

このコードをCまたはsystemdバインディングをサポートする別の言語で記述する場合は、この目的でsd_notify()関数を使用します。 Cに精通している場合は、 sd_notify(3) のマニュアルページをご覧ください。

7
filbranden

完全な答えではありませんが、「netcat」を使用してこれまでに行きました

A)1つのターミナルセッションで、次の操作を行います。

export NOTIFY_SOCKET=/tmp/test.sock
nc -l -U -u /tmp/test.sock

B)別のターミナルセッションを開き、次の操作を行います。

export NOTIFY_SOCKET=/tmp/test.sock
systemd-notify --read --status="hello"`

これは機能しますが、netcat側ではnc: connect: Invalid argument。私はそれを回避する方法を知りません。

1
Jos

メッセージ形式sd_notifyを学ぶには、これを試すことができます:

ターミナル1:

$ socat unix-recv:/tmp/test.sock -

ターミナル2:

$ NOTIFY_SOCKET=/tmp/test.sock systemd-notify --ready --status="hello"

ターミナル1に結果が表示されます。

READY=1
STATUS=hello
0
osexp2003