Linux INotif機制
一、 前言:
眾所周知,Linux 桌面系統與 MAC 或 Windows 相比有許多不如人意的地方,為了改善這種狀況,開源社區提出用戶態需要內核提供一些機制,以便用戶態能夠及時地得知內核或底層硬件設備發生了什么,從而能夠更好地管理設備,給用戶提供更好的服務,如 hotplug、udev 和 inotify 就是這種需求催生的。Hotplug 是一種內核向用戶態應用通報關于熱插拔設備一些事件發生的機制,桌面系統能夠利用它對設備進行有效的管理,udev 動態地維護 /dev 下的設備文件,inotify 是一種文件系統的變化通知機制,如文件增加、刪除等事件可以立刻讓用戶態得知,該機制是著名的桌面搜索引擎項目 beagle 引入的,并在 Gamin 等項目中被應用。
事實上,在 inotify 之前已經存在一種類似的機制叫 dnotify,但是它存在許多缺陷:
1. 對于想監視的每一個目錄,用戶都需要打開一個文件描述符,因此如果需要監視的目錄較多,將導致打開許多文件描述符,特別是,如果被監視目錄在移動介質上(如光盤和 USB 盤),將導致無法 umount 這些文件系統,因為使用 dnotify 的應用打開的文件描述符在使用該文件系統。
2. dnotify 是基于目錄的,它只能得到目錄變化事件,當然在目錄內的文件的變化會影響到其所在目錄從而引發目錄變化事件,但是要想通過目錄事件來得知哪個文件變化,需要緩存許多 stat 結構的數據。
3. Dnotify 的接口非常不友好,它使用 signal。
Inotify 是為替代 dnotify 而設計的,它克服了 dnotify 的缺陷,提供了更好用的,簡潔而強大的文件變化通知機制:
1. Inotify 不需要對被監視的目標打開文件描述符,而且如果被監視目標在可移動介質上,那么在 umount 該介質上的文件系統后,被監視目標對應的 watch 將被自動刪除,并且會產生一個 umount 事件。
2. Inotify 既可以監視文件,也可以監視目錄。
3. Inotify 使用系統調用而非 SIGIO 來通知文件系統事件。
4. Inotify 使用文件描述符作為接口,因而可以使用通常的文件 I/O 操作select 和 poll 來監視文件系統的變化。
Inotify 可以監視的文件系統事件包括:
IN_ACCESS,即文件被訪問
IN_MODIFY,文件被 write
IN_ATTRIB,文件屬性被修改,如 chmod、chown、touch 等
IN_CLOSE_WRITE,可寫文件被 close
IN_CLOSE_NOWRITE,不可寫文件被 close
IN_OPEN,文件被 open
IN_MOVED_FROM,文件被移走,如 mv
IN_MOVED_TO,文件被移來,如 mv、cp
IN_CREATE,創建新文件
IN_DELETE,文件被刪除,如 rm
IN_DELETE_SELF,自刪除,即一個可執行文件在執行時刪除自己
IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動自己
IN_UNMOUNT,宿主文件系統被 umount
IN_CLOSE,文件被關閉,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE,文件被移動,等同于(IN_MOVED_FROM | IN_MOVED_TO)
注:上面所說的文件也包括目錄。
二、用戶接口
在用戶態,inotify 通過三個系統調用和在返回的文件描述符上的文件 I/ 操作來使用,使用 inotify 的第一步是創建 inotify 實例:
int fd = inotify_init ();
每一個 inotify 實例對應一個獨立的排序的隊列。
文件系統的變化事件被稱做 watches 的一個對象管理,每一個 watch 是一個二元組(目標,事件掩碼),目標可以是文件或目錄,事件掩碼表示應用希望關注的 inotify 事件,每一個位對應一個 inotify 事件。Watch 對象通過 watch描述符引用,watches 通過文件或目錄的路徑名來添加。目錄 watches 將返回在該目錄下的所有文件上面發生的事件。
新聞熱點
疑難解答