Linux

當寫入開始或完成時,inotify 是否會觸發通知?

  • July 12, 2012

想像一下兩個程序,一個讀取器和一個寫入器,通過 ext3 fs 上的正常文件進行通信。閱讀器對文件有一個 inotifyIN_MODIFY監視。write()Writer 在一次呼叫中將 1000 個字節寫入文件。Reader 獲取 inotify 事件,並呼叫fstat文件。讀者看到了什麼?

  1. 是否有任何保證 Reader 將在文件上獲得至少 1000 個st_size?從我的實驗來看,似乎不是。
  2. 是否有任何保證 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,反之亦然,在這之間可能會發生一些事情。如果您繼續附加到文件,呼叫statfirst 保證您將能夠閱讀那麼遠,但是在閱讀器呼叫時可能已經寫入了更多數據read,即使它尚未收到 inotify 通知。
  • 僅僅因為 writer 呼叫write並不意味著核心將寫入請求的字元數。很少有情況可以保證原子寫入達到任何大小。然而,每次write呼叫都保證是原子的:在某些時候數據還沒有寫入,然後突然n個字節被寫入,其中nwrite呼叫的返回值。如果您觀察到部分寫入的文件,則意味著write返回的文件小於其大小參數。

調查正在發生的事情的有用工具包括:

  • strace -tt
  • auditd 子系統****

引用自:https://unix.stackexchange.com/questions/42827