udev 環境変数を systemd サービス実行に渡す

udev 環境変数を systemd サービス実行に渡す

ブロック デバイスの変更アクションにバインドされ、指定されたスクリプトを実行する既存の udev ルールを移行しています。

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", RUN+="/usr/local/bin/script"

ID_CDROM_MEDIA-0この構成では、 udev は、やなどのハードウェア デバイスに関連付けられた環境変数を渡しましたID_FS_LABEL。その後、ハードウェアの変更時に systemd を使用してサービスを開始するように udev ルールを更新しました。

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change.service"

systemd サービス ファイル:

[Unit]
Description=changes to dvd drive

[Service]
Type=oneshot
ExecStart=/usr/local/bin/script

[Install]
WantedBy=multi-user.target

この時点では、サービスは変更イベント時に実行されますが、udev の RUN コマンドによって渡される環境変数はサービスの実行に渡されません。

udev から systemd の実行環境に環境を渡すことは可能ですか、それとも明示的にパラメータを渡す必要がありますか?

答え1

udevからsystemdに環境を渡す方法は見つかりませんでしたが、udevデータベースで環境プロパティを照会することは可能です。udevadm info 指示には、環境プロパティのみを照会し、評価可能な形式で出力できる パラメータ--queryとパラメータの両方があります。--export

systemd インスタンス変数とコマンドの組み合わせを使用して、udevadm環境変数を初期化しました。

SUBSYSTEM=="block", ENV{DEVNAME}=="/dev/sr0", ACTION=="change", TAG+="systemd", ENV{SYSTEMD_WANTS}=="drive-change@%E{DEVNAME}.service"

この udev ルールは、次のサービス ファイルを実行し、DEVNAME変数をインスタンス変数としてサービスに渡します。

[Unit]
Description=changes to dvd drive

[Service]
Type=oneshot
ExecStart=/usr/local/bin/script %I

[Install]
WantedBy=multi-user.target

このインスタンス変数を使用して udev 要素の環境プロパティを評価し、問題を解決しました。

#!/bin/sh

# Systemd passes the DEVNAME as the first parameter to the script
eval $(udevadm info --query=env --export $1)

 # The rest of the script that depends on the udev environment
 ...

答え2

偉大な答え@Ben Campbell による投稿。

デバイスが udev ルールをトリガーした後に、udev 環境データベースからプロパティにアクセスする方法は次のとおりです。たとえば、USB ドライブが接続されたばかりで、そのラベルを取得したいとします。

systemd サービスによって実行されるスクリプトで、eval $(udevadm info --query=env --export $1)行の後に次のような内容を追加します。
echo $ID_FS_LABEL >> "/tmp/file.txt"

ID_PART_ENTRY_UUID同様に、などの値を取得することもできますID_VENDOR

関連情報