Linuxシステムでudevが動作し、カーネルからnetlinkソケットを介して送信されたueventを受信することは知っていました。
しかし、私の質問は次のとおりです。
カーネルはどのようにイベントを送信しますか?デバイスの追加/削除によってトリガーされ、udevにイベントを送信するものでなければなりません。カーネルはこれをどのように行いますか? (見つけることができるコード例はありますか?)
udevはこれらのueventをnetlinkソケットを介してのみ受け取ります。これは、udevが行う唯一の方法です。これは正しいです?
カーネルからueventが送信されると、ブロードキャストを実行できることがわかりました。ただし、ユニキャストはできますか?
フィードバックをありがとう。
Ueventと呼ばれるnetlinkメッセージを送信します。 ueventは、netlinkソケット経由で送信される特別な形式の単なる文字列です。例:
"add@/class/input/input9/mouse2\0 // message
ACTION=add\0 // action type
DEVPATH=/class/input/input9/mouse2\0 // path in /sys
SUBSYSTEM=input\0 // subsystem (class)
SEQNUM=1064\0 // sequence number
PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/22/22:1.0\0 // device path in /sys
PHYSDEVBUS=usb\0 // bus
PHYSDEVDRIVER=usbhid\0 // driver
MAJOR=13\0 // major number
MINOR=34\0", // minor number
実際にueventを送信するカーネル関数は kobject_uevent_env
そしてそのラッパーkobject_uevent
呼ばれる 多くの場所で 。
はい、udevはnetlinkソケットからueventを受信することで機能します。ただし、オプションがあります-カーネルはユーザーモードヘルパーを呼び出すことができます。この場合、カーネルはホットプラグイベントごとに1つのプロセスを生成し、その特定のホットプラグイベントを記述する新しいプロセスごとに環境変数を提供します。 kobject_uevent_env
ネットリンクメッセージが表示されます 実際は#ifdef
'ed そしてデフォルトのアクションは、そのユーザーモードヘルパーを呼び出すことです
理論的には、netlinkメッセージはブロードキャスト、マルチキャスト、ユニキャストが可能ですが、カーネル ブロードキャストメッセージを送信 with netlink_broadcast_filtered
呼び出し。とにかくそのメッセージは NETLINK_KOBJECT_UEVENT
ファミリー。 netlinkソケットの作成は uevent_net_init
。
コメントの質問に答えます。カーネルにはsend
関数は表示されません。 send
はシステムコールです-カーネルがユーザー空間に提供するインターフェースですが、カーネル自体はsyscallを使用しません。関数呼び出しの長いチェーンがあります( net/netlink/af_netlink.c および net/core/dev.c )kobject_uevent_env
send
を含まない最終送信へ-カーネルでskb(ソケットバッファー)を送信することは、バッファーをキューに配置し、スケジューラーを呼び出してそのバッファーを配信し、syscallで待機しているユーザースペースに通知するrecv
リソース: