正如 chattr 手冊中提到的,Linux 中的「專案 ID」是什麼?

正如 chattr 手冊中提到的,Linux 中的「專案 ID」是什麼?

chattr當我在我的 Linux 機器 ( ) 上閱讀手冊kali4-amd64時,我在檔案屬性定義清單中看到了這一點:

A directory with the 'P' attribute set will enforce a hierarchical
structure for project id's.  This means that files and directory created in
the directory will inherit the project id of the directory, rename
operations are constrained so when a file or directory is moved into
another directory, that the project id's much match.  In addition, a hard
link to file can only be created when the project id for the file and the
destination directory match.

我個人不知道 Linux/UNIX 中的「專案 id」是什麼,而且很多谷歌搜尋也沒有結果,所以我希望這裡有人可以幫助我。

答案1

您所問的是專案配額概念的一部分。專案配額是一種管理方式磁碟配額。特定的檔案系統類型可能支援也可能不支援項目 ID。讓我們專注於 ext4 並從以下開始man 8 tune2fs

-O [^]feature[,...]
設定或清除檔案系統中指示的檔案系統功能(選項)。 […]

[…]

project
啟用項目 ID 追蹤。這用於專案配額追蹤。

quota 啟用內部檔案系統配額 inode。

[…]

-Q quota-options
在超級區塊上設定「配額」功能並處理給定配額類型的配額檔案。配額選項可以是以下一項或多項:

[^]usrquota
設定/清除超級區塊中的使用者配額 inode。

[^]grpquota
設定/清除超級區塊中的群組配額 inode。

[^]prjquota 設定/清除超級區塊中的項目配額 inode。

您可以在現有檔案系統上啟用這些選項:

tune2fs -O project,quota /your/device

mke2fs(或在建立新檔案系統時提供它們)。然後啟用專案配額(如果您願意,可以使用使用者配額和/或群組配額):

tune2fs -Q prjquota /your/device

安裝它:

mount /your/device /the/mountpoint

現在,您可以使用setquota和等工具來管理配額quota(請注意,舊版本的工具可能缺少-P處理項目配額的選項)。傳統上,您會限制使用者或群組可以使用的磁碟空間量。透過專案配額,您可以對「專案」執行此操作,無論參與的使用者和群組為何。

它的工作原理是這樣的。首先將自己置於掛載點並建立幾個目錄:

cd /the/mountpoint
mkdir foo bar baz

在它們上啟用項目層次結構:

chattr +P foo bar baz

將它們分配給兩個不同的項目:

chattr -p 123 foo       # 123 is an arbitrary number, project id
chattr -p 5 bar baz     # so is 5, the point is they are different

在以下位置建立文件:

echo "lorem ipsum" > foo/file1
echo "lorem ipsum" > bar/file2
echo "lorem ipsum" > baz/file3

現在呼叫:

lsattr -pR .

你會看到(除其他外)這樣的行:

  123 --------------e---P ./foo/file1
    5 --------------e---P ./bar/file2
    5 --------------e---P ./baz/file3

表示file1屬於 id 的項目123file2並且file3屬於 id 的項目5。如果您為這些項目定義配額(即限制項目可以使用的磁碟空間量),則每個檔案都會影響其各自項目的配額消耗。

現在你引用的內容很有意義:

在該目錄下建立的檔案和目錄都會繼承該目錄的項目id

在我們的範例中,file1繼承了項目 id foo。如果您建立更多檔案/目錄,foo它們也會繼承該 id。這允許您(和其他使用者)在其指定目錄中處理該項目,而您建立的檔案會自動計入相應的配額。

僅當檔案的項目 ID 與目標目錄相符時才能建立檔案的硬連結。

ln ./baz/file3 ./foo/會失敗(嘗試)但ln ./baz/file3 ./bar/會成功。作業系統不會讓您輕鬆地將屬於一個專案的檔案(並且必須保持這樣,因為來源路徑未取消連結)「嵌入」到不同的專案目錄中。允許在其項目內連結文件。

當檔案或目錄移動到另一個目錄時,項目 ID 必須匹配

我認為這是相當誤導的。mv即使 id 不匹配也會完成它的工作。關鍵是如果你調用

mv baz/file3 foo/

該工具將首先嘗試將rename(2)檔案移至新路徑,這將會失敗(就像ln上面一樣)。通常或在同一專案內,它會成功,原始名稱會消失。顯然,這種行為就是「項目 ID 必須匹配」的意思。

mv還不會退出。這就像在檔案系統之間移動:mv重新命名失敗後,它會退回到複製+刪除模式。實際上它創建了一個複製(使用新的索引節點號)在目標目錄中。在我們的例子中,副本繼承了項目 ID foo(就像此目錄中的任何新檔案一樣),因此它會影響專案的配額消耗123。然後取消連結原始路徑。這可能會影響專案的配額消耗5;或可能不會:硬連結或開啟檔案描述符將導致原始 inode 和資料保留。

請注意,這有點令人驚訝:創建了一個新文件,舊的硬連結(如果有)沒有連結到新文件,指向舊文件的文件描述符與新文件無關;就像在檔案系統之間執行移動操作一樣。

有一種方法可以重mv命名而不是複製+刪除。如果您手動將原始文件指派給目標項目

chattr -p 123 baz/file3

然後mv baz/file3 foo/將真正移動它而無需複製,也不會破壞硬連結(如果有)。但請注意,項目編號屬於索引節點(不是路徑,不是名稱,不是目錄條目),因此chattr -p會影響所有硬連結。

因此,如果您需要將一個大檔案(即某個索引節點後面的數據,而不僅僅是許多硬連結之一)移動到另一個項目,更改項目然後移動將節省您不必要的複製。

相關內容