GNU/Linux >> Linux の 問題 >  >> Linux

Udevの紹介:デバイスイベントを管理するためのLinuxサブシステム

Udevは、コンピューターにデバイスイベントを提供するLinuxサブシステムです。平易な英語では、ネットワークカード、外付けハードドライブ(USBサムドライブを含む)、マウス、キーボード、ジョイスティックとゲームパッド、DVD-ROMドライブなど、コンピューターに接続されているものを検出するコードです。の上。これは潜在的に有用なユーティリティであり、標準ユーザーが手動でスクリプトを作成して、特定のハードドライブが接続されているときに特定のタスクを実行するなどの操作を実行できることは十分に公開されています。

この記事では、特定のサムドライブの接続など、いくつかのudevイベントによってトリガーされるudevスクリプトを作成する方法について説明します。 udevを操作するプロセスを理解すると、ゲームパッドが接続されているときに特定のドライバーをロードしたり、バックアップドライブを接続したときに自動バックアップを実行したりするなど、あらゆる方法でudevを使用できます。

基本的なスクリプト

udevを操作する最良の方法は、小さなチャンクにすることです。スクリプト全体を事前に作成するのではなく、udevがカスタムイベントをトリガーすることを単に確認するものから始めます。

スクリプトの目標によっては、スクリプトの結果が自分の目で表示されることを保証できないため、スクリプトが正常にトリガーされたことをログに記録してください。ログファイルの通常の場所は/varです。 ディレクトリですが、それは主にrootユーザーのドメインです。テストには、 / tmpを使用します 、通常のユーザーがアクセスでき、通常は再起動するとクリーンアップされます。

お気に入りのテキストエディタを開き、次の簡単なスクリプトを入力します:

#!/usr/bin/bash

/usr/bin/date >> /tmp/udev.log

これを/usr / local / binに配置します または、デフォルトの実行可能パスのそのような場所。それをtrigger.shと呼びます もちろん、 chmod + xで実行可能にします。 。

$ sudo mv trigger.sh /usr/local/bin
$ sudo chmod +x /usr/local/bin/trigger.sh

このスクリプトはudevとは何の関係もありません。スクリプトが実行されると、タイムスタンプがファイル /tmp/udev.logに配置されます。 。スクリプトを自分でテストします:

$ /usr/local/bin/trigger.sh
$ cat /tmp/udev.log
Tue Oct 31 01:05:28 NZDT 2035

次のステップは、udevにスクリプトをトリガーさせることです。

一意のデバイスID

スクリプトがデバイスイベントによってトリガーされるためには、udevはどのような条件下でスクリプトを呼び出す必要があるかを知っている必要があります。実生活では、サムドライブは、その色、製造元、およびコンピューターに接続したばかりであるという事実によって識別できます。ただし、コンピュータには別の基準セットが必要です。

Udevは、シリアル番号、メーカー、さらにはベンダーIDと製品ID番号によってデバイスを識別します。これはudevスクリプトのライフスパンの初期段階であるため、可能な限り幅広く、非特定的で、包括的である必要があります。つまり、スクリプトをトリガーするために、最初にほぼすべての有効なudevイベントをキャッチする必要があります。

udevadmモニターを使用 コマンドを使用すると、udevをリアルタイムで利用して、さまざまなデバイスを接続したときに何が表示されるかを確認できます。ルートになって試してみてください。

$ su
# udevadm monitor

監視機能は、受信したイベントを次のように出力します:

  • UDEV:ルール処理後にudevが送信するイベント
  • カーネル:カーネルuevent

udevadmモニターを使用 実行中、サムドライブを接続し、あらゆる種類の情報が画面に表示されるのを確認します。イベントのタイプが追加であることに注意してください イベント。これは、必要なイベントの種類を特定するための良い方法です。

udevadmモニター コマンドは多くの優れた情報を提供しますが、コマンド udevadm info を使用すると、よりきれいなフォーマットで表示できます。 、サムドライブが現在 / devのどこにあるかを知っていると仮定します 木。そうでない場合は、サムドライブを取り外して再度接続し、すぐに次のコマンドを発行します。

$ su -c 'dmesg | tail | fgrep -i sd*'

そのコマンドがsdb:sdb1を返した場合 たとえば、カーネルがサムドライブに sdbを割り当てていることがわかります。 ラベル。

または、 lsblkを使用することもできます サイズやパーティションなど、システムに接続されているすべてのドライブを表示するコマンド。

ドライブがファイルシステム内のどこにあるかを確認したので、次のコマンドを使用して、そのデバイスに関するudev情報を表示できます。

# udevadm info -a -n /dev/sdb | less

これにより、多くの情報が返されます。今のところ、情報の最初のブロックに焦点を当てます。

あなたの仕事は、そのデバイスに最も固有のデバイスに関するudevのレポートの一部を選択し、それらの固有の属性が検出されたときにスクリプトをトリガーするようにudevに指示することです。

