Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

啟用 Synology DS1813+ 的 btrfs 與 snapshot 功能
post by tommy @ 10 四月, 2016 19:27

去年開始 Synology 在 DSM 5.2 在少數的幾個機型加入了 btrfs 的支援,  然後在今年的 DSM 6.0 上, 又增加了一些機型. 不過.... 我使用的 DS1813+ 並沒有在支援的機型內.

實際連線進去主機查看, lsmod | grep btrfs 可以看到 kernel 有加入  btrfs 的模組, 執行 btrfs 也可以看到也有放入 btrfs 的指令... 也許是為了與新的機器做出區隔, 故意不把 btrfs 的功能打開.... 所以... 只好自己動手來做了.

要啟用 btrfs 的功能, 只要修改 /etc/synoinfo.conf 加入下面的設定:

support_btrfs="yes"

然後重開機就可以在新建儲存空間時選擇 btrfs 來格式化.

在網路上查過的資料, 是建議下面三個設定:

support_btrfs="yes"
support_dr_snap="yes"
support_share_snapshot="yes"

不過... 第三個似乎原本就有打開, 第二個.... Synology 把 snapshot 的管理 web 介面用另一個 package 來處理, 而且... 似乎不允許裝在 DS1813+ 上, 所以就算打開來也沒作用.

因為沒有這個管理介面, 只好自改寫個 script 透過 btrfs 來處理.

#!/bin/bash
 
#
# btrfs snapshot script
#
# 需傳入 4 個或 5 個參數
# 第一個參數是 btrfs 的根目錄, 如 /volume1
# 第二個參數是快照要存放的目錄, 為第一個參數下的子目錄, 如 snapshot
# 第三個參數是快照的類別, 如 hourly, daily, weekly, monthly 之類
# 可以是任意不含空白字串, 用來分類使用
# 產生的快照目錄會以這個字串加底線再加日期時間為目錄名稱
# 第四個參數是要產生快照的 subvolume 列表, 以空白區隔, 使用雙引號包起來
# 這些 subvolume 是位於第一個參數下的子目錄
# 第五個參數是要保留的快照數量, 沒有指定時為 2
 
# btrfs 的根目錄
if [ "x$1" == "x" ]; then
echo "syntax: $0 btrfs_root snapshot_vol snapshot_type subvolume_list [keep_number]"
exit 1
fi
BTRFS_ROOT="$1"
 
# 快照要存放的子目錄 (位於 ${BTRFS_ROOT} 目錄下)
if [ "x$2" == "x" ]; then
echo "syntax: $0 btrfs_root snapshot_vol snapshot_type subvolume_list [keep_number]"
exit 1
fi
SNAPSHOT_DIR="$2"
 
# 快照類別
if [ "x$3" == "x" ]; then
echo "syntax: $0 btrfs_root snapshot_vol snapshot_type subvolume_list [keep_number]"
exit 1
fi
SNAPSHOT_TYPE="$3"
 
# 快照 subvolume 列表
if [ "x$4" == "x" ]; then
echo "syntax: $0 btrfs_root snapshot_vol snapshot_type subvolume_list [keep_number]"
exit 1
fi
SNAPSHOT_VOLUME_LIST="$4"
 
# 保留的快照數量
if [ "x$5" == "x" ]; then
KEEP_SNAPSHOT=2
else
KEEP_SNAPSHOT=$5
fi
 
# 產生的快照存放的目錄
SNAPSHOT_ROOT="${BTRFS_ROOT}/${SNAPSHOT_DIR}"
 
# 當天的日期時間
TM=`date +%Y%m%d%H%M%S`
 
echo "-----------------------------------------------"
echo "處理快照類別: ${SNAPSHOT_TYPE}"
echo "-----------------------------------------------"
if [ ! -d "${SNAPSHOT_ROOT}" ]; then
echo "目錄 ${SNAPSHOT_ROOT} 不存在!"
exit 1
fi
 
