Udev 觸發器不會在將 CF 卡插入 USB 讀卡器時觸發(不再)
udev
當我將卡插入我的 USB 讀卡器時,我有一條規則會觸發一個 shell 腳本,該腳本會從我的 CF 卡上複製照片。這工作了一段時間。但在最近一次升級後,它已經停止工作。問題(AFAICT)是將 CF 卡插入 USB 讀卡器不再觸發任何
udev
事件,因此我的腳本永遠不會執行。(即使插入中的條目/dev/disk/by-label/
也不會出現,並且dmesg
沒有顯示任何關於插入的內容。)如果我執行(或似乎是 CF 卡出現的任何設備),我可以
udev
觸發事件。我已經使用和 執行驗證了這些事件。在我手動觸發系統後,腳本從這一點開始工作正常。fdisk -l /dev/sdf``sdh``udev``udevadm monitor``udevd --debug
我正在執行 Debian 6.0 (Squeeze),我非常有信心是幾個月前 Lenny 的升級改變了這種行為,但我不確定這是否是一些細微的變化
udev
(也許我在聽對於錯誤的事件?)或核心或 USB 堆棧中的一些更改?無論如何,有人對如何解決這個問題有建議嗎?或者從 usb-storage 模組中獲取更多調試資訊的建議?這是我正在使用的 udev 規則:
KERNEL=="sd??", SUBSYSTEM=="block", RUN+="/usr/local/bin/hot-add"
更新 #1:觸發 blockdev 和分區更改
我添加了一條規則來僅在塊設備上觸發而不是在分區上觸發(以防出現這種情況),但是當我插入 CF 卡時它也不會觸發:
KERNEL=="sd?", SUBSYSTEM=="block", RUN+="/usr/local/bin/hot-add-disk"
奇怪的是,如果我執行
fdisk -l /dev/sdf
以觸發對 CF 卡的辨識,我會收到一個“更改”事件/dev/sdf
(即使我從未收到過“添加”事件)。更新 #2:
add
uevent 觸發器有一個開放的、不完整的Debian 錯誤,它涵蓋了一些類似的領域(相關內容請跳至Update#25)。這有一些方便的提示。
對於我的設置,如果我(以 root 身份)
echo add > /sys/block/sdf/uevent
插入 CF 卡但無法辨識,這將udev
正確觸發所有事件並且我的所有腳本都正確執行。
udevadm info --query=all --name=sdf
插入CF卡前後執行無差異。如果我注入“添加”事件並重新執行udevadm
命令,我會得到更多輸出(有一些關於磁碟分區的資訊)。更新 #3:USB 讀卡器中的 USB 密鑰與 CF 卡
插入普通 USB 密鑰會
udev
立即觸發所有事件並且工作正常。將 CF 卡插入 USB 讀卡器不會。對於讀卡器來說,即使沒有插入 CF 卡,USB 設備似乎也“存在”(因此/sys/block/sdf
存在條目),但是對於 USB 密鑰,/sys/block/sdj
只有在插入 USB 密鑰時才存在。更新 #4:可能在 2.6.38 中修復
這個Ubuntu 錯誤有一個更新(最後一個),聲稱該錯誤不再存在於 2.6.38 核心中。
更新 #5:未修復(在 3.2.0 中)
我已經升級了幾次核心,甚至更換了我正在使用的主機板,但我仍然看到同樣的問題。我目前使用的是 3.2.0.0 核心。和
udev
版本 164。
**tl;博士:**請參閱下面更新 2 中的解決方案。
可悲的是,這並不是一個真正的答案,或者至少不是好消息:我感覺這無論如何都行不通——我只是覺得有點難以置信,因為我肯定認為這在過去是行得通的!
這通常是有效的,以及為什麼:大多數筆記型電腦 SD 卡讀卡器。你會發現你插入了一張 SD 卡,
udev
看到它,Linux 會掃描它的分區,自動掛載就可以了。為什麼這行得通?看lsusb
插卡前後。您會注意到,在沒有插入 SD 卡的情況下,USB 設備不存在。因此,當您插入 SD 卡時,就會發生全面的 USB 熱插拔事件。我顯示器上的讀卡器好像不是這樣工作的,它總是在那裡。當我插入 SD 卡時,我無法讓它生成任何事件。我首先查看 syslogs,然後查看
udevadm monitor
,然後usbmon
查看原始 USB 事件日誌記錄。不走運,似乎根本沒有任何插入/彈出通知/事件,無論是來自我顯示器中的讀卡器還是我電腦中便宜的 DealExtreme 讀卡器。我嘗試訪問原始設備的那一刻,核心喚醒並出現分區。同樣,打電話
udevadm trigger
,它會注意到設備。取出卡並沒有任何反應,直到我再次嘗試訪問設備並且核心意識到它已經消失了。我現在想知道的是,這怎麼可能奏效(也就是說,如果我沒有編造這段記憶)?也許某些守護程序曾經每隔幾秒鐘輪詢一次原始設備並停止這樣做?真的很難找到這方面的任何文件。
更新#1
以上都是 Debian 庫存核心。我剛剛用 Ubuntu 核心做了一些實驗,其中 SD 卡熱插拔似乎可以工作。毫不奇怪,在
usbmon
我每兩秒看到一次民意調查。這也解釋了為什麼沒有立即檢測到卡片但有輕微延遲。輪詢似乎是由核心完成的,因為它即使在單使用者模式下也會發生,除了卡在
select()
循環中之外,沒有使用者態程序做任何事情。我一直無法弄清楚這是在核心中的哪個位置完成的,如果我發現了,我會更新這篇文章。更新#2
重要的區別似乎是
/sys/block/sd?/events_poll_msecs
。在我的 Debian 機器上是 -1,在 Ubuntu 機器上是 2000。這條udev
規則似乎可以做到:# enable in-kernel media-presence polling ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", ATTR{parameters/events_dfl_poll_msecs}="2000" ACTION=="add", ATTR{removable}=="1", ATTR{events_poll_msecs}=="-1", ATTR{events_poll_msecs}="2000"