udevadm情報 (デバイスパスで指定された)デバイスに関するレポートを処理してから、親デバイスのチェーンを「ウォークアップ」します。見つかったすべてのデバイスについて、Key-Value形式を使用してすべての可能な属性を出力します。デバイスの属性と単一の親デバイスの属性に応じて一致するルールを作成できます。

looking at device '/devices/000:000/blah/blah//block/sdb':
  KERNEL=="sdb"
  SUBSYSTEM=="block"
  DRIVER==""
  ATTR{ro}=="0"
  ATTR{size}=="125722368"
  ATTR{stat}==" 2765 1537 5393"
  ATTR{range}=="16"
  ATTR{discard\_alignment}=="0"
  ATTR{removable}=="1"
  ATTR{blah}=="blah"

udevルールには、1つの親デバイスからの1つの属性が含まれている必要があります。

親属性は、デバイスを最も基本的なレベルから説明するものです。たとえば、物理ポートに接続されているものなどです。 またはサイズのあるものです またはこれはリムーバブルデバイスです

sdbのカーネルラベル以降 サムドライブを接続する前に接続された他のドライブの数に応じて変更される可能性があります。これは、udevルールの最適な親属性ではありません。ただし、概念実証として機能するため、使用できます。さらに良い候補は、これが「ブロック」システムデバイスであることを識別するSUBSYSTEM属性です(これが lsblk の理由です) コマンドはデバイスを一覧表示します。

80-local.rulesというファイルを開きます /etc/udev/rules.d 次のコードを入力します:

SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

ファイルを保存し、テストサムドライブを取り外して、再起動します。

待って、再起動 Linuxマシンで?

理論的には、 udevadm control --reloadを発行するだけです。 、これはすべてのルールをロードする必要がありますが、ゲームのこの段階では、すべての変数を削除するのが最善です。 Udevは十分に複雑であり、構文エラーが原因でそのルールが機能しなかったのか、それとも再起動する必要があるのか​​、一晩中ベッドに横になりたくありません。したがって、POSIXプライドが何を示しているかに関係なく再起動してください。

システムがオンラインに戻ったら、テキストコンソール(Ctl + Alt + F3など)に切り替えて、サムドライブを接続します。最近のカーネルを実行している場合は、ドライブを接続すると、コンソールに大量の出力が表示される可能性があります。 実行できませんでした/などのエラーメッセージが表示された場合 usr /local/bin/trigger.sh 、おそらくスクリプトを実行可能にするのを忘れたでしょう。それ以外の場合は、デバイスが接続されているか、何らかのカーネルデバイスが割り当てられているかなどが表示されることを願っています。

さて、真実の瞬間:

$ cat /tmp/udev.log
Tue Oct 31 01:35:28 NZDT 2035

/tmp/udev.logから返されたごく最近の日付と時刻が表示された場合 、udevはスクリプトを正常にトリガーしました。

ルールを有用なものに改良する

このルールの問題は、それが非常に一般的であるということです。マウス、サムドライブ、または他の誰かのサムドライブを接続すると、スクリプトが無差別にトリガーされます。今こそ、スクリプトをトリガーする正確なサムドライブに焦点を合わせ始めるときです。

これを行う1つの方法は、ベンダーIDと製品IDを使用することです。これらの数値を取得するには、 lsusbを使用できます コマンド。

$ lsusb
Bus 001 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 002 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 003 Device 005: ID 03f0:3307 TyCoon Corp.
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 hub
Bus 001 Device 003: ID 13d3:5165 SBo Networks

この例では、 03f0:3307 TyCoon Corp.の前 idVendorおよびidProduct属性を示します。これらの数値は、 udevadm info -a -n / dev /sdb|の出力でも確認できます。 grepベンダー 、しかし、 lsusbの出力が見つかりました 目には少し楽です。

これらの属性をルールに含めることができるようになりました。

SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/thumb.sh"

これをテストします(はい、udevから新鮮な反応が得られることを確認するために、再起動する必要があります)。たとえば、別の会社が製造したサムドライブを接続した場合にのみ、以前と同じように機能するはずです。 (したがって、別のidVendorを使用する場合)、またはマウスやプリンターでは、スクリプトはトリガーされません。

その1つにさらに焦点を合わせるために、新しい属性を追加し続けます スクリプトをトリガーする一意のサムドライブ。 udevadm info -a -n / dev / sdbの使用 、ベンダー名、場合によってはシリアル番号、製品名などを見つけることができます。

自分の正気のために、一度に1つの新しい属性のみを追加してください。私が犯した(そしてオンラインで他の人が犯すのを見た)ほとんどの間違いは、たくさんの属性を彼らのudevルールに投げ込み、なぜそれが機能しなくなったのか疑問に思うことです。属性を1つずつテストすることは、udevがデバイスを正常に識別できることを確認するための最も安全な方法です。

セキュリティ

これにより、ドライブが接続されたときに自動的に何かを実行するudevルールを作成するというセキュリティ上の懸念が生じます。私のマシンでは、自動マウントもオンにしていませんが、この記事では、コマンドを実行するスクリプトとルールを提案します。何かが接続されている。

