I’m looking for a simple setup which will take daily snapshots of /home and then send those snapshots to a second drive, keeping exactly a month’s worth. I already have an online backup solution; this would primarily be for convenience in the event of drive failure or quickly grabbing a file I deleted by mistake.
Most of the things I’ve looked at have what seems like extra complexity for my use case.
I started with btrbk, because that’s packaged in Fedora, but it has instructions which start like with In this example, we assume you have a laptop with a disk having a btrfs root subvolume (subvolid=5) mounted on /mnt/btr_pool…. and that doesn’t seem like the setup we have in Fedora Workstation by default. And it seems really geared for backup to remote systems, which is great and all but not what I need.
Maybe this can all be done with a simple shell script run nightly from cron? I looked at the btrfs subvolume snapshot, btrfs send and btrfs receive commands, which seem to be the basic building blocks for what I want, but they’re really short on examples. Is there a place I can find good ones?
The program timeshift looks a lot like what I want, except it is focused entirely on system partitions and doesn’t do user data, which is the opposite of what I want.
A variation on the above article that I use is putting the snapshots in the “top-level” of the file system. I do this just for organizational reasons, it keeps the snapshots out of the /home search path where otherwise they affect find, locate, and du commands.
For example (sudo implied):
mount /dev/sdXY /mnt/internal
cd /mnt/internal
ls -l
By default you’ll see what looks like two directories, root and home but these are actually subvolumes.
btrfs sub snap -r home home.20210122
The convention I’m using is anything with a date stamp is a read-only snapshot. You can certainly make this a one-shot systemd service and associate it with a timer unit for once per day or per hour.
Just like in the article, but with my own naming convention. This assumes the home.20210121 snapshot is already on the destination. The initial send/receive is described in the article.
To restore individual files, you can just copy them out of the backup using the file manager. There’s nothing special about the files or snapshots in this regard.
You could use this template (it is missing your time limit setting) as a baseline.
#!/usr/bin/env bash
# Needs to be run with sudo
if [ "$EUID" -ne 0 ]; then
echo "This script needs to be run with sudo or as a root user"
exit 1
fi
LOCALSNAPSHOTSDIR="/.snapshots"
EXTERNALSNAPSHOTSDIR="/run/media/btrfs_formatted_drive"
LATEST_HOME=(`ls -d $LOCALSNAPSHOTSDIR/home-* | sort | tail -c 9`)
LATEST_HOME_EXTERNAL=(`ls -d $EXTERNALSNAPSHOTSDIR/home-* | sort | tail -c 9`)
TODAY=`date +%Y%m%d`
# make local snapshot
if test -d "$LOCALSNAPSHOTSDIR"; then
echo "Using directory $LOCALSNAPSHOTSDIR for local snapshots."
if [[ $LATEST_HOME -ne $TODAY ]]; then
echo "Today is $TODAY and latest home backup was $LATEST_HOME doing new snapshot"
btrfs subvolume snapshot -r /home $LOCALSNAPSHOTSDIR/home-$TODAY
else
echo "Todays backup already done"
fi
fi
# make an external backup of the snapshot
# destination drive needs to be formatted as BTRFS !
if test -d "$EXTERNALSNAPSHOTSDIR"; then
echo "using directory $EXTERNALSNAPSHOTSDIR for external backup."
if [[ $LATEST_HOME_EXTERNAL -ne $TODAY ]]; then
echo "Today is $TODAY and latest external backup is $LATEST_HOME_EXTERNAL copying data to external drive"
# Update using latest external backup-date as reference to do the differential backup against
btrfs send -p $LOCALSNAPSHOTSDIR/home-$LATEST_HOME_EXTERNAL $LOCALSNAPSHOTSDIR/home-$TODAY | btrfs receive $EXTERNALSNAPSHOTSDIR
else
if test -f "$EXTERNALSNAPSHOTSDIR/home-$TODAY"; then
echo "External backup already up to date"
else
echo "Earlier versions not found, creating the first external backup to $EXTERNALSNAPSHOTSDIR"
btrfs send $LOCALSNAPSHOTSDIR/home-$TODAY | btrfs receive $EXTERNALSNAPSHOTSDIR
fi
fi
else
echo "External drive not found, is it mounted?"
fi
Timeshift can backup the user data (/home) folder, but it is not enabled by default. You also have to change your mounting points on the file system to be in line with Ubuntu’s method. I followed this guide to change my mounting points and regenerate the grub2 efi boot.
I don’t have an encrypted filesystem, so I didn’t need to mount LUKS like the writer of the article did. I just mounted the SATA (/dev/sda1) partition in /btrfs_pool and changed the fstab to reflect the new mounting points, while being more SSD friendly.
I know that Timeshift can be set to also include the home folder. I am thinking that is not set by default for size consideration, and making sure as much as your configuration as possible is what is saved. Though I don’t want to claim to know for sure on that front. I know a few of the “easy Arch” based distros come with it automatically, and you just need to change those settings.