
我有一些儲存的 ZFS「發送流」(即,它們是透過將輸出重定向zfs send
到檔案而創建的)。我想檢查這些流的內容,而不接收它們並將其寫入文件系統 - 例如,我想查看流內的文件名列表。有什麼辦法可以做到這一點嗎?
我已經閱讀和搜尋了一些內容,但沒有找到任何與我所說的類似的內容。我正在使用自由BSD和Linux 上的 ZFSZFS 的實作。
答案1
您可以透過將它們傳遞到 中來獲取一些信息zstreamdump -d
,但這不會直接提供有關文件名的任何信息,因為流中沒有文件。流是塊中描述的兩棵樹之間的純粹區別。然而,程式碼是公開的,因此如果您設法添加 ZFS 結構檢測和解析,您可以從中獲得更多資訊。
ZFS內部結構是內部有一棵樹,所有操作都在該樹上完成。檔案、目錄、檔案名稱、屬性和其他所有內容都只是該樹中的資料。快照、磁碟區和 FS 是樹根,當您拍攝另一個快照時,您只會將目前根儲存在某處。即時系統為每筆交易產生新的根,不斷遠離舊的根,同時保持前一棵樹的大量資料「葉子」完好無損。此流表示應在樹 A 上執行以變為 B 的操作清單。
我只是想說,您可能看不到您在流中查找的數據,因為它們不需要在那裡。當檔案被刪除時,對應的區塊會被釋放,因此您無法分辨檔案名稱或內容是什麼。當檔案變更時,它會由物件 id 引用,因此即使檔案從頭開始重寫但目錄條目尚未更新,您也不會從串流中取得任何內容。
如果該流不是差分流或您有一些超過其先前狀態的數據,那麼您會很幸運。但這只是因為完整的流將空根轉換為目標樹,從而包含所有所需的資料。因此,您可以新增區塊解析程式碼來zstreamdump
偵測和處理 ZFS 內部資料。
答案2
簡短回答:
我不認為有任何方法可以有效地對發送流的內容進行編目,這種方式比透過管道將其傳輸到 zfs receive 以將其重新建立為資料集更輕。
更長的答案:
發送流是儲存區塊級資料集合,不是文件系統層級的資料集合。發送流不知道也不關心單一文件;它旨在複製本質上是原始區塊設備的內容。雖然一個使用者可能專門用於zfs send
複製直接儲存在其上的檔案的ZFS 資料集,但另一個使用者可能會使用它來複製使用ext4、ntfs 甚至像LUKS 這樣的加密系統格式化的ZVOL - 在這些情況下,ZFS 絕對不知道該資料集是什麼。
zfs send
無論您是複製資料集還是原始 zvol,其工作原理都完全相同,因為它根本不關心原始區塊儲存層級以下的任何內容。它不知道檔案名稱、檔案大小、路徑或其他任何內容 - 它知道哪些區塊屬於 zvol 或快照的給定快照,但它確實不是知道這些區塊中的任何一個是如何相互關聯的。
因此,沒有輕量級的方法來對流的文件內容進行編目zfs send
,因為是沒有一個檔案的內部目錄。即使您最終知道這個特定的流恰好是未加密的 ZFS 資料集的完整(非增量)複製,您也必須逐行解析它的每個區塊,以嘗試找出其中的哪些區塊包含檔案名稱。
本質上,為了從發送流中提取文件名,您需要執行zfs receive
與首先將該流應用於資料集所做的所有相同工作。