rsnapshot backup dual-configuration for Linux and Windows (via WSL) filesystems
  • Assembly 57.8%
  • C++ 14.3%
  • Shell 8.2%
  • Pascal 7%
  • PHP 6.8%
  • Other 5.9%
Find a file
2026-07-12 10:47:29 -07:00
conf initial commit 2026-06-07 11:28:31 -07:00
cron.d switch from cron to systemd timers; update README 2026-06-14 09:26:34 -07:00
excludes update Windows excludes; add AI-generated exclude example snippets in excludes/ 2026-06-08 08:02:18 -07:00
systemd update README; improve excludes-windows.inc; update rsnapshot-report.sh; improve systemd timer timing to work with logrotate 2026-07-12 10:47:29 -07:00
cp_rsnapshot_wrapper.sh initial commit 2026-06-07 11:28:31 -07:00
default.inc initial commit 2026-06-07 11:28:31 -07:00
excludes-windows.inc update README; improve excludes-windows.inc; update rsnapshot-report.sh; improve systemd timer timing to work with logrotate 2026-07-12 10:47:29 -07:00
excludes.inc rename rsnapshot-linux.conf to rsnapshot.conf; rname exclude-linux.inc to excludes.inc; rename exclude-windows.inc to excludes-windows.inc; remove -V switch in cron jobs; rsnapshot-report.sh: only show summary, errors, and/or warnings 2026-06-14 08:32:19 -07:00
README.md update README; improve excludes-windows.inc; update rsnapshot-report.sh; improve systemd timer timing to work with logrotate 2026-07-12 10:47:29 -07:00
rsnapshot-report.sh update README; improve excludes-windows.inc; update rsnapshot-report.sh; improve systemd timer timing to work with logrotate 2026-07-12 10:47:29 -07:00
rsnapshot-windows.conf rename systemd timers and units to be more consistent; change PID names to be more consistent and update PID location 2026-06-16 08:55:00 -07:00
rsnapshot.conf rename systemd timers and units to be more consistent; change PID names to be more consistent and update PID location 2026-06-16 08:55:00 -07:00

rsnapshot Dual Backup: Linux Filesystems and Windows Filesystems via WSL

This is a dual rsnapshot configuration. The two configurations are for:

  1. Linux filesystems

    • note: files in the WSL Linux filesystem should be transferred here
    • for example: /home, /etc, /usr/local, etc.
  2. Windows filesystems

    • for tranferring Windows filesystem files via WSL
    • for example, anything under /mnt/c, /mnt/d, etc.

What is rsnapshot?

In case you don't know what rsnapshot is, it is a rotating incremental backup system. It performs daily backups and every day a new backup is created it rotates the previous ones. The current day's backup is daily.0. The day before's is daily.1, and so on. At the end of a week you end up with weekly.0. Every week these get rotated so you end up with weekly.1, weekly.2, etc. The same thing goes for months: monthly.0, monthly.1, monthly.2, etc.

I can't tell you how many times having backups has saved my skin. Operating information appliances always involves a certain level of risk that some important data or files may inadvertently become deleted.

It gives great peace of mind to know that you have not just a backup, but literally a series of daily backups going back a full week, and then weekly and monthly backups going back even further.

The backup storage is efficient because instead of creating completely new files on disk, for files that are unchanged from previous backups it creates hard links.

Restoration is as simply as copying files back into place.

I choose to use rsnapshot because it is solid and tested, and based on purely free and Open-Source technologies, which every good tool should be.

Notes

  • My backup filesystem is BTRFS and is mounted under /mnt/lback on my backup server
  • Because of this I'm using a custom cp wrapper cp_rsnapshot_wrapper.sh

