背景:
昨天在gnome的一個panel上加了幾個disk Mounter的按鈕,每個都有一個設置的界面,需要設mount的位置,
當Mouse點擊時,disk mounter會調用mount程序,具體mount什麼設置由/etc/fstab來決定,
/dev/hde1 /media/ms0 vfat user,sync,noauto,uni_xlate 0 0/dev/hdg1 /media/cf0 vfat user,sync,noauto,uni_xlate 0 0
當MS插入系統時,系統發現他是一個BLOCK設備,於是就在/hde開始找第一個安全空閒的盤符,同樣CF插入的情況也類似,
這裡有一個問題,當CF先插入時,系統會把/dev/hde1分配給它。此時對應的關系就發生了混亂。
為了解決這個問題可以使用Linux2.6kernel的UDEV規則。
udev規則簡介
關於這個規則,有一篇很經典的英文說明 http://www.reactivated.net/writing_udev_rules.Html
udev是一種Linux2.6內核采用的/dev 目錄的管理系統,它通過從sysfs獲得的信息,可以提供對特定設備的固定的設備名。
sysfs是linux 2.6內核的一種新型文件系統,它提供了當前設備的基本信息。
udev的一個重要目的就是提供固定的設備名,像我們剛才碰到的情況,如果ms插入系統,系統能使用固定的設備名
(例如/dev/ms) CF卡插入系統,使用/dev/cf,就可以很方便的解決我們需要到的困難。
/etc/udev/rules.d/ 下面的文件根據字母的順序來解析,一般udev當找到滿足它條件的說明項後就會終於解析過程,
因為為了使用我們的配置優先於系統的默認值,選擇文件名時一定要注意,例如,我們選擇 /etc/udev/rule.d/10-local.rules
BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
上面是一個USB打印機的印子。當一台USB打印機序列號是HXOLL0012202323480,就會創建一個device名 /dev/lpepson,
同時創建一個symbol link /dev/printers/epson_styles
注意:在任何規則修改後,為了讓它生效:需要執行udevstart
規則書寫格式
最方便的查找方法是 man udev 或在線文檔 http://www.die.net/doc/linux/man/man8/udev.8.html
常用的有
* BUS - 匹配總路類型,比如PCI USB等 * KERNEL - 匹配Kernel設備名,比如hda hdb. * DRIVER - 匹配Kernel的驅動程序名 * SUBSYSTEM - 匹配子系統名。 * ID - 匹配總路系統的ID (e.g. PCI bus ID)。 * PLACE - 匹配物理位置 (對USB很有用)。 * SYSFS{filename} - 匹配從sysfs得到的信息,比如label, vendor, USB serial number, SCSI UUID or file system label. * PROGRAM - 調用外部程序。 * RESULT - 匹配最後一次調用外部程序所得到的返回字符串 * NAME - 需要創建的設備或 * SYMLINK -需要創建的符號鏈接名 * OWNER, GROUP, MODE 設置設備的所有者,組,及模式
匹配符號:
%n 內核設備號 例如 sda3 的3 %k 內核設備名 %M 設備的major號 %m 設備的minor號 %b bus id %c %s{filename} sysfs屬性的內容 %% 引用%時使用 * 可以匹配任意個字符 ? 可以匹配一個字符 [ ] 從中選一個字符sample:
# if /sbin/scsi_id returns "OEM 0815" device will be called disk1BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="OEM 0815", NAME="disk1"# USB printer to be called lp_colorBUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_color"# SCSI disk with a specific vendor and model number will be called bootBUS="scsi", SYSFS{vendor}="IBM", SYSFS{model}="ST336", NAME="boot%n"# sound card with PCI bus id 00:0b.0 to be called dspBUS="pci", ID="00:0b.0", NAME="dsp"# USB mouse at third port of the second hub to be called mouse1BUS="usb", PLACE="2.3", NAME="mouse1"# ttyUSB1 should always be called pda with two additional symlinksKERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld"# multiple USB webcams with symlinks to be called webcam0, webcam1, ……BUS="usb", SYSFS{model}="XV3", NAME="video%n", SYMLINK="webcam%n"
查看sysfs的信息
這裡使用udevinfo的指令, man udevinfo 在線文檔http://www.die.net/doc/linux/man/man8/udevinfo.8.html 基本用法
-a SYSFS{filename} attributes along the device chain. -p sysfs_path Specify the sysfs path of the device to query. -q query_type Query the database for specified value of a created device node or network interface. valid type: name, symlink, mode ,owner , group , path or all. -n name Specify the name of the node, the symlink or the network interface for the device to queue sample:
udevinfo -a -p /sys/path/to/hardware/info udevinfo -a -p /sys/block/sda udevinfo -q path -n /dev/sda 聯起來用: # udevinfo -a -p $(udevinfo -q path -n /dev/sda)
測試方法
# udevtest /sys/class/sound/dsp/version 056looking at '/class/sound/dsp/'opened class_dev->name='dsp'configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, added symlink '%k'configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, 'dsp' becomes 'sound/%k'creating device node '/dev/sound/dsp', major = '14', minor = '3', mode = '0660', uid = '0', gid = '18'
實際的例子
010_local.rules
#Clie th55#syncBUS="usb", SYSFS{prodUCt}="Palm Handheld", KERNEL="ttyUSB*", SYMLINK="pilot%n"#eXPortBus="usb", SYSFS{product}="Sony PEG Mass Storage", KERNEL="sd*",SYMLINK="cliems"#usb HDDBUS="usb", SYSFS{product}="USB TO IDE", KERNEL="sd*", SYMLINK="usbhdd%n"#cf1 used for 5in1 card readerBUS="ide", ID="2.0", KERNEL="hd*", SYMLINK="ms"]