rsyncでなくsend/receiveを使うことでBtrfsに戻す
sync
- TOP
- Old Archives
- rsyncでなくsend/receiveを使うことでBtrfsに戻す
概要
btrfsがrsyncで死んでしまうので、現在はLVM+XFSを使用しているが、いい加減容量は限界近いのでbtrfsに戻す。
rsyncで詰んでしまう以上、rsyncではなく、send/receiveを用いたものとする。 btrfs wikiによれば、rsyncを用いるよりも遥かに高速なのだという。
手順
まずはアンマウント
umount /MirrorSlave
そして、LVMをインアクティブに
vgchange -a n
btrfsを作る
mkfs.btrfs -L MirrorBtr /dev/mapper/btr*
/etc/fstabを編集する
UUID=0123456-7890-acbd-ef01-234567890ab /MirrorRoot btrfs noauto,noatime,autodefrag,compress-force=lzo,space_cache,subvol=mirror 0 0
初期化スクリプトを編集する
#!/bin/zsh
typeset -i index=1
for i in /dev/disk/by-id/{ata-foo,ata-bar,ata-baz,ata-quux}
do
# print $i
cryptsetup --hash=sha512 --cipher=twofish-xts-plain --offset=0 --key-file=/home/foo/key --key-size=512 open --type=plain "$i" "btrdm_$(printf "%02d" $index)" || exit 1
(( index++ ))
done
mount /MirrorRoot
#mount -U 7ebc7d8d-35c6-4d98-8457-3323c242e9fe -o noatime,autodefrag,compress-force=lzo,space_cache,subvol=mirror /MirrorRoot
#pvscan
#vgscan
#lvscan
#vgchange -a y MirrorVG
#lvchange -a y MirrorVG/MirrorLV
#mount -U "0d09b605-a52b-48f4-8ad5-ed26456ab6cd" /MirrorRoot
クライアント側スクリプト。
#!/usr/bin/zsh
notify-send "BtrSnapSync: Woke"
if ! btrfs subvolume snapshot -r /home/foo/share /home/foo/share/snapshots/snapshot-new
then
print "BtrSnapSync: **CRITICAL** Failed to create new snapshot"
exit 2
fi
sync
notify-send "BtrSnapSync: Snapshot."
if [[ -e /home/foo/share/snapshots/snapshot-old ]]
then
if btrfs send -v -p /home/foo/share/snapshots/snapshot-old /home/foo/share/snapshots/snapshot-new/ | ssh -v -i /root/.ssh/btrsnapsync daisy.local /usr/local/sbin/btrrecv.sh
then
notify-send "Send Snapshot."
btrfs subvolume delete /home/foo/share/snapshots/snapshot-old
mv /home/foo/share/snapshots/snapshot-new /home/foo/share/snapshots/snapshot-old
notify-send "Deleted old Snapshot."
else
notify-send "Failed to send Snapshot"
btrfs subvolume delete /home/foo/share/snapshots/snapshot-new
fi
else
if btrfs send -v /home/foo/share/snapshots/snapshot-new | ssh -i /root/.ssh/btrsnapsync daisy.local /usr/local/sbin/btrrecv.sh
then
notify-send "Send Snapshot."
mv /home/foo/share/snapshots/snapshot-new /home/foo/share/snapshots/snapshot-old
notify-send "Deleted old Snapshot."
else
notify-send "Failed to send Snapshot"
btrfs subvolume delete /home/foo/share/snapshots/snapshot-new
fi
fi
サーバー側スクリプト
#!/bin/sh
btrfs receive /MirrorRoot && mv /MirrorRoot/snapshot-new /MirrorRooot/snapshot`date +%y%m%d%H%M`
rootのSSH鍵を生成(適宜)
mkdir .ssh
ssh-keygen -f .ssh/snapshot
chmod 700 .ssh
chmod 600 .ssh/*
鍵を転送(適宜)
scp .ssh/snapshot.pub server:.ssh/authorized_keys
ssh server
chmod 600 .ssh/authorized_keys
鍵をコマンドに結びつける
vim .ssh/authorized_keys
sshd_configでforced-commands-only
vim /etc/ssh/sshd_config
挙動
btrfsのsnapshotやsend/receiveについて知識がなかったため、挙動をひとつひとつ確認することにした。
まず、snapshotはディレクトリに見える。 そのディレクトリにはスナップショットの完全なファイルがあるように見える。常時アクセス可能な凍結された状態が存在するわけだ。
そして、スナップショットは元となるボリュームにネストされたサブボリュームになる。 つまり、/fooにマウントされているサブボリュームのスナップショットは、/foo/snapshot1のようになるというわけだ。この外、例えば/barには置けない。
この/foo/snapshot1はmv
は可能だが、rm
はできない。rm
するのであれば、btrfs subvolume delete
でなければならない。
このスナップショットをsendする時、-p
オプションがなければそのsnapshotを構成する全体を送信する。あれば、指定されたサブボリューム(マウントされたディレクトリを指定)との差分を送信する。
内容は標準出力に吐かれ、-f
オプションで保存することもできるが、それはリダイレクトで保存しても良いようだ。
receiveについても、およそ似たような挙動である。
標準出力から読んで再編成するか、もしくは-f
オプションでファイルから編成する。
これは、sharのようなものではなく、編成されるのはスナップショットである。
つまり、snapshot1というsnapshotをreceiveした場合、snapshot1というsnapshotが作られる。
mvで名前が変わった状態で、-pオプション付きで送りつけたsnapshotがどうなるのかは、まだ試していない。
snapshotにロールバックする場合は、マウントポイントの付け替えと、サブボリュームのデリートでよさそうだ。set-default
が必要か?
多くのスナップショットを維持することでディスク容量やI/Oにどのように影響するのかはわからない。 英語文書を読めばよいのかもしれないが、なかなか大変そうなので、そこには当面手を付ける予定はない。
思わぬつまづき
rootユーザーでRSA鍵でsshログインできないという問題に遭遇した。
一般ユーザーならばできるし、またサーバー側がsshd -d
で起動した場合は通る。
デバッグモードなら通るため、メッセージの確認もできない。
かなり困った。