Personal log of yet another digital native.
sudo apt update && sudo apt upgrade && sudo apt autoclean && sudo apt autoremovesudo apt install mergerfs snapraid -ylsblk -o NAME,SIZE,TYPE,FSTYPE,UUIDsudo parted /dev/sdX --script mklabel gpt mkpart primary ext4 0% 100%sudo mkfs.ext4 -O ^has_journal /dev/sdX1sudo mkdir -p /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/arraysudo blkidUUID=<uuid1> /mnt/disk1 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0
UUID=<uuid2> /mnt/disk2 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0
UUID=<uuid3> /mnt/disk3 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0
UUID=<uuid4> /mnt/disk4 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0
nofail → don’t break boot if a disk is slowx-systemd.device-timeout=10 → wait up to 10 seconds for USB spin‑upnoatime → reduces writes on HDDssudo mount -a/mnt/disk* /mnt/array fuse.mergerfs defaults,allow_other,use_ino,category.create=mfs,moveonenospc=true,minfreespace=10G,nofail 0 0sudo mount -a && df -hsudo systemctl daemon-reloadsudo mount -adf -hnano /etc/snapraid.conf (using snapraid.conf below)sudo touch /var/log/snapraid.log && sudo chmod 666 /var/log/snapraid.logln -s /var/log/snapraid.log ~/snapraid.logsudo nano /usr/local/bin/maintain.sh (using maintain.sh below)sudo chmod +x /usr/local/bin/maintain.shln -s /usr/local/bin/maintain.sh ~/maintain.sh (need sudo to run as non root)sudo crontab -e:
@reboot /usr/local/bin/snapraid-maint
0 */6 * * * /usr/local/bin/snapraid-maint
https://apt.syncthing.net/sudo curl -L -o /etc/apt/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpgecho "deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable-v2" | sudo tee /etc/apt/sources.list.d/syncthing.listsudo apt-get update && sudo apt-get install syncthingsudo systemctl enable syncthing@pi.servicesudo systemctl start syncthing@pi.servicesystemctl status syncthing@pi.servicecurl -fsSL https://tailscale.com/install.sh | shsudo tailscale up##############################################$
# SnapRAID configuration for Whitefall$
# Layout: 3 data disks + 1 parity disk$
##############################################$
$
# PARITY DISK$
parity /mnt/disk4/snapraid.parity$
$
# CONTENT FILES (redundant metadata)$
content /mnt/disk1/snapraid.content$
content /mnt/disk2/snapraid.content$
content /mnt/disk3/snapraid.content$
content /mnt/disk4/snapraid.content$
$
# DATA DISKS$
data disk1 /mnt/disk1$
data disk2 /mnt/disk2$
data disk3 /mnt/disk3$
$
# EXCLUDES (recommended)$
exclude *.tmp$
exclude *.bak$
exclude *.swp$
exclude *.DS_Store$
exclude Thumbs.db$
exclude .Trash*/$
exclude .recycle*/$
exclude .cache*/$
exclude .@__thumb*/$
exclude lost+found/$
$
# TUNING$
# Autosave prevents corruption if sync is interrupted$
autosave 100$
$
# Larger blocksize = fewer I/O ops on slow USB disks$
blocksize 256$
#!/bin/bash
# CONFIG
SYNC_DAYS=1
SCRUB_DAYS=14
LOG=/var/log/snapraid-maint.log
SNAPRAID=/usr/bin/snapraid
# Command-line overrides
FORCE_SYNC=false
FORCE_SCRUB=false
while [[ "$1" != "" ]]; do
case $1 in
--force-sync ) FORCE_SYNC=true ;;
--force-scrub ) FORCE_SCRUB=true ;;
esac
shift
done
format_elapsed() {
local seconds=$1
local days=$(( seconds / 86400 ))
local hours=$(( (seconds % 86400) / 3600 ))
local mins=$(( (seconds % 3600) / 60 ))
local out=""
# Only print days if > 0
[ $days -gt 0 ] && out="${out}${days}d "
# Only print hours if > 0
[ $hours -gt 0 ] && out="${out}${hours}h "
# Only print minutes if > 0 OR if nothing else printed
if [ $mins -gt 0 ] || [ -z "$out" ]; then
out="${out}${mins}m"
fi
echo "${out%" "}"
}
# Show quick usage help only when run interactively
if [ -t 1 ]; then
echo "Usage: $0 [--force-sync] [--force-scrub]"
fi
# Start
echo "=== SnapRAID maintenance $(date) ===" | tee -a "$LOG"
# Wait for disks to mount at boot (max 50 seconds)
for i in {1..10}; do
if mountpoint -q /mnt/disk1; then
break
fi
sleep 5
done
# Ensure disks are mounted
for d in /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4; do
if ! mountpoint -q "$d"; then
echo "Disk $d not mounted, aborting." | tee -a "$LOG"
exit 1
fi
done
# Extract last sync timestamp safely
LAST_SYNC=$($SNAPRAID status | grep "Sync finished" | sed 's/.*: //')
LAST_SYNC_TS=$(date -d "$LAST_SYNC" +%s 2>/dev/null)
NOW_TS=$(date +%s)
# If no sync has ever run
if [ -z "$LAST_SYNC_TS" ]; then
echo "No previous sync found — running initial sync." | tee -a "$LOG"
$SNAPRAID sync 2>&1 | tee -a "$LOG"
exit 0
fi
# Time calculations
SYNC_AGE=$(( NOW_TS - LAST_SYNC_TS ))
SYNC_AGE_FMT=$(format_elapsed $SYNC_AGE)
SYNC_INTERVAL=$(( SYNC_DAYS * 86400 ))
SYNC_REMAIN=$(( SYNC_INTERVAL - SYNC_AGE ))
SYNC_REMAIN_FMT=$(format_elapsed $SYNC_REMAIN)
if $FORCE_SYNC; then
echo "Forcing sync (override flag)." | tee -a "$LOG"
$SNAPRAID sync 2>&1 | tee -a "$LOG"
elif [ $SYNC_AGE -ge $SYNC_INTERVAL ]; then
echo "Last sync: $SYNC_AGE_FMT ago — running sync." | tee -a "$LOG"
$SNAPRAID sync 2>&1 | tee -a "$LOG"
else
echo "Last sync: $SYNC_AGE_FMT ago — next sync in $SYNC_REMAIN_FMT (every $(format_elapsed $((SYNC_DAYS * 86400))))." | tee -a "$LOG"
fi
# Scrub timestamp
LAST_SCRUB=$($SNAPRAID status | grep "Scrub finished" | sed 's/.*: //')
LAST_SCRUB_TS=$(date -d "$LAST_SCRUB" +%s 2>/dev/null)
if [ -z "$LAST_SCRUB_TS" ]; then
echo "No previous scrub found — running scrub." | tee -a "$LOG"
$SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"
exit 0
fi
# Time calculations
SCRUB_AGE=$(( NOW_TS - LAST_SCRUB_TS ))
SCRUB_AGE_FMT=$(format_elapsed $SCRUB_AGE)
SCRUB_INTERVAL=$(( SCRUB_DAYS * 86400 ))
SCRUB_REMAIN=$(( SCRUB_INTERVAL - SCRUB_AGE ))
SCRUB_REMAIN_FMT=$(format_elapsed $SCRUB_REMAIN)
if $FORCE_SCRUB; then
echo "Forcing scrub (override flag)." | tee -a "$LOG"
$SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"
elif [ $SCRUB_AGE -ge $SCRUB_INTERVAL ]; then
echo "Last scrub: $SCRUB_AGE_FMT ago — running scrub." | tee -a "$LOG"
$SNAPRAID scrub -p 10 2>&1 | tee -a "$LOG"
else
echo "Last scrub: $SCRUB_AGE_FMT ago — next scrub in $SCRUB_REMAIN_FMT (every $(format_elapsed $((SCRUB_DAYS * 86400))))." | tee -a "$LOG"
fi
# End
END_LINE="=== SnapRAID maintenance END $(date) ==="
echo "$END_LINE" | tee -a "$LOG"
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
# SnapRAID: burst mode after boot (0, 5, 10, 15 minutes)
@reboot sleep 0 && /usr/local/bin/snapraid-maint
@reboot sleep 300 && /usr/local/bin/snapraid-maint
@reboot sleep 600 && /usr/local/bin/snapraid-maint
@reboot sleep 900 && /usr/local/bin/snapraid-maint
# SnapRAID: steady-state (every 30 minutes)
*/30 * * * * /usr/local/bin/snapraid-maint
proc /proc proc defaults 0 0$
PARTUUID=7e4022c3-01 /boot/firmware vfat defaults 0 2$
PARTUUID=7e4022c3-02 / ext4 defaults,noatime 0 1$
UUID=15d0b85a-9a5b-4976-9314-6c9519bc595f /mnt/disk1 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0$
UUID=93933b41-30b6-4ee1-aaa0-76f3a7ad68d6 /mnt/disk2 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0$
UUID=272b6924-a2b6-4e05-9cfe-502db41f8501 /mnt/disk3 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0$
UUID=809dfe56-65e2-4aef-a952-0e1284daa6a0 /mnt/disk4 ext4 defaults,noatime,nofail,x-systemd.device-timeout=10 0 0$
/mnt/disk1:/mnt/disk2:/mnt/disk3 /mnt/array fuse.mergerfs defaults,allow_other,use_ino,category.create=mfs,moveonenospc=true,minfreespace=10G,nofail 0 0$