ここで覚えておくべき2つのこと。

  1. udevルールが機能するようになったら、それらに焦点を合わせて、スクリプトがトリガーされるようにします あなたが本当に彼らにしたいとき。同じブランドのサムドライブを持っている人がたまたまそれをボックスに差し込んだ場合に備えて、コンピュータとの間でデータを盲目的にコピーするスクリプトを実行することはお勧めできません。
  2. udevルールとスクリプトを記述したり、忘れたりしないでください。どのコンピューターにudevルールが設定されているかはわかっています。これらのボックスは、ほとんどの場合、私のパーソナルコンピューターであり、会議に持ち込んだり、職場のオフィスに置いたりするコンピューターではありません。コンピューターが「ソーシャル」であるほど、そのコンピューターにudevルールが適用される可能性が低くなり、その結果、私のデータが他の誰かのデバイスに保存されたり、他の誰かのデータやマルウェアが私のに保存されたりする可能性があります。 デバイス。

言い換えれば、GNUシステムによって提供される多くの力と同様に、その力をどのように使用しているかに注意するのはあなたの仕事です。あなたがそれを乱用したり、敬意を持って扱わなかったりすると、それはひどくうまくいかない可能性があります。

現実世界のUdev

スクリプトがudevによってトリガーされていることを確認できたので、スクリプトの機能に注意を向けることができます。今のところ、それは役に立たず、実行されたという事実を記録するだけです。

udevを使用して、サムドライブの自動バックアップをトリガーします。アイデアは、アクティブなドキュメントのマスターコピーがサムドライブにあり(どこにでも移動でき、いつでも作業できるため)、ドライブを接続するたびにそれらのマスタードキュメントがコンピューターにバックアップされるというものです。そのマシン。つまり、私のコンピューターはバックアップドライブであり、本番データはモバイルです。ソースコードが利用可能であるため、udevテストを制約するその他の例については、attachupのコードを参照してください。

これが私がudevを最もよく使用するものなので、ここで使用する例ですが、udevはゲ​​ームパッドなど、他の多くのものを取得できます(これは、ゲームパッドが付属)とカメラとマイク(特定のマイクが接続されているときに入力を設定するのに便利です)なので、この1つの例よりもはるかに優れていることを理解してください。

私のバックアップシステムの単純なバージョンは、2つのコマンドプロセスです:

SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", SYMLINK+="safety%n"
SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

最初の行は、すでに説明した属性でサムドライブを検出し、デバイスツリー内でサムドライブにシンボリックリンクを割り当てます。割り当てられるシンボリックリンクはsafety%n です 。 %n はudevマクロであり、カーネルがデバイスに与える番号に関係なく解決します。 、sdb1、sdb2、sdb3など。つまり、%n 1または2または3になります。

これにより、開発ツリーにシンボリックリンクが作成されるため、デバイスを接続する通常のプロセスに干渉することはありません。これは、デバイスの自動マウントが好きなデスクトップ環境を使用している場合、問題が発生しないことを意味します。

2行目はスクリプトを実行します。

私のバックアップスクリプトは次のようになります:

#!/usr/bin/bash

mount /dev/safety1 /mnt/hd
sleep 2
rsync -az /mnt/hd/ /home/seth/backups/ && umount /dev/safety1

スクリプトはシンボリックリンクを使用します。これにより、udevがドライブに予期しない名前を付ける可能性を回避します(たとえば、DISKというサムドライブが既にコンピューターに接続されていて、2番目のディスクと呼ばれるもう1つのサムドライブを接続している場合) DISK_というラベルが付けられ、スクリプトが失敗します)。 safe1をマウントします (ドライブの最初のパーティション) / mnt / hdの優先マウントポイント 。

安全にマウントされると、rsyncを使用してドライブをバックアップフォルダにバックアップします(実際のスクリプトはrdiff-backupを使用し、任意の自動バックアップソリューションを使用できます)。

Udevはあなたの開発者です

Udevは非常に柔軟なシステムであり、他のほとんどのシステムがユーザーに提供することのない方法でルールと機能を定義できます。それを学び、使用し、POSIXのパワーを楽しんでください。

この記事は、 GNU Free DocumentationLicense1.3の下でライセンスされているSlackermediaHandbookのコンテンツに基づいています。


Linux
  1. 初心者向けのLinuxターミナルガイド

  2. Linux 用 Windows サブシステムの Kali

  3. Gemini PDA 用の Kali Linux

  1. Linuxコマンドラインに関する8つのヒント

  2. Linuxのchownコマンドの概要

  3. Linux:デバイスに使用されているデバイスドライバーを見つける方法は?

  1. Linuxでのalternativesコマンドの概要

  2. tarコマンドを使いこなす:Linuxでバックアップを管理するためのヒント

  3. コマンドラインでVMを管理するための8つのLinuxvirshサブコマンド