Inotify - 強大而簡單的檔案更改通知系統

文件由 Robert Love 於 2005 年 3 月 15 日開始編寫 <rml@novell.com>

文件由 Zhang Zhen 於 2015 年 1 月 4 日更新 <zhenzhang.zhang@huawei.com>

  • 刪除了過時的介面,請參考手冊頁瞭解使用者介面。

  1. 原理

為什麼不將監視繫結到被監視物件的開啟 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。