Skip to content

Commit c1239ad

Browse files
authored
Merge pull request #36 from buildplan/improve_ssh_compatibility
fix(rsync): Make --noatime option configurable for compatibility
2 parents 00a8873 + 6a73659 commit c1239ad

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

README.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ To run the backup automatically, edit the root crontab.
184184
185185
```ini
186186
# =================================================================
187-
# Configuration for rsync Backup Script v0.30
187+
# Configuration for rsync Backup Script v0.31
188188
# =================================================================
189189
# !! IMPORTANT !! Set file permissions to 600 (chmod 600 backup.conf)
190190
@@ -216,6 +216,9 @@ BEGIN_SSH_OPTS
216216
/root/.ssh/id_ed25519
217217
END_SSH_OPTS
218218
219+
# Set RSYNC_NOATIME_ENABLED to true for a performance boost if rsync >= 3.3.0. Set to false for older versions (e.g., 3.2.7).
220+
RSYNC_NOATIME_ENABLED=false
221+
219222
# The timeout in seconds for rsync operations.
220223
RSYNC_TIMEOUT=300
221224
@@ -304,7 +307,7 @@ END_EXCLUDES
304307
305308
```bash
306309
#!/bin/bash
307-
# ===================== v0.30 - 2025.08.13 ========================
310+
# ===================== v0.31 - 2025.08.13 ========================
308311
#
309312
# =================================================================
310313
# SCRIPT INITIALIZATION & SETUP
@@ -374,9 +377,8 @@ if [ -f "$CONFIG_FILE" ]; then
374377
value="${value%\"}"; value="${value#\"}"
375378

