理解Linux中的陳舊檔案控制代碼
概述
在本文中,我們將討論陳舊檔案控制代碼的概念以及如何在應用程式中避免它。我們還將看到一些關於如何使用fcntl()函式檢查檔案控制代碼是否有效的例子。
本教程中的程式碼已在帶有GNU Bash 5.0.3的Debian 10.10 (Buster)上進行了測試。它是POSIX相容的,應該在任何此類環境中都能工作。
什麼是陳舊檔案控制代碼?
檔案控制代碼可以被認為是一個整數,它代表特定檔案的訪問許可權。檔案系統維護所有開啟的檔案及其相應檔案控制代碼的列表。當使用“close”命令關閉檔案時,作業系統會自動將其引用從其內部資料結構中刪除,並相應地更新檔案描述符表(FDT)。這意味著當您嘗試開啟另一個同名的檔案時,作業系統會檢查是否與該檔名關聯的任何現有檔案控制代碼。如果是,則將現有檔案控制代碼返回給您。否則,它將建立一個新的檔案控制代碼並將其分配給新開啟的檔案。
索引節點
索引節點(inode)是檔案系統元素,它描述其他檔案。基本上,在建立任何檔案或目錄之類的物件之前,必須存在inode。任何具有關聯inode的檔案系統物件都稱為“檔案系統物件”。
我們使用stats()函式顯示特定文字文件的詳細資訊。
user@baeldung:~$ stat filename File: filename Size: 583 Blocks: 8 IO Block: 4096 regular file Device: 810h/2064d Inode: 666 Links: 1 [...]
檔名引用索引節點號666(最後一行)。
誰引用了該檔案?
檔案控制代碼
檔案控制代碼(檔案描述符)只是數字。它們用於為開啟的檔案描述符的索引系統表儲存檔案描述。與檔案系統元素不同,檔案控制代碼不會駐留在檔案系統上或隨檔案系統更新。相反,它們被程序用來跟蹤其開啟的檔案。
我們使用ls(列表)命令和proc檔案系統上的−l(長列表格式)標誌列出此檔案−
user@baeldung:~$ ls -l /proc/1296/fd total 0 lrwx------ 1 user user 64 Jul 1 10:49 0 -> /dev/pts/1 lrwx------ 1 user user 64 Jul 1 10:49 1 -> /dev/pts/1 lrwx------ 1 user user 64 Jul 1 10:49 2 -> /dev/pts/1 lrwx------ 1 user user 64 Jul 1 10:50 3 -> /home/user/filename
輸出表明fd3指向/home/user/filename。在fd3上使用取消引用命令(-L)告訴我們該路徑的inode編號為2。
user@baeldung:~$ stat -L /proc/1296/fd/3 File: /proc/1296/fd/3 Size: 583 Blocks: 8 IO Block: 4096 regular file Device: 810h/2064d Inode: 666 Links: 1 [...]
程序可以使用其名稱(例如,/tmp/foo)引用特定的inode,但是如果inode已被重新命名,則程序將無法訪問它。
陳舊檔案控制代碼
一旦inode不再被引用或連結,它就可供將來使用。
在此階段,相關檔案的開啟控制代碼指向無效的inode編號或與之前的不同。系統幾乎不可能再次重用相同的inode編號。
不成功上傳的結果以不同的方式出現,但一種常見的方式是ESTALE 116,並顯示訊息“陳舊檔案控制代碼”。
user@baeldung:~$ cd /mounted -bash: cd: /mounted: Stale file handle
如果程序沒有成功完成,它可能只是靜默失敗,而不會產生任何輸出或聲稱缺少檔案。
這個問題通常只有一個標準解決方案。
解決陳舊檔案控制代碼
當程序開啟陳舊控制代碼時,它會得到一個新的控制代碼。如果檔案已經有一個inode,則更新其inode將更新其檔案描述。大多數情況下,該過程必須在內部完成。如果不是,我們可能必須重新開始。
使用掛載共享目錄時,此解決方案可能並非易事。
使用NFS或CIFs時,陳舊檔案未重新整理的最常見場景是當它們用於掛載共享資料夾時。協議實現通常缺乏標準化的快取和檔案控制代碼協調。此類場景通常需要重新掛載(可能使用不同的設定)甚至重新啟動伺服器程序。這兩個操作都可能導致某些停機時間。
總結
我們查看了特定軟體用於訪問檔案的引用鏈。我們看到了該鏈如何斷裂。
我們展示瞭如何在發生陳舊檔案控制代碼的不同情況下修復它們。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP