web-dev-qa-db-ja.com

btrfsファイルシステムをコピーする方法

Btrfsファイルシステムの内容のフルコピーを作成するにはどうすればよいですか? 完全コピーとは、現在のデータだけでなく、異なるsubvolumessnapshotsを使用して、理想的にはCoW構造を維持します(つまり、同じ内容のブロックを複製しない) 。

ブロックレベルのコピー(ddなど)は、UUIDを複製するため、良い考えではないようです。 簡単に変更する方法はありません

17
goncalopp

オプション1-ダムデータをコピーしてからUUIDを変更する

ソースパーティションがマウント解除されており、自動マウントされないことを確認します。

dd(遅い、ダム)またはpartclone.btrfs -b -s /dev/src -o /dev/targetを使用します

btrfstune -uを使用して、コピー後およびマウント前にUUIDを変更します。

データ損失の警告Do[〜#〜] not [〜#〜] UUIDが変更されるまで(自動)マウントどちらかオリジナルまたはコピーを試みます


オプション2-btrfs-clone

私は個人的には試していません btrfs-clone ですが、既存のBTRFSファイルシステムを新しいものに複製し、各サブボリュームを順番に複製することを目的としています。

4
Tom Hale

今日(2016-05-06)の時点で既成の解決策は見つかりませんでしたが、コピーオンライト処理を含む私の目的のために問題を解決しました。 /sourceから/targetを「複製」する手順は次のとおりです。

  1. ogenで注文されたサブボリュームのリストを取得します:btrfs subvolume list -qu --sort ogen /source。おそらく、以前のものに依存するスナップショットまたはサブボリュームが最初に処理されることを保証するには、ソートで十分です。最初にベースボリュームを転送する必要があるため、これはコピーオンライトの処理にとって重要です。

  2. btrfs property set -ts /source/some-volume ro trueを使用して、すべてのサブボリュームを読み取り専用にします。

  3. さて、上のリストの各サブボリュームに対して、先頭から始めて、次のようにします。

    1. ボリュームに親UUID(-として表示)がないか、親UUIDがリストに存在しない場合は、次のコマンドを実行します:btrfs send /source/some/volume | btrfs receive /target/some/

    2. ボリュームにまだ存在する親UUIDがある場合、--sort ogenのためにすでに転送されているはずであり、データの重複を回避するためのベースとして使用できます。したがって、リストから親UUIDのパスを見つけて実行します:btrfs send -p /source/parent/volume/ -c /source/parent/volume/ /source/some/volume/ | btrfs receive /target/some/(btrfsはおそらく-p引数を自動的に推測しますが、明示的にすることを好みます)。

    3. 上記のコマンドのいずれかを実行した後、ターゲットとソースを再度読み書き可能にします:btrfs property set -ts /source/some/volume ro false; btrfs property set -ts /target/some/volume ro false。ソースが以前に読み取り専用であった場合は、この手順をスキップできます。

これは多くのケースを処理するはずです。警告:

  1. サブボリューム/スナップショットをネストするときの順序に関して、いくつかの複雑な問題があるかもしれません。

  2. スクリプト化すると、プロセス全体が明らかに楽しいものになります。

  3. btrfs sendは、複数のクローンソース(-c)引数を受け入れます。親のボリュームパスを指定するだけでなく、祖先のパス、または単に以前に送信されたボリュームのパスも指定すると有利な場合があります。ここでは何の違いもありませんでしたが、場合によってはデータの重複を回避するのに役立つ可能性があります。

  4. スナップショットまたはサブボリュームのメタ情報が途中で失われているかどうかはわかりませんしかし、ほとんどのユースケースで興味深い他のすべてのものを保持する必要があります。

プロセス全体で、3.8 GBが使用された(dfに基づく)800 GBファイルシステムを、3.8 GBが使用された10 GBイメージに転送するのに役立ちました。 -pおよび-cなしで転送すると、約190 GBが使用されるため、データの重複は実際に回避されました。

16
Thomas Luzat

これを行うことができる pythonツール を作成しました。これは、自分の実装と@Johannes Ernstの実装の両方で@Thomas Luzatのアプローチを試し、クローン作成手順で使用済みスペースが20GBから40GBに倍増したためです。もっと効率的なものが必要だと思いました。

次の一般的なファイルシステムの履歴を検討してください。

current ---------------------------------\
             |       |        |          |
           snap4   snap3    snap2      snap1

Thomasのアルゴリズムでは、「current」が最初に複製され、すべてのスナップショット(「current」の以前の状態のスナップショット)は、クローンソース/親として「current」を使用します。明らかに、snap3をsnap4に基づいて、snap2をsnap3に基づいて作成した方がよいでしょう。

そして、これは氷山の一角にすぎません。複雑な履歴を持つbtrfsファイルシステムで(スペース節約の観点から)「最良の」クローンソースを見つけることは、重要な問題です。私はこの問題を解決するために他に3つの方法を考え出しました。これはスペースをより効率的に使用するようです。実際には、クローンのサイズがソースのサイズよりもわずかに小さくなっています。

興味があれば github page で詳細を読むことができます。

6
uncleremus

nix.stackexchange.comの同様の質問 がpartclone.btrfsを指していますが、これに関する詳細はわかりません。

カーネルメーリングリストでの議論 もありますが、実際には有望ではありません...

2
jstarek

最後に見たbtrfs-sendはまだbtrfsメーリングリストに浮かんでいる実験的なパッチでした。

2
psusi