376379
case "$key" in
377-
BACKUP_DIRS|BOX_DIR|BOX_ADDR|LOG_FILE|LOG_RETENTION_DAYS|\
378-
MAX_LOG_SIZE_MB|BANDWIDTH_LIMIT_KBPS|RSYNC_TIMEOUT|\
379-
CHECKSUM_ENABLED|\
380+
BACKUP_DIRS|BOX_DIR|BOX_ADDR|LOG_FILE|LOG_RETENTION_DAYS|CHECKSUM_ENABLED|\
381+
MAX_LOG_SIZE_MB|BANDWIDTH_LIMIT_KBPS|RSYNC_TIMEOUT|RSYNC_NOATIME_ENABLED|\
380382
NTFY_ENABLED|DISCORD_ENABLED|NTFY_TOKEN|NTFY_URL|DISCORD_WEBHOOK_URL|\
381383
NTFY_PRIORITY_SUCCESS|NTFY_PRIORITY_WARNING|NTFY_PRIORITY_FAILURE|\
382384
RECYCLE_BIN_ENABLED|RECYCLE_BIN_DIR|RECYCLE_BIN_RETENTION_DAYS)
@@ -435,11 +437,15 @@ if (( ${#SSH_OPTS_ARRAY[@]} > 0 )); then
435437
fi
436438

437439
RSYNC_BASE_OPTS=(
438-
-aR -z --delete --partial --timeout="${RSYNC_TIMEOUT:-300}" --mkpath --noatime
440+
-aR -z --delete --partial --timeout="${RSYNC_TIMEOUT:-300}" --mkpath
439441
--exclude-from="$EXCLUDE_FILE_TMP"
440442
-e "$SSH_CMD"
441443
)
442444

445+
if [[ "${RSYNC_NOATIME_ENABLED:-false}" == "true" ]]; then
446+
RSYNC_BASE_OPTS+=(--noatime)
447+
fi
448+
443449
# Optional: Add bandwidth limit if configured
444450
if [[ -n "${BANDWIDTH_LIMIT_KBPS:-}" && "${BANDWIDTH_LIMIT_KBPS}" -gt 0 ]]; then
445451
RSYNC_BASE_OPTS+=(--bwlimit="$BANDWIDTH_LIMIT_KBPS")
@@ -542,6 +548,20 @@ run_preflight_checks() {
542548
done
543549
if [[ "$check_failed" == "true" ]]; then exit 10; fi
544550
if [[ "$test_mode" == "true" ]]; then printf "${C_GREEN}✅ All required commands are present.${C_RESET}\n"; fi
551+
# Check rsync version for --noatime compatibility if the feature is enabled
552+
if [[ "${RSYNC_NOATIME_ENABLED:-false}" == "true" ]]; then
553+
if [[ "$test_mode" == "true" ]]; then printf "${C_BOLD}--- Checking rsync version for --noatime...${C_RESET}\n"; fi
554+
local rsync_version
555+
rsync_version=$(rsync --version | head -n1 | awk '{print $3}')
556+
local major minor
557+
IFS='.' read -r major minor _ <<< "$rsync_version"
558+
if ! (( major > 3 || (major == 3 && minor >= 3) )); then
559+
printf "${C_RED}❌ FATAL: RSYNC_NOATIME_ENABLED is true but rsync version %s is too old.${C_RESET}\n" "$rsync_version" >&2
560+
printf "${C_DIM} The --noatime option requires rsync version 3.3.0 or newer.${C_RESET}\n" >&2
561+
exit 10
562+
fi
563+
if [[ "$test_mode" == "true" ]]; then printf "${C_GREEN}✅ rsync version %s supports --noatime.${C_RESET}\n" "$rsync_version"; fi
564+
fi
545565
if [[ "$test_mode" == "true" ]]; then printf "${C_BOLD}--- Checking SSH connectivity...${C_RESET}\n"; fi
546566
# Quick preflight connectivity "ping": short 10s timeout for fail-fast behaviour
547567
if ! ssh "${SSH_OPTS_ARRAY[@]}" -o BatchMode=yes -o ConnectTimeout=10 "$BOX_ADDR" 'exit' 2>/dev/null; then
@@ -568,7 +588,7 @@ run_preflight_checks() {
568588
fi
569589
if [[ "$dir" != *"/./"* ]]; then
570590
local err_msg="Directory '$dir' in BACKUP_DIRS is missing the required '/./' syntax."
571-
if [[ "$test_mode" == "true" ]]; then
591+
if [[ "$test_mode" == "true" ]]; then
572592
echo "❌ FATAL: $err_msg"
573593
else
574594
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: $err_msg"

backup.conf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# =================================================================
2-
# Configuration for rsync Backup Script v0.30
2+
# Configuration for rsync Backup Script v0.31
33
# =================================================================
44
# !! IMPORTANT !! Set file permissions to 600 (chmod 600 backup.conf)
55

@@ -31,6 +31,9 @@ BEGIN_SSH_OPTS
3131
/root/.ssh/id_ed25519
3232
END_SSH_OPTS
3333

34+
# Set RSYNC_NOATIME_ENABLED to true for a performance boost if rsync >= 3.3.0. Set to false for older versions (e.g., 3.2.7).
35+
RSYNC_NOATIME_ENABLED=false
36+
3437
# The timeout in seconds for rsync operations.
3538
RSYNC_TIMEOUT=300
3639

backup_script.sh

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
# ===================== v0.30 - 2025.08.13 ========================
2+
# ===================== v0.31 - 2025.08.13 ========================
33
#
44
# Example backup.conf:
55
# BACKUP_DIRS="/home/user/test/./ /var/www/./"
@@ -9,6 +9,8 @@
99
# LOG_RETENTION_DAYS=7
1010
# MAX_LOG_SIZE_MB=10
1111
# BANDWIDTH_LIMIT_KBPS=1000
12+
# RSYNC_NOATIME_ENABLED=false
13+
# Set RSYNC_NOATIME_ENABLED to true for rsync >= 3.3.0. Set to false for older versions (e.g., 3.2.7).
1214
# RSYNC_TIMEOUT=300
1315
# RECYCLE_BIN_ENABLED=true
1416
# RECYCLE_BIN_DIR="recycle_bin"
@@ -98,9 +100,8 @@ if [ -f "$CONFIG_FILE" ]; then
98100
value="${value%\"}"; value="${value#\"}"
99101

100102
case "$key" in
101-
BACKUP_DIRS|BOX_DIR|BOX_ADDR|LOG_FILE|LOG_RETENTION_DAYS|\
102-
MAX_LOG_SIZE_MB|BANDWIDTH_LIMIT_KBPS|RSYNC_TIMEOUT|\
103-
CHECKSUM_ENABLED|\
103+
BACKUP_DIRS|BOX_DIR|BOX_ADDR|LOG_FILE|LOG_RETENTION_DAYS|CHECKSUM_ENABLED|\
104+
MAX_LOG_SIZE_MB|BANDWIDTH_LIMIT_KBPS|RSYNC_TIMEOUT|RSYNC_NOATIME_ENABLED|\
104105
NTFY_ENABLED|DISCORD_ENABLED|NTFY_TOKEN|NTFY_URL|DISCORD_WEBHOOK_URL|\
105106
NTFY_PRIORITY_SUCCESS|NTFY_PRIORITY_WARNING|NTFY_PRIORITY_FAILURE|\
106107
RECYCLE_BIN_ENABLED|RECYCLE_BIN_DIR|RECYCLE_BIN_RETENTION_DAYS)
@@ -159,11 +160,15 @@ if (( ${#SSH_OPTS_ARRAY[@]} > 0 )); then
159160
fi
160161

161162
RSYNC_BASE_OPTS=(
162-
-aR -z --delete --partial --timeout="${RSYNC_TIMEOUT:-300}" --mkpath --noatime
163+
-aR -z --delete --partial --timeout="${RSYNC_TIMEOUT:-300}" --mkpath
163164
--exclude-from="$EXCLUDE_FILE_TMP"
164165
-e "$SSH_CMD"
165166
)
166167

168+
if [[ "${RSYNC_NOATIME_ENABLED:-false}" == "true" ]]; then
169+
RSYNC_BASE_OPTS+=(--noatime)
170+
fi
171+
167172
# Optional: Add bandwidth limit if configured
168173
if [[ -n "${BANDWIDTH_LIMIT_KBPS:-}" && "${BANDWIDTH_LIMIT_KBPS}" -gt 0 ]]; then
169174
RSYNC_BASE_OPTS+=(--bwlimit="$BANDWIDTH_LIMIT_KBPS")
@@ -266,6 +271,20 @@ run_preflight_checks() {
266271
done
267272
if [[ "$check_failed" == "true" ]]; then exit 10; fi
268273
if [[ "$test_mode" == "true" ]]; then printf "${C_GREEN}✅ All required commands are present.${C_RESET}\n"; fi
274+
# Check rsync version for --noatime compatibility if the feature is enabled
275+
if [[ "${RSYNC_NOATIME_ENABLED:-false}" == "true" ]]; then
276+
if [[ "$test_mode" == "true" ]]; then printf "${C_BOLD}--- Checking rsync version for --noatime...${C_RESET}\n"; fi
277+
local rsync_version
278+
rsync_version=$(rsync --version | head -n1 | awk '{print $3}')
279+
local major minor
280+
IFS='.' read -r major minor _ <<< "$rsync_version"
281+
if ! (( major > 3 || (major == 3 && minor >= 3) )); then
282+
printf "${C_RED}❌ FATAL: RSYNC_NOATIME_ENABLED is true but rsync version %s is too old.${C_RESET}\n" "$rsync_version" >&2
283+
printf "${C_DIM} The --noatime option requires rsync version 3.3.0 or newer.${C_RESET}\n" >&2
284+
exit 10
285+
fi
286+
if [[ "$test_mode" == "true" ]]; then printf "${C_GREEN}✅ rsync version %s supports --noatime.${C_RESET}\n" "$rsync_version"; fi
287+
fi
269288
if [[ "$test_mode" == "true" ]]; then printf "${C_BOLD}--- Checking SSH connectivity...${C_RESET}\n"; fi
270289
# Quick preflight connectivity "ping": short 10s timeout for fail-fast behaviour
271290
if ! ssh "${SSH_OPTS_ARRAY[@]}" -o BatchMode=yes -o ConnectTimeout=10 "$BOX_ADDR" 'exit' 2>/dev/null; then
@@ -292,7 +311,7 @@ run_preflight_checks() {
292311
fi
293312
if [[ "$dir" != *"/./"* ]]; then
294313
local err_msg="Directory '$dir' in BACKUP_DIRS is missing the required '/./' syntax."
295-
if [[ "$test_mode" == "true" ]]; then
314+
if [[ "$test_mode" == "true" ]]; then
296315
echo "❌ FATAL: $err_msg"
297316
else
298317
send_notification "❌ Backup FAILED: ${HOSTNAME}" "x" "${NTFY_PRIORITY_FAILURE}" "failure" "FATAL: $err_msg"

backup_script.sh.sha256

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
192650a55e70472ef23fdea13b0738cc259bdbb66ed10da6b8074131680acc2c backup_script.sh
1+
c86ad2b090ee73e7489315bad8650022943b1b5df57d64e84252e306b6d91750 backup_script.sh

0 commit comments

Comments
 (0)