Prerequisites

  • rsnapshot installed
  • SSH as root user must work from backup server to all targets
  • I personally recommend using WSL in mirrored networking mode and either disabling Windows native OpenSSH altogether (it's pretty useless), or else changing its port to not interfere with WSL SSH
  • If you use WSL NAT networking mode you would need to set up SSH proxy to go through Windows SSH -> WSL SSH

Vim modeline

rsnapshot configuration files require tabs between options and their values/arguments

To make life easier, this Vim modeline displays tabs as >- characters so you can visualize tabs in the configuration files:

# vim:syntax=conf:noexpandtab:ts=2:softtabstop=2:list:listchars=tab\:>-:

Testing rsnapshot

rsnapshot [-c /path/to/config] configtest
rsnapshot [-c /path/to/config] -t daily

Filesystem Structure

Configuration files are under /etc/rsnapshot

/etc/rsnapshot
├── default.inc
├── excludes.inc
├── excludes-windows.inc
├── rsnapshot.conf
└── rsnapshot-windows.conf

/etc/systemd/system
├── rsnapshot-daily.service
├── rsnapshot-daily.timer
├── rsnapshot-monthly.service
├── rsnapshot-monthly.timer
├── rsnapshot-weekly.service
├── rsnapshot-weekly.timer
├── rsnapshot-windows-daily.service
├── rsnapshot-windows-daily.timer
├── rsnapshot-windows-monthly.service
├── rsnapshot-windows-monthly.timer
├── rsnapshot-windows-weekly.service
├── rsnapshot-windows-weekly.timer

/etc/cron.d
└── rsnapshot

/usr/local/bin/
├── cp_rsnapshot_wrapper.sh
├── rsnapshot-report.sh

NOTE: The conf directory contains Debian default files for reference. The excludes directory contains some example AI-generated excludes.

systemd timers

copy the .service and .timer files into place, then:

systemctl daemon-reload

for t in rsnapshot-daily rsnapshot-weekly rsnapshot-monthly \
          rsnapshot-windows-daily rsnapshot-windows-weekly; do
  systemctl enable --now ${t}.timer
done

rsnapshot-report.sh

This is a custom e-mail report generator created by Claude.ai that works better than rsnapreport.pl. It should be placed in /usr/local/bin and made executable.

chmod +x /usr/local/bin/rsnapshot-report.sh

Note: Check your logs to examine the datestamps at line beginnings. Make sure the date field separator character is the same as those in this line:

# hyphen separators:
TODAY="$(date '+%Y-%m-%d')"

# slash separators:
TODAY="$(date '+%Y/%m/%d')"

Use the one that corresponds with the date field separators in your rsnapshot log files.

Log files

mkdir /var/log/rsnapshot
touch /var/log/rsnapshot/rsnapshot.log
touch /var/log/rsnapshot/rsnapshot-windows.log

/etc/logrotate.d/rsnapshot

/var/log/rsnapshot/rsnapshot.log {
    daily
    create 640 root adm
        rotate 12
    dateext
    dateformat -%Y-%m-%d
    notifyempty
}
/var/log/rsnapshot/rsnapshot-windows.log {
    daily
    create 640 root adm
        rotate 12
    dateext
    dateformat -%Y-%m-%d
    notifyempty
}

Invoking manually

It's recommended to run rsnapshot sync and rsnapshot daily manually the first time or even several times in order to check for errors and verify that it's running smoothly before enabling cron.

You should see daily.0, daily.1, etc. in your backup directory for every time you run it. Inspect the logs during/after running it and look for critical errors. Some files failing to transfer due to permission issues are not critical errors.

If manually invoking via remote shell session it's also recommended to use tmux session to gracefully handle any disconnects:

# in first window:
tail -F /var/log/rsnapshot/rsnapshot.log
# then:
tail -F /var/log/rsnapshot/rsnapshot-windows.log

# in second window:
tmux new -s rsnapshot

# 3 possible ways to manually run:

## 1. Run and generate email report
sudo sh -c '(rsnapshot -c /etc/rsnapshot/rsnapshot.conf sync && rsnapshot -V -c /etc/rsnapshot/rsnapshot.conf daily); /usr/local/bin/rsnapshot-report.sh -l daily -t Linux -f /var/log/rsnapshot/rsnapshot.log'
sudo sh -c '(rsnapshot -V -c /etc/rsnapshot/rsnapshot-windows.conf sync && rsnapshot -V -c /etc/rsnapshot/rsnapshot-linux.conf daily); /usr/local/bin/rsnapshot-report.sh -l daily -t Linux -f /var/log/rsnapshot/rsnapshot-windows.log'

## 2. Create output suitable for parsing errors & warnings
sudo rsnapshot -V -c /etc/rsnapshot/rsnapshot.conf sync 2>&1 | grep -i "error\|warning\|cannot\|failed\|skip" | head -50
sudo rsnapshot -V -c /etc/rsnapshot/rsnapshot-windows.conf sync 2>&1 | grep -i "error\|warning\|cannot\|failed\|skip" | head -50

## 3. Or just simply:
sudo sh -c 'rsnapshot -c /etc/rsnapshot/rsnapshot.conf sync'
sudo sh -c 'rsnapshot -c /etc/rsnapshot/rsnapshot.conf daily'
sudo sh -c 'rsnapshot -c /etc/rsnapshot/rsnapshot-windows.conf sync'
sudo sh -c 'rsnapshot -c /etc/rsnapshot/rsnapshot-windows.conf daily'

Ctrl-b-d detaches the tmux session tmux attach -t rsnapshot reattaches it

Excludes

  • excludes contained in separate files for convenience

It is recommended to use AI to help generate excludes.

For example you can ask Claude.ai "Please generate rsnapshot excludes for Android Studio, Vivaldi, VMware, and Hyper-V". It seems this is one thing AI seems to be able to handle well without any errors nor weirdness, but of course always double-check the results.

You can also feed Claude your log files and ask it to generate excludes based on any errors it parses. It's common for some files to fail to transfer due to permission issues. These files are usually unnecessary and should be excluded.

Honing Excludes

cd /mnt/c/Users/<user>/AppData/Roaming
for d in */; do
  echo "$(find "$d" -type f | wc -l) $d"
done | sort -rn | head -30

# go two levels deep into each of top directories and show biggest file-count subfolders
cd /mnt/c/Users/dhya/AppData/Roaming
for top in Zoom "Telegram Desktop" Kodi NVIDIA Adobe Google Code uv JetBrains Slack MediaMonkey5 LibreOffice Microsoft Steinberg Figma ZoiteChat Thunderbird Claude Ableton; do
  echo "=== $top ==="
  find "$top" -mindepth 1 -maxdepth 2 -type d 2>/dev/null | while read -r d; do
    n=$(find "$d" -maxdepth 1 -type f 2>/dev/null | wc -l)
    [ "$n" -gt 0 ] && echo "$n $d"
  done | sort -rn | head -5
  echo
done