當寫入開始或完成時,inotify 是否會觸發通知?
想像一下兩個程序,一個讀取器和一個寫入器,通過 ext3 fs 上的正常文件進行通信。閱讀器對文件有一個 inotify
IN_MODIFY
監視。write()
Writer 在一次呼叫中將 1000 個字節寫入文件。Reader 獲取 inotify 事件,並呼叫fstat
文件。讀者看到了什麼?
- 是否有任何保證 Reader 將在文件上獲得至少 1000 個
st_size
?從我的實驗來看,似乎不是。- 是否有任何保證 Reader 實際上可以
read()
1000 字節?這發生在嚴重的 I/O 綁定框上。例如,
sar
顯示大約 1 秒的等待時間。在我的情況下,閱讀器實際上是在呼叫 inotify 事件之後等待 10 秒stat
,並且得到的結果太小。我曾希望在文件準備好之前不會傳遞 inotify 事件。我懷疑實際發生的是 inotify 事件
write()
在 Writer 中的呼叫期間觸發,並且只要恰好準備好,數據實際上就可供系統上的其他程序使用。在這種情況下,10s 是不夠的。我想我只是在尋找確認核心實際上以我猜測的方式實現 inotify 的確認。此外,如果有任何選項,可能,改變這種行為?
最後-考慮到這種行為,inotify 的意義何在?無論如何,在您收到事件之後,您都只能輪詢文件/目錄,直到數據實際可用。不妨一直這樣做,忘記inotify。
編輯 *** * 好吧,就像經常發生的那樣,我看到的行為實際上是有道理的,現在我明白了我真正在做什麼。^_^***
****我實際上是在響應文件所在目錄上的 IN_CREATE 事件。所以我實際上是在對文件進行 stat() 以響應文件的創建,而不一定是 IN_MODIFY 事件,它可能稍後會到達。
我將更改我的程式碼,以便在收到 IN_CREATE 事件後,我將訂閱文件本身的 IN_MODIFY,並且在收到 IN_MODIFY 事件之前我不會真正嘗試讀取文件。我意識到那裡有一個小視窗,我可能會錯過對文件的寫入,但這對我的應用程序來說是可以接受的,因為在最壞的情況下,文件將在最大秒數後關閉。****
****從我在核心原始碼中看到的,inotify 僅在寫入完成後才會啟動(即您的猜測是錯誤的)。
sys_write
觸發通知後,在實現系統呼叫的函式中只發生了兩件事write
:設置一些調度程序參數,以及更新文件描述符上的位置。這段程式碼早在2.6.14 就很相似。當通知觸發時,文件已經有了新的大小。檢查可能出錯的地方:
- 也許讀者從以前的文章中收到了舊的通知。
- 如果讀者打電話
stat
,然後打電話read
,反之亦然,在這之間可能會發生一些事情。如果您繼續附加到文件,呼叫stat
first 保證您將能夠閱讀那麼遠,但是在閱讀器呼叫時可能已經寫入了更多數據read
,即使它尚未收到 inotify 通知。- 僅僅因為 writer 呼叫
write
並不意味著核心將寫入請求的字元數。很少有情況可以保證原子寫入達到任何大小。然而,每次write
呼叫都保證是原子的:在某些時候數據還沒有寫入,然後突然n個字節被寫入,其中n是write
呼叫的返回值。如果您觀察到部分寫入的文件,則意味著write
返回的文件小於其大小參數。調查正在發生的事情的有用工具包括:
strace -tt
- auditd 子系統****