Sharing

2012年4月26日 星期四

Linux udev 筆記

http://zh.wikipedia.org/wiki/Udev
  • udev 是Linux kernel 2.6系列的設備管理器, 用來接替devfs及hotplug的功能, 依賴於升級後的Linux kernel 2.6.13的uevent介面的最新版本
  • udev支持設備的固定命名,而並不依賴於設備插入系統的順序。默認的udev設置提供了存儲設備的固定命名。任何硬碟都根據其唯一的文件系統id、磁碟名稱及硬體連接的物理位置來進行識別。
  • udev完全在用戶空間執行,而不是像devfs在核心空間一樣執行
  • udev系統可以分為三個部分
    • libudev函數庫,可以用來獲取設備的信息。
    • udevd守護進程,處於用戶空間,用於管理虛擬/dev
    • 管理命令udevadm,用來診斷出錯情況。


最常被拿來配對(match)的 udev 的基本 Rules 有下面幾種.
  • KERNEL - kernel 對於裝置會有一個預設名稱如第一顆 IDE 硬碟名稱就是 hda,第一個乙太網路就是 eth0 .
  • SUBSYSTEM - 通常會指出這是什麼裝置硬碟就是 block,乙太網路就是 net.
  • DRIVER - driver 當然就是這個裝置是靠哪一個 driver(module) 在運作的.
udev 要在命名裝置時有兩種方式 NAME 和 SYMLINK.
  • NAME - 會產生唯一裝置名稱出來.
  • SYMLINK - 是一個連結到真實裝置的 symbolic links.
比對(Matching) sysfs 屬性(attributes),  SYSFS 是存在 /sys 的一個檔案值,如 SYSFS{dev} 就是儲存在 /sys///dev   ex: /sys/block/hdc/dev

也可以用 udevinfo -ap /sys/block/sda 來看所有的資訊
                 udevadm info -a -p /sys/block/sda
                 udevinfo –a –p $(udevinfo –q path –n /dev/whatever)

裝置名稱參數

%k 代表是用 kernel 名稱來命名裝置
%n 代表是用 number 來命名裝置

http://linux.die.net/man/8/udev
http://manpages.ubuntu.com/manpages/karmic/man7/udev.7.html


BUS
Match the bus type of the device
KERNEL
Match the kernel device name
ID
Match the device number on the bus
SYSFS{filename}
Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID
PROGRAM
Call external program
RESULT
Match the returned string of the last PROGRAM call
NAME
The name of the node to be created
If given with the attribute NAME{all_partitions} it will create all 15 partitions of a blockdevice
SYMLINK
The name of a symlink targeting the node.
DEVPATH
Match the devpath of the event devices  (Ubuntu)
SUBSYSTEM
Match the subsystem of the event device (Ubuntu)
ATTR{filename}
Match sysfs attributes of the event device (Ubuntu)
TAG{key}
Search the devpath upwarrds for a devices with matching tag (Ubuntu)
RUN
Add a problem to the list of programs (Ubuntu)
LABEL
A name label to which a GOTO may jump
GOTO
Jumps to the next LABEL with a matching name
IMPORT{type}
Import a set of variables as device properties, depends on type (Ubuntu)

program: execute an external program

file: import a text file specified as the assigned value

Cmdline: Import a single property from the kernel command line

Parent: import the stored keys from the parent device



%n
Kernel number
%k
Kernel name
%M
Kernel major name
%m
Kernel minor name
%b
Bus id
%c
The string returned from execution of PROGRAM
%c{N}
A single part of the string, separated by a space character
%s{filename}
Content of a sysfs attribute
%3s{filename}
Only insert the first three characters of sysfs attribute
%p
The devpath of the device  (Ubuntu)
%E{key}
A device property value
%P
The node name of the parent device
%N
The name of a temporary device node created to provide access to the device from a external program before the real node is created


注意事項

在玩  udev rules 的時候, 發現了幾個重要的事情

  • PROGRAM 是立即執行
  • RUN 是先加到一串執行序列中, 等到所有的 rules 都  parse 完後, 才會執行
  • 比方說我寫了兩個 rule, 在某一個 udev event 進來時會先觸發 a.rule, 再觸發 b.rule a.rule 的內容為
    PROGRAM=="print.sh a.program"
    RUN+="print.sh a.run"
    
    b.rule 的內容為
    PROGRAM=="print.sh b.program"
    RUN+="print.sh b.run"
    
    那執行的結果應該會是
    a.program
    b.program
    a.run
    b.run
    
  • PROGRAM 是一個 Global variable, 任何新的 PROGRAM 都會改變他的值, 所以如果在 RUN 當中會使用到 %c, 就要特別注恴
  • 同樣的, 在某一個 udev event 進來時會先觸發 a.rule, 再觸發 b.rule a.rule 的內容如下 (echo.sh 是一個直接回傳第一個參數的 script)
    PROGRAM=="echo.sh a.program"
    RUN+="print.sh %c"
    
    b.rule 的內容為
    PROGRAM=="echo.sh b.program"
    
    那結果會是 b.program, 而不是 a.program, 原因是我們在 b.rules 裡面我們把 PROGRAM 的值改掉了, 所以當執行 RUN 裡面的指令時, 他使用到的是 PROGRAM 最終的值
  • 如果希望執行到目前的 rule 就停止, 不再往下執行, 可以加上 last_rule 這個 OPTION
  • OPTIONS="last_rule"
    


沒有留言: