同じ uuid とラベルを持つセットから一意の USB ドライブを udev に認識させるには? RHEL7

同じ uuid とラベルを持つセットから一意の USB ドライブを udev に認識させるには? RHEL7

RHEL7 で udev を設定して、USB フラッシュ ドライブに特定のフラッシュ ドライブの特定の /dev 名 (つまり、/dev/backup1、/dev/backup2....) を割り当てようとしています。/dev/sdx の割り当てを制御できないことはわかっていますが、udev ルールを使用して自動化されたシンボリック リンクを設定しようとしています。

blkid は私に次のことを与えます:

/dev/sdi1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"
/dev/sdj1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"
/dev/sdk1: LABEL="Samsung USB" UUID="64A5-F009" TYPE="exfat"

私は次のようなことをしたかったのです:ルールファイルで

KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/lib/udev/scsi_id --whitelisted --replace-whitespace --device=%N", RESULT=="64A5-F009", SYMLINK+="backupkeya%n"

しかし、3 つの USB フラッシュ ドライブはすべて同じ UUID を持っているため、特定のフラッシュ ドライブを特定の仮想デバイス名にリンクさせたいと考えました。したがって、「drive2」というラベルの付いたドライブを接続すると、/dev/backupkeyb にリンクされます。現在、フラッシュ ドライブは 3 つありますが、8 つ程度に拡張したいと考えています。

udevadm は私に独自性を与えてくれます...

[root@alpha2 mnt]# udevadm info /dev/sdg | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0305119070014252
[root@alpha2 mnt]# udevadm info /dev/sdi | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0330219070015017
[root@alpha2 mnt]# udevadm info /dev/sdj | grep "ID_SERIAL_SHORT"
E: ID_SERIAL_SHORT=0305119070014208  

udevルールを次のように変更しました (/etc/udev/rules.d/99-symlink.rules)

KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/bin/udevadm info --name=%N", RESULT=="0305119070014208", SYMLINK+="backupkeyc%n"

しかし、シリアル番号が ...4208 のキーを挿入すると、/dev/backupkeyc シンボリックリンクは作成されませんでした。udevadm ステートメントの出力が RESULT== と完全に一致しなかったためと思われます。

スクリプト /usr/local/udevinfo を作成し、PROGRAM=="/usr/local/udevinfo %N" を以下のように変更して、udev ルールが乱雑にならないようにしました...フラッシュ ドライブを挿入した後 (シンボリック リンクなし)、さらに重要なのは、デバイス名が含まれているはずの /tmp/passeddata に何もなかったことです。つまり、udev ルールが実行されなかったように見えます。

echo "$1" >> /tmp/passeddata
udevadm info --name=$1 | grep "ID_SERIAL_SHORT" | awk -F= '{print $2}'

何か見落としていることはありませんか? 私がやろうとしていることを実行するより簡単な方法はありますか?

答え1

はい、完全に一致したわけではありません。「udevadm info」はシリアル番号だけでなく、さまざまな情報を出力するからです。

しかし、「udevadm info」に表示されるものはによって設定されましたudev ルール自体 (多くの場合、udev 組み込み関数を呼び出すことによって)。したがって、シリアル番号は、ENV{ID_SERIAL_SHORT}=="..."外部プログラムを呼び出すことなく、すでに使用可能です。 (これが、"E:" プレフィックスが実際に示しているものです。)

KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_SERIAL_SHORT}=="0305119070014208", SYMLINK+="backupkeyc"

(実際、「udevadm info」が機能しない可能性がありますまったくルール処理中。udev ルールでよくある間違いは、「ルール終了」シグナルからのみ情報を取得するツールを使用しようとすることです。

答え2

私は、そのようなソリューションにスクリプトを使用せず、直接 env を使用するという @grawity の回答に完全に同意します。ただし、他の側面については:

プログラムの構文は、あなたが書いたとおりに正しく、機能します。ファイルが作成されないファイルには何も含まれていないということでしょうか? つまり、シェバン行 (スニペットのように) または実行権限が欠落しているのでしょうか? それ以外の場合は、そのように動作するはずです。また、udev が認識しているすべての情報は環境変数として使用できるため、引数を渡す必要もありません。したがって、スクリプトは、udev ルールの PROGRAM ステートメントによって呼び出されたときにそれらにアクセスできます。

しかし、別のアプローチに従う方がはるかに便利で汎用的であるはずです。
デバイスのシリアル番号を使用せず、UUID またはパーティション ラベル (または、同じ UUID またはパーティション ラベルを持つ他のものが挿入される可能性を下げるために両方) を割り当てます。したがって、パーティションを再ラベルするか、再フォーマットして、新しい "UUID" を設定します。再フォーマットしたくない場合は、既存のパーティション内の UUID 情報をパッチすることもできます (これを行うツールについては知りませんが、独自のツールを作成するのは非常に簡単です)。
そのようにすると、システムを変更せずにターゲットを置き換えることができます。または、たとえば、プールにスティックを追加します。
その場合は、特定の形式のパーティション ラベルを特定の形式のシンボリック リンク名に変換する小さなプログラム スクリプトを使用することをお勧めします。
もう 1 つの方法 (実行可能であれば、最も標準的な方法) は、デバイスで GPT を使用し、ユース ケースに合わせて特定のパーティション タイプと -UUID の組み合わせ (場合によっては追加のパーティション名) を割り当てることです。

関連情報