重要なサービスが停止したら、スクリプトを実行して自分に知らせるか、事前定義されたタスクを実行してサービスを復元できるように、実行中のサービスの状態に接続したいと思います。
答え1
いいえどの提供する。 systemd 管理者の dbus インターフェイスは、このタイプのグローバル通知を提供しません。グローバルにトリガされる信号を探している場合、管理者の信号はパフォーマンス上の理由でわずかに制限されます。
$ busctl introspect org.freedesktop.systemd1 \
/org/freedesktop/systemd1 \
org.freedesktop.systemd1.Manager \
| grep signal
.JobNew signal uos - -
.JobRemoved signal uoss - -
.Reloading signal b - -
.StartupFinished signal tttttt - -
.UnitFilesChanged signal - - -
.UnitNew signal so - -
.UnitRemoved signal so - -
完全なインターフェイスはここで見ることができます:
https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html
ただし、特定のサービスの状態が変更されたかどうかを知りたい場合は、その特定のサービスに参加してください。例: sshd.service:
$ busctl introspect \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/sshd_2eservice \
org.freedesktop.DBus.Properties
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Get method ss v -
.GetAll method s a{sv} -
.Set method ssv - -
.PropertiesChanged signal sa{sv}as - -
.PropertiesChanged
属性が変更されるたびにシグナルが発生します。
興味を持っている可能性のあるプロパティはまたはインターフェイスにあります.ActiveState
。.SubState
org.freedesktop.systemd1.Unit
$ busctl introspect \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/sshd_2eservice \
org.freedesktop.systemd1.Unit
...
.ActiveState property s "active" emits-change
.SubState property s "running" emits-change
それでは、どのように購読してこのデータを入手できますか?どのようにスクリプトを書くのかわかりませんが、#include <systemd/sd-bus.h>
sd-bus API()を使ってCで何かを書いてみましょう。これには次のステップが必要です。
- オープンバス:
int r = sd_bus_default_system(&m_bus);
- 特定のユニットの変更を購読してください。
sd_bus_match_signal(
m_bus,
NULL, // slot
NULL, // sender
"/org/freedesktop/systemd1/unit/sshd_2eservice", // path
"org.freedesktop.DBus.Properties", // interface
"PropertiesChanged", // member
callback, // callback
NULL // userdata
);
sd_bus_match_signal(
m_bus,
NULL,
NULL,
"/org/freedesktop/systemd1/unit/network_2etarget",
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
callback,
NULL
);
- 変更に応じて新しい状態を取得します。
int callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error)
{
sd_bus_error err = SD_BUS_ERROR_NULL;
char* msg = NULL;
int r;
r = sd_bus_get_property_string(m_bus,
"org.freedesktop.systemd1",
sd_bus_message_get_path(m), // (/org/freedesktop/systemd1/unit/sshd_2eservice)
"org.freedesktop.systemd1.Unit",
"ActiveState",
&err,
&msg);
if (r < 0) { /* Error */ }
sd_bus_error_free(&err);
printf("Property change, state is: %s\n", msg);
free (msg);
}
関連する答えは次のとおりです。 https://stackoverflow.com/questions/61940461/how-to-get-the-state-of-a-service-with-sd-bus/62038047#62038047
答え2
簡単な可能性はログ出力を追跡することですjournalctl -f
。簡単な解析のためにjsonを含むいくつかの出力フォーマットオプションがあります。