Inotify - 強大而簡單的檔案更改通知系統¶
文件由 Robert Love 於 2005 年 3 月 15 日開始編寫 <rml@novell.com>
文件由 Zhang Zhen 於 2015 年 1 月 4 日更新 <zhenzhang.zhang@huawei.com>
刪除了過時的介面,請參考手冊頁瞭解使用者介面。
原理
- 問
為什麼不將監視繫結到被監視物件的開啟 fd 上?
- 答
監視與開啟的 inotify 裝置相關聯,而不是與開啟的檔案相關聯。 這解決了 dnotify 的主要問題:保持檔案開啟會鎖定檔案,更糟糕的是,還會鎖定掛載點。 因此,Dnotify 對於具有可移動媒體的桌面系統是不可行的,因為無法解除安裝媒體。 監視檔案不應要求它處於開啟狀態。
- 問
為什麼使用每個例項一個 fd,而不是每個監視一個 fd?
- 答
每個監視一個 fd 很快就會消耗比允許的更多的檔案描述符,比管理可行的更多的 fd,以及比最佳 select()-able 更多的 fd。 是的,root 可以提升每個程序的 fd 限制,是的,使用者可以使用 epoll,但要求兩者都是愚蠢且無關的要求。 監視消耗的記憶體比開啟的檔案少,因此,分離數字空間是有意義的。 當前的設計是使用者空間開發人員想要的:使用者初始化 inotify 一次,並新增 n 個監視,但只需要一個 fd,無需調整 fd 限制。 初始化一個 inotify 例項兩千次是很愚蠢的。 如果我們可以乾淨地實現使用者空間的偏好——我們可以,idr 層使此類事情變得微不足道——那麼我們應該這樣做。
還有其他好的論點。 使用單個 fd,只有一個專案可以阻塞,該專案對映到單個事件佇列。 單個 fd 返回所有監視事件以及任何潛在的帶外資料。 如果每個 fd 都是單獨的監視,
將無法獲得事件排序。 檔案 foo 和檔案 bar 上的事件會彈出 poll() 在兩個 fd 上,但是無法分辨哪個先發生。 單個佇列可以輕鬆地為您提供排序。 這種排序對於 Beagle 等現有應用程式至關重要。 想象一下沒有排序的“mv a b ; mv b a”事件。
我們將不得不維護 n 個 fd 和 n 個帶有狀態的內部佇列,而不是隻有一個。 在核心中會更加混亂。 單個線性佇列是有意義的資料結構。
使用者空間開發人員更喜歡當前的 API。 例如,Beagle 的人們喜歡它。 相信我,我問過了。 這並不奇怪:誰願意透過 select 管理和阻塞 1000 個 fd?
無法獲得帶外資料。
1024 仍然太低了。 ;-)
當您談論設計一個可擴充套件到數千個目錄的檔案更改通知系統時,處理數千個 fd 似乎不是正確的介面。 它太重了。
此外,_是_可以擁有多個例項並處理多個佇列,因此可以處理多個關聯的 fd。 不需要每個程序一個 fd 的對映; 它是每個佇列一個 fd,並且一個程序很容易需要多個佇列。
- 問
為什麼採用系統呼叫方法?
- 答
糟糕的使用者空間介面是 dnotify 的第二大問題。 訊號是檔案通知的糟糕、糟糕的介面。 或者對於任何事情,就此而言。 從所有角度來看,理想的解決方案是基於檔案描述符的解決方案,該解決方案允許基本的檔案 I/O 和 poll/select。 獲取 fd 和管理監視可以透過裝置檔案或一系列新的系統呼叫來完成。 我們決定實現一系列系統呼叫,因為這是新核心介面的首選方法。 唯一的真正區別是我們是否想使用 open(2) 和 ioctl(2) 或幾個新的系統呼叫。 系統呼叫優於 ioctls。