URAMIRAIKAN

1020のなれの果て (since 2005.6.19)

SambaでVSSを使えるようにする

 ちょっと前にCentOS 7で構築したファイルサーバでボリューム・シャドウ・コピー・サービス(VSS)が使いたいという要望があったので、やったことのメモ。

 LVMのスナップショットとrsyncのどちらでやるか迷いましたが、ディスクの容量とかを考えて前者にしました。

 対象の環境はLVMを使用していて、共有フォルダ用のLVを作っていました。
 しかし、一つのLVで複数の共有フォルダを設定していたので、単純にスナップショットを作成して共有フォルダ配下にマウントするという方法はできません。
 そこで、シンボリックリンクを使って下図のような構成にしました。


 Samba側では、"smb.conf"の各共有にvfs_shadow_copy2関連の設定を追加すると共に、[global]セクションにもリンクをたどれるように設定を入れます。
 以下、追加した部分の抜粋です。

[global] ~ snip ~ wide links = yes unix extensions = no follow symlinks = yes ~ snip ~ [share1] ~ snip ~ vfs objects = shadow_copy2 shadow:snapdir = /export/share1/.snap shadow:basedir = /export/share1 shadow:format = GMT-YYYY.MM.DD-hh.mm.ss shadow: sort = desc ~ snip ~

 "shadow:format"は、SambaがVSSとして認識するスナップショット名のフォーマットです。このフォーマットに合わせたフォルダ名で"shadow:snapdir"(上記の例では"/export/share1/.snap")配下にスナップショットを見せなければなりません。
 今回は、この部分をシンボリックリンクにします。
 処理は次の通り。

  1. "lvcreate -s"でLVMスナップショットを作成
  2. 作成したスナップショットを"/export/.snap"にRead Onlyでマウント
  3. 各共有配下にスナップショット内の同一階層へのシンボリックリンクを作成(リンク元は"/export/share1/.snap/GMT-2016.01.25-09.00.00"のようにする)

 これでWindowsのエクスプローラでファイル/フォルダを選択し、「プロパティ」→「以前のバージョン」で過去のファイルを復元できるようになりました。
 あとは処理をスクリプト化して、Cronで定期的に実行するようにします。
 (とりあえず日次で1世代を想定)

#!/bin/bash VG="vg01" LV="lv01" BASEMNT="/export" SNAPMNT="${BASEMNT}/.snap" SNAPSIZE="30G" SNAPFREC="${BASEMNT}/.snap-old" SHAREDIR=("share1" "share2" "share3") # Unmount old snapshot [ -d ${SNAPMNT} ] || mkdir -p ${SNAPMNT} if mountpoint -q ${SNAPMNT}; then umount ${SNAPMNT} if [ $? -ne 0 ]; then sleep 15 umount ${SNAPMNT} if [ $? -ne 0 ]; then # 古いスナップショットのアンマウントに失敗 exit 1 fi fi fi # Create snapshot SNAPNAME=$(TZ=GMT date +GMT-%Y.%m.%d-%H.%M.%S) sync /sbin/lvcreate -s -L ${SNAPSIZE} -n ${SNAPNAME} /dev/${VG}/${LV} mount -o nouuid,ro /dev/${VG}/${SNAPNAME} ${SNAPMNT} if [ $? -ne 0 ]; then # スナップショットのマウントに失敗 exit 2 fi # Delete old snapshot if [ -f ${SNAPFREC} ]; then SNAPOLD=$(cat ${SNAPFREC}) /sbin/lvremove -f /dev/${VG}/${SNAPOLD} if [ $? -ne 0 ]; then # 古いスナップショットの削除に失敗 exit 3 fi fi # Create VSS link for DIR in ${SHAREDIR[@]} do if [ -d ${BASEMNT}/${DIR}/.snap ]; then rm -f ${BASEMNT}/${DIR}/.snap/GMT* ln -s ${SNAPMNT}/${DIR} ${BASEMNT}/${DIR}/.snap/${SNAPNAME} fi done echo -n $SNAPNAME > $SNAPFREC exit 0

 古いスナップショットが残り続けるとディスクを圧迫することがあるので、実運用では監視をちゃんとしないといけないですね。

 最初からここまで考えて、共有フォルダ単位でLVを作っておくべきだったのですよね…。