FreeBSD UFS Snapshot Management Environmentを使って定期的にSnapshotを作成する

最近、ML115を使ったFreeBSD 7.2-RELEASE boxを仕立てたので、某所からのサルベージも兼ねて、以前書いた記事の内容を再実行してる。
自宅サーバに格納されているデータは、1日1回rsyncを使って自宅サーバの外付けHDDにコピーを取得している。rsyncは--deleteをつけて動作させてるので、サーバのデータを誤って削除した場合、次のrsyncが起動するまでに気づかないとゲームオーバーになる。それじゃあんまりなので、FreeBSD UFS Snapshotを使って何日分かのデータを残しましょう、という話題。
ちなみに、Maildirのメールボックスがあるため、pdumpfsなんかのファイルレベルの操作は時間がかかりすぎて対応不能なことが、身にしみて分かってる。

FreeBSD UFS Snapshot Management Environmentのインストールと設定

まずは、今回使用するFreeBSD UFS Snapshot Management Environmentをインストールする。sysutils/freebsd-snapshotでportsになってるので、インストールは楽ちん。インストールが終わると、periodic-snapshot(8)が使えるようになってる。
periodic-snapshot(8)は、cronから起動することで、/etc/periodic.confの設定に従って、hourly/daily/weeklyのsnapshotを作成してくれる。FreeBSD base systemのperiodicと似てるけど、hourlyがあってmonthlyがないところが異なる。
まずは、/etc/crontabにperiodic-snapshotを起動する設定を追加する。

# /etc/crontab

0	*	*	*	*	root	/usr/local/sbin/periodic-snapshot hourly
0	0	*	*	*	root	/usr/local/sbin/periodic-snapshot daily
0	0	*	*	0	root	/usr/local/sbin/periodic-snapshot weekly

次は、/etc/periodic.confでsnapshotの取得方法を設定する。

snapshot_enable="YES"
snapshot_schedule="/home:2:10:0"

snapshot_scheduleは、各ファイルシステムでどんなタイミングでsnapshotを作成するかの設定。:で区切られた最初のフィールドには、ファイルシステムを記述する。複数記述したい場合は、カンマで区切る。残りの3つのフィールドは、snapshotの個数を設定する。左から順番に、weekly daily hourlyで、0を記述するとそのタイミングではsnapshotを作成しないことになる。/home:2:10:0だと、weeklyを2個とdailyを10個、という設定になる。
また、hourlyは取得する時刻を1時間単位で指定できる。たとえば/home:2:6:8@8,12,16,20だと、8:00, 12:00, 16:00, 20:00にhourly snapshot作成し、8回分を保存することになる。
なお、snapshotの個数は、合計で20を超えないようにする必要がある。これはFreeBSD UFS Snapshotの限界からくるもの。
あとは、しばらく待ってperiodic-snapshotが起動すれば、指定したとおりのsnapshotができてるはず。/home/.snap/以下を確認してみるべし。
取得したsnapshotは、snapshot(8)でmountして使用する。

/homeのsnapshotをmount
# snapshot mount /home:daily.0 /mnt

umount
# snapshot umount /mnt

amdを使ってFreeBSD UFS Snapshotに簡単にアクセスする

periodic-snapshot(8)を使って作成したsnapshotは、snapshot(8)を使ってread onlyでmountできる。とは言っても、root権限で実行する必要があるし、現在どんなsnapshotが存在するかどうかは.snapディレクトリを見ないと分からないから面倒。というわけで、amd(8)を使って楽をしましょう、という話題。
amd(8)は、FreeBSD base systemに含まれる自動マウントのためのデーモンプログラム。Linuxだとautofsに相当する。よくある使い方としては、homeをnfsで共有してる場合、必要なユーザのhomeのみを自動的にマウントするため、など。amd(8)は、所定のpathにアクセスがあった際に、あらかじめ設定されたprogramを起動してマウントすることができる。今回は、snapshot(8)を使うことで、snapshotの自動マウントを実現した。
というわけで、実際の設定メモ。まずはamd(8)の設定ファイルから。とは言っても、FreeBSD UFS Snapshot Management Environmentをインストールしていれば、/usr/local/etc/amd.map.snapに設定ファイルがインストールされる。うちの環境だと、snapshot対象が/media/backupだから、mountコマンドに変更が必要になるため、amd.snapにコピーして変更した。/${key}の前に、snapshot対象のマウントポイントの一つ上までのディレクトリを追加すればok。今回は対象が/media/backupだから、/mediaを追加した。

/defaults type:=program
*         mount:="/usr/local/sbin/snapshot snapshot mount /media/${key} ${fs}";\
          unmount:="/usr/local/sbin/snapshot snapshot umount ${fs}"

このmapファイルを指定してamd(8)が起動するように、/etc/rc.confに以下の設定を追加する。各オプションの意味は、manを参照。

amd_enable="YES"
amd_flags="-a /.am -c 1800 -w 60 -l syslog /snap /usr/local/etc/amd.snap"

rc.confへの設定が終われば、/etc/rc.d/amdを使用してamd(8)を起動するか、サーバごと再起動。
後は所定のディレクトリに移動すれば、amd(8)がsnapshot mountを自動的に起動してくれる。これで、snapshotへのアクセスがかなり楽ちんになった。

> cd /snap/backup:daily.0

自動的にマウントされてる
> df
/dev/md0               236511738  83503274 134087526    38%    /.am/hostname/snap/backup:daily.0

/snapからマウントポイントへsymlinkが張られてる
> ls -l /snap
total 1
lrwxrwxrwx  1 root  wheel  32 11 28 23:37 backup:daily.0 -> /.am/hostname/snap/backup:daily.0

なお、amd(8)で使うmapの書き方については、FreeBSD base systemのmanにはないので、
本家am-utilsのドキュメント
に当たるとよい。今回使用したのは、Am-utils (4.4BSD Automounter Utilities): 5. Filesystem Typesの中のAm-utils (4.4BSD Automounter Utilities): 5. Filesystem Types