作者:Neil Brown 請查閱 MAINTAINERS 檔案以瞭解向何處傳送問題。
Overlay 檔案系統¶
本文件描述了一種在 Linux 中提供 overlay-filesystem 功能(有時稱為 union-filesystems)的新方法的原型。overlay-filesystem 嘗試呈現一個檔案系統,該檔案系統是將一個檔案系統疊加在另一個檔案系統之上的結果。
Overlay 物件¶
overlay 檔案系統方法是“混合”的,因為出現在檔案系統中的物件並不總是看起來屬於該檔案系統。在許多情況下,在聯合中訪問的物件與從原始檔案系統訪問相應物件沒有區別。從 stat(2) 返回的“st_dev”欄位中可以明顯看出這一點。
雖然目錄將報告來自 overlay-filesystem 的 st_dev,但非目錄物件可能會報告來自提供該物件的較低檔案系統或較高檔案系統的 st_dev。同樣,只有與 st_dev 結合使用時,st_ino 才是唯一的,並且這兩者都可能在非目錄物件的生命週期內發生變化。許多應用程式和工具會忽略這些值,因此不會受到影響。
在所有 overlay 層都在同一底層檔案系統的特殊情況下,所有物件都將報告來自 overlay 檔案系統的 st_dev 以及來自底層檔案系統的 st_ino。這將使 overlay 掛載更符合檔案系統掃描器的要求,並且 overlay 物件可以與原始檔案系統中的相應物件區分開來。
在 64 位系統上,即使所有 overlay 層都不在同一底層檔案系統上,也可以透過“xino”功能實現相同的合規行為。“xino”功能透過真實物件的 st_ino 和底層 fsid 號組成唯一的物件識別符號。“xino”功能使用 inode 號的高位作為 fsid,因為底層檔案系統很少使用 inode 號的高位。如果底層 inode 號溢位到 xino 高位,overlay 檔案系統將回退到該 inode 的非 xino 行為。
可以使用“-o xino=on”overlay 掛載選項啟用“xino”功能。如果所有底層檔案系統都支援 NFS 檔案控制代碼,則 overlay 檔案系統物件的 st_ino 值不僅是唯一的,而且在檔案系統的整個生命週期中都是持久的。“-o xino=auto”overlay 掛載選項僅在滿足永續性 st_ino 要求時才啟用“xino”功能。
下表總結了在不同 overlay 配置中可以預期的情況。
Inode 屬性¶
配置 |
永續性 st_ino |
統一的 st_dev |
st_ino == d_ino |
d_ino == i_ino [*] |
||||
|---|---|---|---|---|---|---|---|---|
目錄 |
!目錄 |
目錄 |
!目錄 |
目錄 |
!目錄 |
目錄 |
!目錄 |
|
所有層在同一檔案系統上 |
是 |
是 |
是 |
是 |
是 |
是 |
是 |
是 |
層不在同一檔案系統上,xino=off |
否 |
否 |
是 |
否 |
否 |
是 |
否 |
是 |
xino=on/auto |
是 |
是 |
是 |
是 |
是 |
是 |
是 |
是 |
xino=on/auto,ino 溢位 |
否 |
否 |
是 |
否 |
否 |
是 |
否 |
是 |
[*] nfsd v3 readdirplus 驗證 d_ino == i_ino。 i_ino 透過多個 /proc 檔案公開,例如 /proc/locks 和 inotify 檔案描述符的 /proc/self/fdinfo/<fd>。
Upper 和 Lower¶
overlay 檔案系統組合了兩個檔案系統 - 一個“upper”檔案系統和一個“lower”檔案系統。當一個名稱同時存在於兩個檔案系統中時,“upper”檔案系統中的物件是可見的,而“lower”檔案系統中的物件要麼被隱藏,要麼(在目錄的情況下)與“upper”物件合併。
更準確的說法是 upper 和 lower “目錄樹”,而不是“檔案系統”,因為兩個目錄樹都可能位於同一檔案系統中,並且 upper 或 lower 都不需要提供檔案系統的根目錄。
Linux 支援的各種檔案系統都可以作為 lower 檔案系統,但並非所有 Linux 可以掛載的檔案系統都具有 OverlayFS 工作所需的特性。lower 檔案系統不需要是可寫的。lower 檔案系統甚至可以是另一個 overlayfs。upper 檔案系統通常是可寫的,如果是可寫的,則必須支援建立 trusted.* 和/或 user.* 擴充套件屬性,並且必須在 readdir 響應中提供有效的 d_type,因此 NFS 不適用。
兩個只讀檔案系統的只讀 overlay 可以使用任何檔案系統型別。
目錄¶
Overlay 主要涉及目錄。如果給定的名稱同時出現在 upper 和 lower 檔案系統中,並且在其中一個檔案中指向非目錄,則 lower 物件將被隱藏 - 該名稱僅指向 upper 物件。
如果 upper 和 lower 物件都是目錄,則會形成一個合併的目錄。
掛載時,作為掛載選項“lowerdir”和“upperdir”給出的兩個目錄將合併到一個合併的目錄中
mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\
workdir=/work /merged
“workdir”需要是與 upperdir 位於同一檔案系統上的空目錄。
然後,每當在這樣一個合併的目錄中請求查詢時,都會在每個實際目錄中執行查詢,並將組合結果快取在屬於 overlay 檔案系統的 dentry 中。如果兩個實際查詢都找到目錄,則會儲存這兩個目錄並建立一個合併的目錄,否則只會儲存一個:如果 upper 存在,則儲存 upper,否則儲存 lower。
僅合併目錄中的名稱列表。其他內容(如元資料和擴充套件屬性)僅報告 upper 目錄的內容。lower 目錄的這些屬性將被隱藏。
whiteout 和 opaque 目錄¶
為了支援 rm 和 rmdir 而無需更改 lower 檔案系統,overlay 檔案系統需要在 upper 檔案系統中記錄已刪除的檔案。這是使用 whiteout 和 opaque 目錄完成的(非目錄始終是不透明的)。
whiteout 建立為裝置號為 0/0 的字元裝置或具有 xattr “trusted.overlay.whiteout” 的零大小的常規檔案。
如果在合併目錄的 upper 層中找到 whiteout,則 lower 層中的任何匹配名稱都將被忽略,並且 whiteout 本身也會被隱藏。
透過將 xattr “trusted.overlay.opaque” 設定為 “y” 來使目錄變得 opaque。如果 upper 檔案系統包含 opaque 目錄,則 lower 檔案系統中任何具有相同名稱的目錄都將被忽略。
opaque 目錄不應包含任何 whiteout,因為它們沒有任何作用。包含具有 xattr “trusted.overlay.whiteout” 的常規檔案的合併目錄還應透過將 xattr “trusted.overlay.opaque” 設定為合併目錄本身的 “x” 來標記。這是為了避免在常見情況下 readdir 期間檢查所有條目的“trusted.overlay.whiteout”的開銷。
readdir¶
當對合並的目錄發出“readdir”請求時,會讀取 upper 和 lower 目錄,並以顯而易見的方式合併名稱列表(首先讀取 upper,然後讀取 lower - 不會重新新增已存在的條目)。此合併的名稱列表快取在“struct file”中,因此只要檔案保持開啟狀態,該列表就會保留。如果目錄被兩個程序同時開啟和讀取,則它們將各自擁有單獨的快取。seekdir 到目錄的開頭(偏移量 0)後跟 readdir 將導致快取被丟棄並重建。
這意味著在讀取目錄時,合併目錄的更改不會顯示。許多程式不太可能注意到這一點。
seek 偏移量在讀取目錄時按順序分配。因此,如果
讀取目錄的一部分
記住一個偏移量並關閉目錄
稍後重新開啟目錄
seek 到記住的偏移量
則檔名列表中的舊位置和新位置之間可能幾乎沒有關聯,特別是如果目錄中的任何內容發生了更改。
對未合併的目錄的 Readdir 僅由底層目錄(upper 或 lower)處理。
重新命名目錄¶
當重新命名位於 lower 層或已合併的目錄(即,該目錄不是一開始就在 upper 層上建立的)時,overlayfs 可以透過兩種不同的方式處理它
返回 EXDEV 錯誤:嘗試跨檔案系統邊界移動檔案或目錄時,rename(2) 會返回此錯誤。因此,應用程式通常會準備好處理此錯誤(例如,mv(1) 會遞迴複製目錄樹)。這是預設行為。
如果啟用了“redirect_dir”功能,則該目錄將被複制到 upper 層(但內容不會)。然後,將“trusted.overlay.redirect”擴充套件屬性設定為從 overlay 根目錄到原始位置的路徑。最後,該目錄被移動到新位置。
有幾種方法可以調整“redirect_dir”功能。
核心配置選項
- OVERLAY_FS_REDIRECT_DIR
如果啟用了此選項,則預設情況下啟用 redirect_dir。
- OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
如果啟用了此選項,則預設情況下始終跟蹤重定向。啟用此選項會導致安全性較低的配置。只有在擔心與具有 redirect_dir 功能的核心向後相容性,並且即使關閉也跟蹤重定向時,才啟用此選項。
模組選項(也可以透過 /sys/module/overlay/parameters/ 更改)
- “redirect_dir=BOOL”
請參閱上面的 OVERLAY_FS_REDIRECT_DIR 核心配置選項。
- “redirect_always_follow=BOOL”
請參閱上面的 OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW 核心配置選項。
- “redirect_max=NUM”
絕對重定向中的最大位元組數(預設為 256)。
掛載選項
- “redirect_dir=on”
啟用重定向。
- “redirect_dir=follow”
不會建立重定向,但會跟蹤重定向。
- “redirect_dir=nofollow”
不會建立重定向,也不會跟蹤重定向。
- “redirect_dir=off”
如果在核心/模組配置中啟用了“redirect_always_follow”,則此“off”轉換為“follow”,否則轉換為“nofollow”。
啟用 NFS 匯出功能後,每個複製到 upper 層的目錄都由 lower inode 的檔案控制代碼索引,upper 目錄的檔案控制代碼儲存在索引條目的 “trusted.overlay.upper” 擴充套件屬性中。在查詢合併的目錄時,如果 upper 目錄與索引中儲存的檔案控制代碼不匹配,則表明多個 upper 目錄可能重定向到同一個 lower 目錄。在這種情況下,查詢返回錯誤並警告可能存在不一致。
由於 lower 層重定向無法透過索引驗證,因此在沒有 upper 層的 overlay 檔案系統上啟用 NFS 匯出支援需要關閉重定向跟蹤(例如,“redirect_dir=nofollow”)。
非目錄¶
不是目錄的物件(檔案、符號連結、裝置特殊檔案等)以適合的方式從 upper 或 lower 檔案系統呈現。當以需要寫訪問許可權的方式訪問 lower 檔案系統中的檔案時,例如開啟以進行寫訪問、更改某些元資料等,該檔案首先從 lower 檔案系統複製到 upper 檔案系統 (copy_up)。請注意,建立硬連結也需要 copy_up,當然,建立符號連結不需要。
copy_up 可能是不必要的,例如,如果檔案以讀寫方式開啟但資料未被修改。
copy_up 過程首先確保包含目錄存在於 upper 檔案系統中 - 根據需要建立它及其任何父目錄。然後,它使用相同的元資料(所有者、模式、mtime、符號連結目標等)建立物件,如果物件是一個檔案,則將資料從 lower 檔案系統複製到 upper 檔案系統。最後,任何擴充套件屬性都會被複制到 upper 層。
copy_up 完成後,overlay 檔案系統只是提供對 upper 檔案系統中新建立的檔案的直接訪問 - overlay 檔案系統幾乎不會注意到對該檔案的未來操作(儘管對檔名稱的操作(例如重新命名或取消連結)當然會被注意到並處理)。
許可權模型¶
overlay 檔案系統會儲存在訪問 lower 或 upper 檔案系統時將使用的憑據。
在舊的掛載 API 中,呼叫 mount(2) 的任務的憑據會被儲存。在新的掛載 API 中,透過 fsconfig(2) 的 FSCONFIG_CMD_CREATE 命令建立超級塊的任務的憑據會被儲存。
從核心 v6.15 開始,可以使用 “override_creds” 掛載選項,該選項將導致記錄呼叫任務的憑據。請注意,“override_creds” 僅在使用新的掛載 API 時才有意義,因為舊的掛載 API 將設定選項和超級塊建立合併到單個 mount(2) 系統呼叫中。
overlay 檔案系統中的許可權檢查遵循以下原則
許可權檢查在 copy up 前後應返回相同的結果
建立 overlay 掛載的任務不得獲得額外的許可權
與直接訪問底層 lower 或 upper 檔案系統相比,任務[*] 可能透過 overlay 獲得額外的許可權
這是透過對每次訪問執行兩次許可權檢查來實現的
檢查當前任務是否基於本地 DAC(所有者、組、模式和 posix acl)以及 MAC 檢查被允許訪問
檢查儲存的憑據是否允許基於底層檔案系統許可權對 lower 或 upper 層執行實際操作,再次包括 MAC 檢查
檢查 (a) 確保一致性 (1),因為所有者、組、模式和 posix acl 都會被複制到 upper 層。另一方面,這可能會導致伺服器強制執行的許可權(例如,NFS 使用的許可權)被忽略 (3)。
檢查 (b) 確保沒有任務獲得儲存的憑據不具有的底層層的許可權 (2)。這也意味著可以建立不滿足一致性規則 (1) 的設定;但是,通常,儲存的憑據將具有執行所有操作的足夠許可權。
演示此模型的另一種方法是在以下兩者之間建立聯絡
mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,... /merged
和
cp -a /lower /upper
mount --bind /upper /merged
生成的訪問許可權應相同。區別在於複製的時間(按需 vs. 預先)。
多個 lower 層¶
現在可以使用冒號 (“:”) 作為目錄名稱之間的分隔符來給出多個 lower 層。例如
mount -t overlay overlay -olowerdir=/lower1:/lower2:/lower3 /merged
如示例所示,可以省略 “upperdir=” 和 “workdir=”。在這種情況下,overlay 將是隻讀的。
指定的 lower 目錄將從最右邊的目錄開始,從左到右堆疊。在上面的示例中,lower1 將位於頂部,lower2 位於中間,lower3 位於底層。
注意:包含冒號的目錄名稱可以透過使用單個反斜槓轉義冒號來作為 lower 層提供。例如
mount -t overlay overlay -olowerdir=/a\:lower\:\:dir /merged
從核心版本 v6.8 開始,也可以使用新的掛載 API 中的 “lowerdir+” 掛載選項和 fsconfig 系統呼叫將包含冒號的目錄名稱配置為 lower 層。例如
fsconfig(fs_fd, FSCONFIG_SET_STRING, "lowerdir+", "/a:lower::dir", 0);
在後一種情況下,lower 層目錄名稱中的冒號將在 /proc/self/mountinfo 中顯示時轉義為八進位制字元 (072)。
僅元資料複製 up¶
啟用“metacopy”功能後,當執行像 chown/chmod 這樣的特定於元資料的操作時,overlayfs 將僅複製 up 元資料(而不是整個檔案)。處於此狀態的 upper 檔案標有 “trusted.overlayfs.metacopy” xattr,表明 upper 檔案不包含資料。當檔案開啟以進行 WRITE 操作時,資料將在稍後複製 up。在複製 up lower 檔案的資料後,將從 upper 檔案中刪除 “trusted.overlayfs.metacopy” xattr。
換句話說,這是延遲的資料複製 up 操作,並且僅在需要實際修改資料時才複製 up 資料。
有多種方法可以啟用/停用此功能。可以設定/取消設定配置選項 CONFIG_OVERLAY_FS_METACOPY,以預設啟用/停用此功能。或者,可以使用模組引數 metacopy=on/off 在模組載入時啟用/停用它。最後,還有一個每個掛載選項 metacopy=on/off 來啟用/停用每個掛載的此功能。
不要將 metacopy=on 與不受信任的 upper/lower 目錄一起使用。否則,攻擊者可能會建立一個帶有適當的 REDIRECT 和 METACOPY xattrs 的手工製作的檔案,並獲得對 REDIRECT 指向的 lower 上的檔案的訪問許可權。這在本地系統上是不可能的,因為設定 “trusted.” xattrs 需要 CAP_SYS_ADMIN。但是,這對於來自筆式驅動器等不受信任的層應該是可能的。
注意:redirect_dir={off|nofollow|follow[*]} 和 nfs_export=on 掛載選項與 metacopy=on 衝突,並將導致錯誤。
[*] 只有在給定 upperdir=... 的情況下,redirect_dir=follow 才與 metacopy=on 衝突。
僅資料 lower 層¶
啟用 “metacopy” 功能後,overlayfs 常規檔案可以是來自最多三個不同層的資訊的組合
來自 upper 層中的檔案的元資料
來自 lower 層中的檔案的 st_ino 和 st_dev 物件識別符號
來自另一個 lower 層(更下方)中的檔案的資料
“lower 資料”檔案可以位於任何 lower 層上,但不能位於最頂層的 lower 層上。
在最頂層的 lower 層下方,可以使用雙冒號 (“::”) 分隔符將任意數量的最底層的 lower 層定義為 “僅資料” lower 層。不允許普通 lower 層位於僅資料層下方,因此不允許在雙冒號 (“::”) 分隔符的右側使用單冒號分隔符。
例如
mount -t overlay overlay -olowerdir=/l1:/l2:/l3::/do1::/do2 /merged
“僅資料” lower 層中的檔案路徑在合併的 overlayfs 目錄中不可見,並且 “僅資料” lower 層中的檔案的元資料和 st_ino/st_dev 在 overlayfs inode 中不可見。
僅當上面的 lower 層中的 “metacopy” 檔案 “重定向” 到 “僅資料” lower 層中 “lower 資料” 檔案的絕對路徑時,“僅資料” lower 層中的檔案資料才可能可見。
無需顯式啟用 “metacopy=on”,指定至少一個僅資料層足以啟用將資料重定向到僅資料層。在這種情況下,其他形式的 metacopy 將被拒絕。注意:可以透過 “userxattr” 將此方式與僅資料層一起使用,在這種情況下,必須密切注意更改 “user.overlay.redirect” xattr 所需的許可權,以防止濫用。
從核心版本 v6.8 開始,也可以使用新的掛載 API 中的 “datadir+” 掛載選項和 fsconfig 系統呼叫新增 “僅資料” lower 層。例如
fsconfig(fs_fd, FSCONFIG_SET_STRING, "lowerdir+", "/l1", 0);
fsconfig(fs_fd, FSCONFIG_SET_STRING, "lowerdir+", "/l2", 0);
fsconfig(fs_fd, FSCONFIG_SET_STRING, "lowerdir+", "/l3", 0);
fsconfig(fs_fd, FSCONFIG_SET_STRING, "datadir+", "/do1", 0);
fsconfig(fs_fd, FSCONFIG_SET_STRING, "datadir+", "/do2", 0);
透過檔案描述符指定層¶
從核心 v6.13 開始,overlayfs 支援透過檔案描述符(而不是將它們指定為路徑)來指定層。此功能可用於新的掛載 API 中帶有 fsconfig 系統呼叫的 “datadir+”、“lowerdir+”、“upperdir” 和 “workdir+” 掛載選項
fsconfig(fs_fd, FSCONFIG_SET_FD, "lowerdir+", NULL, fd_lower1);
fsconfig(fs_fd, FSCONFIG_SET_FD, "lowerdir+", NULL, fd_lower2);
fsconfig(fs_fd, FSCONFIG_SET_FD, "lowerdir+", NULL, fd_lower3);
fsconfig(fs_fd, FSCONFIG_SET_FD, "datadir+", NULL, fd_data1);
fsconfig(fs_fd, FSCONFIG_SET_FD, "datadir+", NULL, fd_data2);
fsconfig(fs_fd, FSCONFIG_SET_FD, "workdir", NULL, fd_work);
fsconfig(fs_fd, FSCONFIG_SET_FD, "upperdir", NULL, fd_upper);
fs-verity 支援¶
在 lower 檔案的元資料複製 up 期間,如果原始檔啟用了 fs-verity 並且啟用了 overlay verity 支援,則 lower 檔案的摘要將新增到 “trusted.overlay.metacopy” xattr。然後,這用於每次開啟 metacopy 檔案時驗證 lower 檔案的內容。
當使用包含 verity xattrs 的層時,這意味著 upper 層中的任何此類 metacopy 檔案都保證與複製 up 時 lower 中的內容匹配。如果在任何時候(在掛載期間、重新掛載之後等)以任何方式替換或修改 lower 中的此類檔案,則對 overlayfs 中相應檔案的訪問將導致 EIO 錯誤(由於 overlayfs 摘要檢查,在開啟時,或由於 fs-verity,在稍後的讀取中),並且詳細的錯誤會列印到核心日誌中。有關 fs-verity 檔案訪問如何工作的更多詳細資訊,請參閱 Documentation/filesystems/fsverity.rst。
Verity 可用作檢測正在使用的 overlayfs 目錄中意外更改的一般穩健性檢查。但是,透過額外的注意,它也可以提供更強大的保證。例如,如果 upper 層是完全受信任的(透過使用 dm-verity 或類似的東西),則不受信任的 lower 層可用於為所有 metacopy 檔案提供經過驗證的檔案內容。如果此外,不受信任的 lower 目錄被指定為 “僅資料”,則它們只能提供此類檔案內容,並且可以信任整個掛載與 upper 層匹配。
此功能由 “verity” 掛載選項控制,該選項支援以下值
- “off”
永遠不會生成或使用 metacopy 摘要。如果未指定 verity 選項,則這是預設值。
- “on”
每當 metacopy 檔案指定預期的摘要時,相應的資料檔案必須與指定的摘要匹配。生成 metacopy 檔案時,verity 摘要將基於原始檔(如果它有摘要)設定在其中。
- “require”
與 “on” 相同,但此外,所有 metacopy 檔案必須指定摘要(否則在開啟時返回 EIO)。這意味著僅當資料檔案啟用了 fs-verity 時才使用元資料複製 up,否則使用完整的複製 up。
巢狀 overlayfs 掛載¶
可以使用儲存在 overlayfs 掛載上的 lower 目錄。對於常規檔案,這不需要任何特殊的注意。但是,具有 overlayfs 屬性的檔案(例如 whiteout 或 “overlay.*” xattrs)將被底層 overlayfs 掛載解釋並剝離。為了允許第二個 overlayfs 掛載檢視屬性,必須轉義它們。
Overlayfs 特定 xattrs 透過使用特殊的 “overlay.overlay.” 字首來轉義。因此,lower 目錄中帶有 “trusted.overlay.overlay.metacopy” xattr 的檔案將在 overlayfs 掛載中公開為帶有 “trusted.overlay.metacopy” xattr 的常規檔案。這可以透過多次重複字首來巢狀,因為每個例項只刪除一個字首。
常規 whiteout 的 lower 目錄將始終由 overlayfs 掛載處理,因此為了支援在 overlayfs 掛載中儲存有效的 whiteout 檔案,支援另一種形式的 whiteout。此形式是一個常規的、零大小的檔案,其中 “overlay.whiteout” xattr 設定為 “overlay.opaque” xattr 設定為 “x” 的目錄中(請參閱 whiteout 和 opaque 目錄)。這些備用 whiteout 永遠不會由 overlayfs 建立,但可以由生成 lower 層的使用者空間工具(如容器)使用。可以使用標準 xattr 轉義機制來轉義這些備用 whiteout,以便正確地巢狀到任何深度。
非標準行為¶
當前版本的 overlayfs 可以充當大部分符合 POSIX 標準的檔案系統。
以下是 overlayfs 當前無法處理的情況列表
POSIX 規定更新讀取的 st_atime。如果檔案位於 lower 層上,則當前未完成此操作。
如果位於 lower 層上的檔案以只讀方式開啟,然後使用 MAP_SHARED 進行記憶體對映,則對該檔案的後續更改不會反映在記憶體對映中。
如果位於 lower 層上的檔案正在執行,則開啟該檔案進行寫入或截斷該檔案將不會因 ETXTBSY 而被拒絕。
以下選項允許 overlayfs 更像標準相容的檔案系統
redirect_dir¶
使用掛載選項或模組選項啟用:“redirect_dir=on” 或使用核心配置選項 CONFIG_OVERLAY_FS_REDIRECT_DIR=y。
如果停用此功能,則對 lower 或合併目錄的 rename(2) 將因 EXDEV (“無效的跨裝置連結”) 而失敗。
index¶
透過掛載選項或模組選項“index=on”或核心配置選項 CONFIG_OVERLAY_FS_INDEX=y 啟用。
如果停用此功能,並且複製一個具有多個硬連結的檔案,則將“破壞”該連結。更改不會傳播到引用同一 inode 的其他名稱。
xino¶
透過掛載選項“xino=auto”或“xino=on”,模組選項“xino_auto=on”或核心配置選項 CONFIG_OVERLAY_FS_XINO_AUTO=y 啟用。透過對組成 overlay 的所有層使用相同的底層檔案系統也可以隱式啟用此選項。
如果停用此功能或底層檔案系統的 inode 號中沒有足夠的空閒位,則 overlayfs 將無法保證 stat(2) 返回的 st_ino 和 st_dev 的值以及 readdir(3) 返回的 d_ino 的值像在普通檔案系統上一樣。 例如,對於同一 overlay 檔案系統中的兩個物件,st_dev 的值可能不同,並且檔案系統物件的 st_ino 值可能不是持久的,甚至可能在 overlay 檔案系統掛載時發生更改,如上面的 Inode 屬性 表中所總結的那樣。
底層檔案系統的更改¶
不允許在掛載的 overlay 檔案系統的一部分時更改底層檔案系統。如果底層檔案系統發生更改,則 overlay 的行為是未定義的,但不會導致崩潰或死鎖。
允許對上層樹進行離線更改(overlay 未掛載時)。只有在未使用“metacopy”、“index”、“xino”和“redirect_dir”功能的情況下,才允許對下層樹進行離線更改。如果修改了下層樹,並且使用了這些功能中的任何一個,則 overlay 的行為是未定義的,但不會導致崩潰或死鎖。
啟用 overlay NFS 匯出功能後,overlay 檔案系統在底層下層的離線更改上的行為與停用 NFS 匯出時的行為不同。
在每次 copy_up 操作時,下層 inode 的 NFS 檔案控制代碼以及下層檔案系統的 UUID 會被編碼並存儲在上層 inode 的擴充套件屬性“trusted.overlay.origin”中。
啟用 NFS 匯出功能後,查詢合併的目錄(該目錄在查詢路徑或“trusted.overlay.redirect”擴充套件屬性指向的路徑處找到一個下層目錄)將驗證找到的下層目錄檔案控制代碼和下層檔案系統 UUID 是否與 copy_up 時儲存的原始檔案控制代碼匹配。 如果找到的下層目錄與儲存的原始檔案控制代碼不匹配,則該目錄不會與上層目錄合併。
NFS 匯出¶
當底層檔案系統支援 NFS 匯出且啟用了“nfs_export”功能時,可以將 overlay 檔案系統匯出到 NFS。
使用“nfs_export”功能,在 copy_up 任何下層物件時,會在索引目錄下建立一個索引條目。索引條目的名稱是 copy_up 原始檔案控制代碼的十六進位制表示。對於非目錄物件,索引條目是上層 inode 的硬連結。對於目錄物件,索引條目具有一個擴充套件屬性“trusted.overlay.upper”,其中包含上層目錄 inode 的編碼檔案控制代碼。
在編碼來自 overlay 檔案系統物件的檔案控制代碼時,適用以下規則
對於非上層物件,編碼來自下層 inode 的下層檔案控制代碼
對於索引物件,編碼來自 copy_up 原始物件的一個下層檔案控制代碼
對於純上層物件和現有的非索引上層物件,編碼來自上層 inode 的上層檔案控制代碼
編碼的 overlay 檔案控制代碼包括
包括路徑型別資訊(例如,下層/上層)的標頭
底層檔案系統的 UUID
底層 inode 的底層檔案系統編碼
此編碼格式與儲存在擴充套件屬性“trusted.overlay.origin”中的檔案控制代碼的編碼格式相同。
解碼 overlay 檔案控制代碼時,請按照以下步驟操作
按 UUID 和路徑型別資訊查詢底層圖層。
將底層檔案系統檔案控制代碼解碼為底層 dentry。
對於下層檔案控制代碼,按名稱在索引目錄中查詢控制代碼。
如果在索引中找到一個 whiteout,則返回 ESTALE。 這表示在對其檔案控制代碼進行編碼後被刪除的 overlay 物件。
對於非目錄,從解碼的底層 dentry、路徑型別和索引 inode(如果找到)例項化一個斷開連線的 overlay dentry。
對於目錄,使用連線的底層解碼的 dentry、路徑型別和索引來查詢連線的 overlay dentry。
解碼非目錄檔案控制代碼可能會返回斷開連線的 dentry。 copy_up 該斷開連線的 dentry 將建立一個沒有上層別名的上層索引條目。
當 overlay 檔案系統具有多個下層時,中間層目錄可能具有指向較低目錄的“重定向”。 由於中間層“重定向”未建立索引,因此無法使用從“重定向”原始目錄編碼的較低檔案控制代碼來查詢中間層或上層目錄。 同樣,無法使用從“重定向”原始目錄的後代編碼的較低檔案控制代碼來重建連線的 overlay 路徑。 為了減輕無法從較低檔案控制代碼解碼目錄的情況,這些目錄會在編碼時複製到上層,並編碼為上層檔案控制代碼。 在沒有上層的 overlay 檔案系統上,無法使用此緩解措施,並且此設定中的 NFS 匯出需要關閉重定向跟隨(例如,“redirect_dir=nofollow”)。
overlay 檔案系統不支援非目錄的可連線檔案控制代碼,因此使用“subtree_check”exportfs 配置匯出將導致透過 NFS 查詢檔案失敗。
啟用 NFS 匯出功能後,所有目錄索引條目都會在掛載時進行驗證,以檢查上層檔案控制代碼是否已過時。在某些情況下,此驗證可能會導致很大的開銷。
注意:對於讀寫掛載,掛載選項 index=off,nfs_export=on 是衝突的,並且會導致錯誤。
注意:可以使用掛載選項 uuid=off 將檔案控制代碼中底層檔案系統的 UUID 替換為 null,並有效地停用 UUID 檢查。 如果複製了底層磁碟並且此副本的 UUID 發生更改,這將非常有用。 這僅適用於所有下層/上層/工作目錄都在同一檔案系統上的情況,否則它將回退到正常行為。
UUID 和 fsid¶
overlayfs 例項本身的 UUID 和 statfs(2) 報告的 fsid 由“uuid”掛載選項控制,該選項支援以下值
- “null”
overlayfs 的 UUID 為空。 fsid 取自最上層檔案系統。
- “off”
overlayfs 的 UUID 為空。 fsid 取自最上層檔案系統。底層圖層的 UUID 將被忽略。
- “on”
生成 overlayfs 的 UUID 並用於報告唯一的 fsid。 UUID 儲存在 xattr “trusted.overlay.uuid”中,使 overlayfs fsid 唯一且持久。此選項需要具有支援 xattr 的上層檔案系統的 overlayfs。
- “auto”:(預設)
如果存在,則從 xattr “trusted.overlay.uuid”中獲取 UUID。 首次掛載滿足先決條件的新 overlay 檔案系統時升級到 “uuid=on”。 對於從未與 “uuid=on” 掛載的現有 overlay 檔案系統,降級到 “uuid=null”。
易失性掛載¶
這透過 “volatile” 掛載選項啟用。 無法保證易失性掛載在崩潰後能倖存。 強烈建議僅當寫入 overlay 的資料無需付出大量努力即可重新建立時才使用易失性掛載。
使用 “volatile” 選項掛載的優點是省略了對上層檔案系統的所有形式的 sync 呼叫。
為了避免產生虛假的安全感,易失性掛載的 syncfs(和 fsync)語義與 VFS 的其餘部分略有不同。 如果在上層目錄的檔案系統上發生任何寫回錯誤(在發生易失性掛載之後),所有 sync 函式都將返回錯誤。 一旦達到此狀態,檔案系統將不會恢復,並且每個後續的 sync 呼叫都將返回錯誤,即使上層目錄自上次 sync 呼叫以來沒有遇到新的錯誤。
當 overlay 使用 “volatile” 選項掛載時,會建立目錄 “$workdir/work/incompat/volatile”。 在下次掛載期間,overlay 會檢查此目錄,如果存在則拒絕掛載。 這強烈表明使用者應丟棄上層和工作目錄並建立一個新的。 在使用者知道系統沒有崩潰並且上層目錄的內容完好無損的非常有限的情況下,可以刪除 “volatile” 目錄。
使用者 xattr¶
“-o userxattr” 掛載選項強制 overlayfs 使用 “user.overlay.” xattr 名稱空間,而不是 “trusted.overlay.”。 這對於非特權掛載 overlayfs 非常有用。
測試套件¶
David Howells 最初開發並由 Amir Goldstein 當前維護的測試套件位於
https://github.com/amir73il/unionmount-testsuite.git
以 root 身份執行
# cd unionmount-testsuite
# ./run --ov --verify