« | »

自宅サーバーをセットアップした際に、すべてを HDD にインストールしていたのですが、今回、/home と /boot、過去のスナップショットデータ以外を SSD に引っ越しました。このとき、Btrfs のサブボリュームとしての引っ越しをしてみました。

最初に openSUSE の Btrfs のサブボリューム構成についておさらいです。Snapper が有効化された状態のサブボリューム構成は次のようになっていました。Btrfs の / には @ というサブボリュームが1つだけあります。@ の中にマウントしたシステムの / にあるディレクトリに対応したサブボリュームがあります。ちなみに /@ が / としてマウントするのではなく、それぞれのサブボリュームごとに /etc/fstab でマウントしています(例: /@/home が /home)。Snapper を使用している場合は 1 番目のスナップショットが現在の / です。

以下のリストに無い、/@/.snapshots/1/ や /@/boot/grub2/ はサブボリュームではなく、その上にあるサブボリューム内のディレクトリです。

さて、今回は /@/home と /@/boot/* を HDD に残し、その他を SSD に移動することにしました。パーティション全体であれば、dd で、ファイルレベルであれば rsync と色々な方法がありますが、今回は Btrfs のサブボリュームを他の Btrfs ファイルシステムに転送する btrfs send を使いました。

作ってみたスクリプトを先に貼り付けて、ポイントを個別に説明します。使い方はコピー元を /dev/sda1、コピー先を /dev/sdb1 とし、次のように使います。3番目の引数はスキップするサブボリュームのパターンです。/dev/sdb1 は mkfs.btrfs でフォーマットしてある前提です。
$ btrfs-subvols-copy.sh /dev/sda1 /dev/sdb1 "@/home|@/.snapshots/[2-9][0-9]*|@/boot"

まずは、送信元、先のボリュームのマウントです。

送信元と先をマウントするだけなのですが、注意点が1つあります。Btrfs では任意のサブボリュームを選んでマウントすることができますが、何も指定しないと / ではなく、デフォルトのサブボリューム(btrfs subvolume set-default で設定可能)がマウントされてしまいます。特に Snapper を使用していると、1番目の Snapper スナップショットがデフォルトになっていますので、明示的に subvol でマウントしたいサブボリュームの指定が必要です。

次に、送信元のサブボリュームのリストアップです。

--sort=path を指定して、親ディレクトリを含むサブボリュームを先にリストし、サブボリュームのツリー構造の親サブボリュームとディレクトリを先にコピーするようにします(存在しないとエラーになってしまいます)。

次に送信するところです。

btrfs send コマンドを使ってコピーするのですが、送信できるのは読み取り専用のサブボリュームなので、一度スナップショットを読み取り専用で作成し、このスナップショットを送ります。コピーは btrfs sendbtrfs receive のペアで行えます。サブボリュームの名前(パス)は送信元と同じものが作成されます。そのため、スナップショットの名前になってしまうので、あとで mv が必要でちょっと不便です(スナップショットを別のディレクトリに作成する方法もあり)。

注意が必要なことが1つあります。この送り方では Snapper のスナップショットを送れません。Snapper のスナップショットはスナップショット間で共通するデータを共有していますが、この方法ではこの共有が解けて複製されてしまいます。btrfs send のオプションにベースとなったスナップショットを指定し、差分だけを送る機能があるようなので、もう少し工夫すると実現できるかもしれません。

最後に、サブボリュームのプロパティのコピーです。

送信前に読み取り専用のスナップショットを作成していますので、読み取り専用を含めた、送信後サブボリュームのプロパティをもと同じに戻します。

コメント/トラックバック

トラックバックURL:

コメントする

※管理人にのみ公開されます