原子刪除目錄

原子刪除目錄

因為rename(2)被 調用mv,所以可以安全地假設以下內容是原子的嗎?

$ mv /home/me/someDir /tmp/toBeDeleted
$ rm -rf /tmp/toBeDeleted

答案1

mv命令稱為rename系統調用,保證是原子的。但是,有兩個例外:

  • 如果來源和目標位於不同的檔案系統上(這對/homevs.來說是相對常見的) /tmp,則rename失敗,mv然後透過將來源樹複製到目標,然後刪除來源樹來運作。這顯然不是原子的。
  • 有些檔案系統不是rename原子的,例如 NFS 的某些實作。在任何「正常」本機檔案系統上,rename都是原子的。

答案2

如果目錄位於作為單一檔案系統安裝的相同硬體分割區上,那麼移動某些東西實際上只是將其重命名為不同的路徑。但是,如果不是,則可能需要讀入並複製其中的每個文件,因此移動的任何部分都不是原子的。正如 Gilles 指出的,POSIX 規定離散檔案系統就是這種情況。

strace除此之外,使用確認進行快速檢查mv確實使用了rename()系統呼叫(不要與rename命令列實用程式混淆)。從用戶空間的角度來看,這將使mv目錄成為原子的。如果出現以下情況,系統rename()呼叫將拋出 EBUSY 錯誤:

oldpath 或 newpath 是某個進程正在使用的目錄(可能作為當前工作目錄,或作為根目錄,或因為它已開啟以供讀取)或正在被系統使用(例如作為掛載點),而係統認為這是一個錯誤。 (請注意,在這種情況下不需要返回 EBUSY — 無論如何進行重命名都沒有問題 — 但如果系統無法以其他方式處理此類情況,則允許返回 EBUSY。)

man 2 rename。這裡與「原子性」的連結是,你不能中斷在目錄中工作的另一個進程,另一個進程也不能中斷它——如果你擊敗它,它最終會出現無效路徑/未找到類型錯誤追逐。

答案3

這兩個答案本質上說的是同一件事,但只關注刪除的一個面向。

如果您的 shell 的工作目錄位於重新命名/移動的目錄樹中,它將繼續使用這些檔案直到它們被實際刪除。因此,shell 將看到處於不同刪除狀態的文件,因此,重新命名/移動(同時 可能“原子”本身)是不是從文件的所有使用者的角度來看,這是一種原子形式的刪除。它只會影響 shell 從一開始就位於目錄樹之外的使用者。

shell 維護自己有關其所在目錄的資訊。受保護目錄的符號連結。

POSIX 對於該行為的原因含糊不清,但確實指出了該行為pwd(外殼內置)和cd(外殼內置)。

相關內容