いくつかのZFS「送信ストリーム」が保存されています(つまり、zfs send
の出力をファイルにリダイレクトすることによって作成されました)。これらのストリームを受信してファイルシステムに書き込むことなく、これらのストリームの内容を調べたいと思います。たとえば、ストリーム内のファイル名のリストを表示したいと思います。これを行う方法はありますか?
私はいくつかの読書と検索をしましたが、私が話しているもののように見えるものは何も見つかりませんでした。 FreeBSDとLinux上のZFSの両方のZFS実装を使用しています。
zstreamdump -d
にパイプすることでいくつかの情報を取得できますが、ストリームにファイルがないため、ファイル名に関する情報は直接提供されません。ストリームは、ブロックで記述された2つのツリー間のまったくの違いです。ただし、コードは公開されているため、ZFS構造の検出と解析を追加できれば、コードからさらに多くのものを得ることができます。
ZFS内部構造is内部的にツリーであり、すべての操作はそのツリーに対して実行されます。ファイル、ディレクトリ、ファイル名、属性、その他すべては、そのツリー内の単なるデータです。スナップショット、ボリューム、およびFSはツリーのルートであり、別のスナップショットを作成すると、現在のルートがどこかに保存されます。ライブシステムは、トランザクションごとに新しいルートを生成し、常に古いルートから離れていきます。 、前のツリーからの多くのデータ「リーブ」をそのまま維持します。ストリームは、ツリーAで実行してBになる必要がある操作のリストを表します。
ストリームに必要なデータがないため、探しているデータがストリームに表示されない可能性があることを伝えようとしています。ファイルがドロップされると、対応するブロックが解放されるだけなので、ファイル名や内容がわかりません。ファイルが変更されると、オブジェクトIDによって参照されるため、ファイルが最初から書き直されてもディレクトリエントリが更新されていなくても、ストリームから何も取得されません。
ストリームが差分ストリームでない場合、または以前の状態を超えるデータがある場合は、幸運です。ただし、これは、フルストリームが空のルートをターゲットツリーに変換し、必要なすべてのデータが含まれるためです。したがって、ブロック解析コードをzstreamdump
に追加して、ZFS内部データを検出および処理できます。
短い答え:
データセットとして再作成するためにzfsreceiveにパイプするよりも軽い送信ストリームのコンテンツを便利にカタログ化する方法はないと思います。
はるかに長い答え:
送信ストリームは、ストレージブロックレベルのデータコレクションであり、ファイルシステムレベルのデータコレクションではありません。送信ストリームは、個々のファイルを認識または認識しません。これは、本質的にrawブロックデバイスであるものを複製するように設計されています。 1人のユーザーがzfs send
を排他的に使用して、ファイルが直接保存されているZFSデータセットを複製する場合もあれば、別のユーザーがそれを使用して、ext4、ntfs、またはLUKSなどの暗号化システムでフォーマットされたZVOLを複製する場合もあります。ボリュームの内容が何であるかを知らず、単にそれらのrawブロックを格納します。
zfs send
は、データセットを複製する場合でも、生のzvolを複製する場合でも、まったく同じように機能します。これは、生のブロックストレージレベルより下の値はまったく気にしないためです。ファイル名、ファイルサイズ、パスなどはわかりません。zvolまたはスナップショットの特定のスナップショットに属するブロックはわかりますが、notこれらのブロックのいずれかが互いにどのように関連しているかを知っています。
したがって、zfs send
ストリームのファイルコンテンツをカタログ化する軽量の方法はありません。これは、ファイルの内部カタログが1つにisないためです。この特定のストリームが暗号化されていないZFSデータセットの完全な(増分ではない)レプリケーションであることが最終的にわかっている場合でも、ファイル名が含まれているブロックを特定するために、そのすべてのブロックを1行ずつ解析する必要があります。
基本的に、送信ストリームからファイル名を抽出するには、最初にそのストリームをデータセットに適用することで、zfs receive
が行っているのと同じ作業をすべて行うことになります。