Linux 爲什麼多進程能夠讀寫正在刪除的文件

Linux中多進程環境下,打開同一個文件,當一個進程進行讀寫操作,如果另外一個進程刪除了這個文件,那麼讀寫該文件的進程會發生什麼呢?

  • 因爲文件被刪除了,讀寫進程發生異常?
  • 正在讀寫的進程仍然正常讀寫,好像沒有發生什麼?

學操作系統原理的時候,我們知道,linux是通過link的數量來控制文件刪除,只有當一個文件不存在任何link的時候,這個文件纔會被刪除。

而每個文件都會有2個link計數器i_count 和 i_nlink。i_count的意義是當前使用者的數量,也就是打開文件進程的個數。i_nlink的意義是介質連接的數量;或者可以理解爲 i_count是內存引用計數器,i_nlink是硬盤引用計數器。再換句話說,當文件被某個進程引用時,i_count 就會增加;當創建文件的硬連接的時候,i_nlink 就會增加。

對於 rm 而言,就是減少 i_nlink。這裏就出現一個問題,如果一個文件正在被某個進程調用,而用戶卻執行 rm 操作把文件刪除了,會出現什麼結果呢?

當用戶執行 rm 操作後,ls 或者其他文件管理命令不再能夠找到這個文件,但是進程卻依然在繼續正常執行,依然能夠從文件中正確的讀取內容。這是因爲,rm 操作只是將 i_nlink 置爲 0 了;由於文件被進程引用的緣故,i_count 不爲 0,所以系統沒有真正刪除這個文件。i_nlink 是文件刪除的充分條件,而 i_count 纔是文件刪除的必要條件。

基於以上只是,大家猜一下,如果在一個進程在打開文件寫日誌的時候,手動或者另外一個進程將這個日誌刪除,會發生什麼情況?

雖然日誌文件被刪除了,但是有一個進程已經打開了那個文件,所以向那個文件中的寫操作仍然會成功,數據仍然會提交。

下面,告訴大家如何恢復那個刪除的文件。

例如,你刪除了tcpdump.log,執行lsof | grep tcpdump.log,你應該能看到這樣的輸出:

tcpdump 2864 tcpdump 4w REG 253,0 0 671457 /root/tcpdump.log (deleted)

然後:

cp /proc/2864/fd/4 /root/tcpdump.log



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章