btrfs 受信が増分ストリームで失敗する:「ファイルが存在します」

btrfs 受信が増分ストリームで失敗する:「ファイルが存在します」

btrfs サブボリュームの場合、2 つの段階から作成された単純な増分バックアップがあります。

btrfs send old/@ > base.btrfs
btrfs send new/@ -p old/@ > update.btrfs

2 つのソース サブボリュームは、同じアクティブにマウントされたサブボリュームから別々の時間にキャプチャされたスナップショットです。

ターゲット上で、次の復元を試みます:

btrfs receive ./ < base.btrfs
btrfs receive ./ < update.btrfs

前のコマンドによって初期バックアップ ステージの復元されたスナップショットが作成され、後者のコマンドによってさらに増分ステージが適用されることが期待されます。

前のコマンドは成功しますが、後者のコマンドは失敗します。

ERROR: creating snapshot ./@ -> @ failed: File exists

存在しないターゲットに後者の段階を適用しても役に立たないことは明らかなので、プロセスがこのチェックを実行する理由と、更新の適用を成功させるために何が期待されるのかについて疑問に思っています。

初期ステージを復元して生成されたターゲットに更新ステージを適用するにはどうすればよいですか?

答え1

送信側と同様に、同じ名前のサブボリュームを複数持つことはできません。

mvターゲット システムでベース スナップショット/サブボリュームを作成できます。

mv @ @.old
btrfs receive ./ < update.btrfs

答え2

質問を投稿してから、私はその質問に答えられるくらい十分に学びました。

答えは2つの部分に分かれます。

まず、receiveサブコマンドは、新しいサブボリュームが子ストリームから作成されたか親ストリームから作成されたかに関係なく、常に元のサブボリュームと同じ名前を持つ新しいエントリをターゲット ディレクトリに作成します。したがって、ターゲット ディレクトリは空でなければならず、少なくとも元のサブボリュームと同じ名前を持つ必要があります。単純な手法としては、親サブボリュームとすべての子サブボリュームごとに新しい空のディレクトリを作成することです。

2 番目に、子に対するサブコマンドの呼び出しでは親への参照は提供されませんが、親が同じパーティションのサブボリュームに復元されている限り、親から必要なデータを利用できます。つまり、receiveサブコマンドは、以前に親の同じパーティションで呼び出されている限り、子ストリームに対して目的の効果をもたらします。

親と子が復元されると、子に害を与えることなく親を削除できます。

したがって、元の目的を達成するための効果的なコマンド シーケンスは次のようになります。

mkdir _tmp
btrfs receive _tmp/ < base.btrfs
btrfs receive ./ < update.btrfs
btrfs subvolume delete _tmp/@
rmdir _tmp

子ストリームのコンテンツ全体が を通じて利用できるようになります./@

base.btrfs当然、保存対象の子ストリームに複数の祖先がある場合 (たとえば、独自の親がある場合)は、さらにコマンドが必要になります。

関連情報