「Ubuntu で Time Machine 的なバックアップ」で書いたバックアップは、最近まで順調に進んでいたのですが、ここ数日失敗するようになってしまいました。途中でタイムアウトになってしまうのです。調べてみたところ、QNAP 本体のバックアップ先のディスクが満杯になっていました。
QNAP のハードディスクが壊れた時に備えて、QNAP に USB 接続でもう1つハードディスクをつなぎ、HBS3 アプリを使ってバックアップしています。このアプリが、本体側で削除済みのファイル・ディレクトリをそのまま残してしまっているようです。また、ハードリンクをサポートしていないため、ハードリンクで同一ファイルを表しているエントリをすべて別ファイルとしてコピーしてしまっているようです。まあ、一般のユーザーでそんなことをする人は少数派でしょうから、HBS3 アプリがハードリンクをサポートしていなかったとしても、文句を言う筋合いはありません。自力でやりな、ということですよね。
ということで、自力でやります。Linux のバックアップ対象フォルダに対しては、HBS3 によるバックアップ対象から外して、自前の rsync スクリプトを cron で回します。QNAP の cron の書き方には癖があって、普通に crontab で編集すると、再起動のときに消えてしまうそうです。こちらに解説があるのですが:
QNAP Systems, Inc. - ネットワーク接続ストレージ(NAS)
How to add jobs to crontab to schedule a job
Applicable Products QTS and QuTS Hero Solution You must be able to connect to you QNAP NAS using SSH and know how to edit a file ...
これでも、システムアップデートのときに消えてしまうことがあるようです(Gemini談)。そこで、/share 配下のストレージ(要はハードディスク)の方に rsync のスクリプトと crontab 設定用のスクリプトを両方書いておいて、起動時に crontab 設定を自動実行する、という作戦でいきます。
まず、rsync のスクリプトです。二重起動を避けるため、PIDファイルを使ってプロセスの生存チェックをしています。また、ログローテーションの機能も自前で書いてあります。(chmod +x で実行可能にしておく)
[/share/LinuxBackups/qnap-backup/myrsync.sh]
#!/bin/bash
SCRIPT_DIR="/share/LinuxBackups/qnap-backup"
LOG_DIR="${SCRIPT_DIR}/logs"
LOG_NAME="myrsync"
MAX_BACKUPS=9
PID_FILE="${SCRIPT_DIR}/${LOG_NAME}.pid"
# Check if PID file exists
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
# Check if the process with that PID is actually running
if kill -0 "$PID" 2>/dev/null; then
echo "$(date): Script is already running with PID $PID. Exiting." >> "${LOG_DIR}/${LOG_NAME}.log"
exit 1
else
# The script crashed last time and left a stale PID file
echo "$(date): Stale PID file found ($PID), but process is dead. Cleaning up." >> "${LOG_DIR}/${LOG_NAME}.log"
rm -f "$PID_FILE"
fi
fi
# Create PID file and register cleanup on exit
echo $$ > "$PID_FILE"
trap 'rm -f "$PID_FILE"; exit' INT TERM EXIT
# 1. Delete the oldest log if it exists (myrsync.9.log)
if [ -f "${LOG_DIR}/${LOG_NAME}.${MAX_BACKUPS}.log" ]; then
rm "${LOG_DIR}/${LOG_NAME}.${MAX_BACKUPS}.log"
fi
# 2. Shift existing backups (8 -> 9, 7 -> 8, ..., 1 -> 2)
for i in $(seq $((MAX_BACKUPS - 1)) -1 1); do
if [ -f "${LOG_DIR}/${LOG_NAME}.${i}.log" ]; then
mv "${LOG_DIR}/${LOG_NAME}.${i}.log" "${LOG_DIR}/${LOG_NAME}.$((i + 1)).log"
fi
done
# 3. Rotate the current log to .1.log
if [ -f "${LOG_DIR}/${LOG_NAME}.log" ]; then
mv "${LOG_DIR}/${LOG_NAME}.log" "${LOG_DIR}/${LOG_NAME}.1.log"
fi
# 4. Do rsync backup
rsync -aHAX --numeric-ids --info=progress2 --recursive --delete --force --stats --sparse "/share/LinuxBackups/snapshots/" "/share/Dev1Partition1/LinuxBackups/snapshots/" >"${LOG_DIR}/${LOG_NAME}.log" 2>&1
次に、crontab 設定用のスクリプトです。(これも chmod +x で実行可能にしておく)
[/share/LinuxBackups/qnap-backup/setup-cron.sh]
#!/bin/sh
CRON_LINE="0 2 * * * /share/LinuxBackups/qnap-backup/myrsync.sh"
if ! grep -q "myrsync.sh" /etc/config/crontab; then
echo "$CRON_LINE" >> /etc/config/crontab
crontab /etc/config/crontab
/etc/init.d/crond.sh restart
fi
自動実行の設定をします。QNAP の管理ページに Web 経由でログインして、「コントロールパネル>システム>ハードウェア」を開き、「起動時にユーザー定義処理を実行」にチェックを入れます。
次に autorun.sh を作成しますが、これがちょっと難しい。以下のページに解説があるのですが、「TS-x28の場合」の説明の通りにやっても、「/dev/mmcblk0p7 does not exist」と断られます。その下にある「init」スクリプトを使うやり方でいきます。
$ /etc/init.d/init_disk.sh mount_flash_config
$ vi /tmp/nasconfig_tmp/autorun.sh
/bin/bash /share/LinuxBackups/qnap-backup/setup-cron.sh
$ chmod +x /tmp/nasconfig_tmp/autorun.sh
$ ls -l /tmp/nasconfig_tmp
total 52
-rwxr-xr-x 1 admin administrators 57 2026-09-12 22:28 autorun.sh*
drwx------ 2 admin administrators 16384 2009-08-25 15:29 lost+found/
-rw-r--r-- 1 admin administrators 8666 2026-07-26 10:07 smb.conf
-rw-r--r-- 1 admin administrators 11 2026-07-26 10:07 smb.conf.cksum
-rw-r--r-- 1 admin administrators 37 2020-10-25 19:12 system.map.key
-rw-r--r-- 1 admin administrators 8708 2026-07-26 10:07 uLinux.conf
$ /etc/init.d/init_disk.sh umount_flash_config
先ほどのコントロールパネルの画面で「autorun.shを開く」をクリックすると、書き込んだスクリプトを確認することができます。
動作確認です。
$ crontab -l | grep myrsync
(何も出力なし)
$ /tmp/nasconfig_tmp/autorun.sh
Stopping periodic command scheduler: crond.
Starting periodic command scheduler: crond.
$ crontab -l | grep myrsync
0 2 * * * /share/LinuxBackups/qnap-backup/myrsync.sh
しばらくこれで運用して、様子を見ます。バックアップは、安定して動くようになるまで、試行錯誤が必要ですね。