ERRCODE=0
for vol in ${SNAPSHOT_VOLUME_LIST}; do
SUBVOLUME_ROOT="${BTRFS_ROOT}/${vol}"
VOLUME_ROOT="${SNAPSHOT_ROOT}/${vol}"
echo "================================================="
echo "處理快照目錄 ${VOLUME_ROOT}"
echo "================================================="
if [ ! -d "${VOLUME_ROOT}" ]; then
echo "建立目錄: ${VOLUME_ROOT}"
mkdir "${VOLUME_ROOT}"
if [ $? -ne 0 ]; then
echo "無法建立目錄: ${VOLUME_ROOT}"
ERRCODE=1
continue
fi
fi
echo "移除舊的快照, 保留最近的 ${KEEP_SNAPSHOT} 個快照"
echo "-----------------------------------------------"
DIRS=`ls -d ${VOLUME_ROOT}/${SNAPSHOT_TYPE}_* 2>/dev/null | sort -r`
i=0
for dirname in ${DIRS}; do
let "i += 1"
if [ ${i} -le ${KEEP_SNAPSHOT} ]; then
echo "略過 ${i}: ${dirname}"
continue;
fi
echo "刪除 ${i}: ${dirname}"
bname=`basename ${dirname}`
CNT=`btrfs subvolume list "${BTRFS_ROOT}" | grep "${SNAPSHOT_DIR}/${vol}/${bname}" | wc -l`
if [ "$CNT" == "0" ]; then
echo "${dirname} 不是快照"
echo "刪除目錄: ${dirname}"
rmdir "${dirname}"
if [ $? -ne 0 ]; then
echo "無法刪除目錄: ${dirname}"
ERRCODE=1
fi
else
echo "${dirname} 是快照"
echo "刪除快照: ${dirname}"
btrfs subvolume delete "${dirname}"
if [ $? -ne 0 ]; then
echo "無法刪除快照: ${dirname}"
ERRCODE=1
fi
fi
done
echo "-----------------------------------------------"
SNAPSHOT_TM="${VOLUME_ROOT}/${SNAPSHOT_TYPE}_${TM}"
if [ -d "${SNAPSHOT_TM}" ]; then
echo "目錄已存在: ${SNAPSHOT_TM}"
ERRCODE=1
continue
fi
echo "建立新的快照: ${SNAPSHOT_TM}"
echo "-----------------------------------------------"
btrfs subvolume snapshot -r "${SUBVOLUME_ROOT}" "${SNAPSHOT_TM}"
if [ $? -ne 0 ]; then
echo "無法為 ${SUBVOLUME_ROOT} 建立新的快照 ${SNAPSHOT_TM}"
ERRCODE=1
continue
fi
done
echo "-----------------------------------------------"
 
exit ${ERRCODE}

檔案可以在 http://www.teatime.com.tw/~tommy/files/mysnapshot.sh.gz 下載.

透過這個 script, 可以自己在排程的地方,每小時, 每天, 每週或每月來產生新的快照並把舊的刪除.

這個 script 需要 4 或 5 個參數.

第一個參數是 btrfs 的根目錄, 例如: /volume1

第二個參數是產生的快照要存放的目錄, 是第一個參數下的一個子目錄 (透過共用資料夾來建立, 可以設定權限方便日後使用)

第三個參數是快照的類別, 用來區隔不同的排程產生的快照, 例如 hourly, daily, weekly monthly 之類的不包含空白的字串, 其際產生的快照目錄名稱會使用這個字串加上 _ 再加上 YYYYMMDDhhmmss 來當目錄名.

第四個參數是要產生快照的 subvolume 列表, 如果有多個, 請用雙引號處理, 每個 subvolume 用空白區隔, 如 "ftp backup download"

第五個參數是要保留的快照數量, 沒有指定時, 會保留兩個快照 (加上新增的就會有 3 個).

透過自訂的排程處理後, 會得到下列這樣的快照:

root@DS1813:/volume1/snapshot# ls -la /volume1/snapshot/ftp/
total 0
d--------- 1 root root 1240 Apr 11 10:31 .
d--------- 1 root root 102 Apr 11 09:17 ..
drwxr-xr-x 1 root root 280 Apr 7 16:00 daily_20160409115902
drwxr-xr-x 1 root root 280 Apr 7 16:00 daily_20160410000102
drwxr-xr-x 1 root root 280 Apr 7 16:00 daily_20160411000102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410103102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410113102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410123102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410133102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410143103
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410153102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410163102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410173102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410183102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410193102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410203102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410213102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410223102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160410233103
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411003102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411013102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411023102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411033102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411043102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411053102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411063102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411073102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411083102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411093102
drwxr-xr-x 1 root root 280 Apr 7 16:00 hourly_20160411103102
drwxr-xr-x 1 root root 280 Apr 7 16:00 weekly_20160410010102
 

上面的方式... 只在 DS1813+ 上試過, 不保證你的機型也能用.... 不過... 基本上 lsmod | grep btrfs 有看到 btrfs 的模組, 執行 btrfs 有正確的指令, 就應該可以用吧.

 


2016/4/12 補充:

1. 上面的 script, 在建立快照的地方加上 -r 來產生唯讀的快照, 避免修改到快照的內容.

2. 如果需要還原時... 少數的檔案, 可以直接到該快照去複製回去就可以. 如果是整個 subvolume 都要還原, 就只能連進系統來下指令了. 例如把 /volume1/snapshot/ftp/daily_2016041000102 這個快照, 還原到 /volume1/ftp 時:

mv /volume1/ftp /volume1/ftp.old
mv /volume1/snapshot/ftp/daily_2016041000102 /volume1/ftp
btrfs property set -ts /volume1/ftp ro false

簡單來說, btrfs 對於 subvolume/snapshot 的處理, 直接用搬移或改名就可以. 所以先把原本的路徑改名, 再把要還原的快照改成那個路徑名, 然後把唯讀的快照改成可以寫入就可以.

至於舊的 subvolume, 確定不要用就可以用 

btrfs subvolume delete /volume1/ftp.old

刪除就可以. (有些 volume 可能系統使用中, 無法刪除.... 要重開機後才能刪)

Del.icio.us Furl HEMiDEMi Technorati MyShare
commons icon [1] Re:啟用 Synology DS1813+ 的 btrfs 與 snapshot 功能 [ 回覆 ]

DSM 6.1 已經加入 Btrfs 的支援了

迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 90 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS