基於inotify的檔案監控方案

2021-05-21 19:33:54 字數 1585 閱讀 8017

最近在做乙個linux上的檔案監控程式,2.6核心提供了inotify機制,這僅僅是個機制,任何策略都必須自己實現,這一點從inotify不提供遞迴介面就可以看出來,如果我實時監控到目錄被建立,那麼馬上將這個新目錄加入監控表,這個想法是最初的想法,也是最直接的想法,可是仔細推敲一下就會發現這個實現有問題,比如在檢測到目錄被建立到新目錄新增到監控表的時間間隔內,新的子目錄的檔案事件以及目錄事件將被遺漏,而且會像**脫絲一樣一發不可收拾,新子目錄內又建立了乙個目錄沒有被監控到,那麼這個子子目錄內的事件將遞迴的丟失,看來這個事情很嚴重,那麼有沒有辦法呢?前面說了一種補救的辦法,可是難度太大,沒有必要,仔細想想這種丟失並不是頻繁發生,只有在像cp -r或者tar快速建立目錄時才會發生,既然我們沒有辦法實現補救方案,那麼可以從程序執行這個大框架入手,如果我們可以讓cp或者tar在監控程式加入新目錄之前不執行就可以了,於是可以通過優先順序來實現,將監控程式設定為實時fifo優先順序就可以了。當檔案系統的系統呼叫執行完,inotify開始執行的時候,最後會wake up等待inotify描述符的監控程序,而在系統呼叫返回使用者空間的時候會檢查need_sched標誌位,因為監控程序是實時排程類,優先順序是很高的,因此必定會搶占當前的檔案操作的程序,可是在多cpu上怎麼能保證這個檔案操作程序不被排程到別的cpu上呢?說實話,不能,於是有了下面的解決方案。

檔案同步方案已經找到,還是用inotify,利用inotify-tools工具的inotifywait程式對目錄進行監控,並且實時加入新建立的子目錄,為了避免遺漏,我的做法是:

單cpu方案:

解決辦法:將監控程序的優先順序設定為fifo實時優先順序,根據inotify的核心實現和2.6核心的程序排程原理(根據是2.6.x的核心源**),實時優先順序的監控程序總是可以在新子目錄建立檔案前首先加入該子目錄,這樣就不會遺漏了。

多cpu方案:

問題:因為在多cpu的情況下,即使將監控程序設定為fifo的實時程序,那麼還是可能將cp -r或者tar等快速建立子目錄和檔案的程序排程到別的cpu,從而和我們的監控程序構成競爭最終造成事件遺漏。

解決辦法:將監控程序分解為多個執行緒,每個cpu繫結乙個執行緒,這些執行緒共享乙個inotify描述符,這樣就不會造成讀取的事件重複。如此一來,在新目錄被新增以後,每個cpu上的均會執行實時fifo執行緒,從而把任何非實時程序的執行攔截。在多cpu上,實際只要有乙個檔案操作,就會喚醒所有cpu上的監控程序,這是靠ipi(處理器間中斷)實現的。

效果:經過測試,發現沒有遺漏。

仍然具有的問題:從核心源**來看,如果沒有將核心編譯成核心搶占,那麼還是有可能遺漏,只不過這種可能性非常之小,我用tar和cp -r沒有測試出來。

雖然每個cpu乙個監控程序解決了大致框架問題,但是又引入了新的問題,怎麼處理這麼多的程序間的通訊,inotifywait是用紅黑樹實現的檔案索引,那麼多的執行緒肯定會打亂紅黑樹的,於是又有了新的想法。想想看設定多個執行緒,每個cpu乙個執行緒的原因就是靠這些執行緒的優先順序是實時fifo來阻止新目錄加入監控表前的檔案操作,於是我們只要保證乙個cpu上進行實際工作,別的cpu上的執行緒不做任何監控,只是乙個樁就可以了,現在問題就是這個樁怎麼設計,很簡單,辦法有兩個,乙個就是在別的cpu的執行緒隨便實現乙個無限的等待迴圈,另乙個方案就是在別的cpu上執行inotify描述符的select而不做read,這種方案一定可以,相信我沒錯的。

基於inotify的檔案監控方案

最近在做乙個linux上的檔案監控程式,2.6核心提供了inotify機制,這僅僅是個機制,任何策略都必須自己實現,這一點從inotify不提供遞迴介面就可以看出來,如果我實時監控到目錄被建立,那麼馬上將這個新目錄加入監控表,這個想法是最初的想法,也是最直接的想法,可是仔細推敲一下就會發現這個實現有...

基於inotify的檔案監控方案

最近在做乙個linux上的檔案監控程式,2.6核心提供了inotify機制,這僅僅是個機制,任何策略都必須自己實現,這一點從inotify不提供遞迴介面就可以看出來,如果我實時監控到目錄被建立,那麼馬上將這個新目錄加入監控表,這個想法是最初的想法,也是最直接的想法,可是仔細推敲一下就會發現這個實現有...

inotify非同步檔案實時監控

inotify是linux核心提供的一組系統呼叫,它可以監控檔案系統操作,比如檔案或者目錄的建立 讀取 寫入 許可權修改和刪除等。inotify使用也很簡單,使用inotify init建立乙個控制代碼,然後通過inotify add watch inotify rm watch增加 刪除對檔案和目...