Btrbk incremental snapshots to external usb - nutthawit/alpine-dotfile GitHub Wiki
Automatically make incremental Btrfs snapshots to the thumb drive for external backup.
In this section, we will create udev rules to automatically make incremental Btrfs snapshots to the thumb drive when it is plugged in.
Udev rule mount USB drive automatically
Format the thump drive to btrfs (assume you thumb drive mount on /dev/sda)
DISK=/dev/sda
USB=/dev/sda1
alias p="parted -sa optimal ${DISK}"
p mklabel gpt
p mkpart p 0G 100%
mkfs.btrfs -f -L btr_backup -n 32k ${USB}The -L option is just a label, which you are free to change.
Prepare directory for store snapshots. We will use /mnt/btr_backup as the path to mount the thumb drive when it is plugged in.
BACKUP=/mnt/btr_backup
mkdir ${BACKUP}
mount ${USB} ${BACKUP} -t btrfs -o rw,subvolid=5
mkdir "${BACKUP}/x509fa"
mkdir "${BACKUP}/lat3430"Note
I created two separate directories inside the thumb drive to separate the backups for my Asus and Dell laptops.
Create btrbk configure file that target to usb
cat << EOF > /etc/btrbk/btrbk-usb.conf
# Snapshot to usb
compat busybox
timestamp_format long
snapshot_dir /mnt/btr_pool/btrbk_snapshots
subvolume /mnt/btr_pool/@
target /mnt/btr_backup/x509fa
EOFtarget is directory where the backup subvolumes are to be created. read more on man 5 btrbk.conf
Install eudev
apk add eudev eudev-docCreate udev rule
cat << EOF > /etc/udev/rules.d/10-usb-automount.rules
SUBSYSTEM=="block", ATTRS{idVendor}=="0951", ACTION=="add", RUN+="/usr/local/bin/btrbk-create-incremental-backup-to-usb"
EOFIf you never create a udev rule before, you can start by this article
Note
0951 is Kingston vendor ID
Create a dependencies script named get-kingston-usb-node. This script will return /dev/sdXY when I plug in the Kingston USB drive that I use to store the backup.
cat << EOF > /usr/local/bin/get-kingston-usb-node
#!/bin/ash
# This should be return: sdXY
KINGSTON_SDA_CMD=$(ls -l /dev/disk/by-label/ | awk '{print $NF}' | grep sda | sed 's|^../../||')
echo /dev/${KINGSTON_SDA_CMD}
# Exit with the status of the last executed command (optional, but good practice)
exit $?
EOF
chmod +x /usr/local/bin/get-kingston-usb-nodeLastly, create a script that called by udev rule
cat << EOF > /usr/local/bin/btrbk-create-incremental-backup-to-usb
#!/bin/ash
# Mount Kingston usb to backup path
mount $(/usr/local/bin/get-kingston-usb-node) /mnt/btr_backup -t btrfs -o rw,subvolid=5
# Create incremental backup to usb
exec /usr/bin/btrbk -c /etc/btrbk/btrbk-usb.conf -q run
EOF
chmod +x /usr/local/bin/btrbk-create-incremental-backup-to-usbRestart udev and test rule by:
udevadm control --reload
udevadm test /dev/sda1
calling: test
version 3.2.14
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.
does not exist, please run udevadm hwdb --update
Load module index
timestamp of '/etc/udev/rules.d' changed
Reading rules file: /etc/udev/rules.d/10-usb-automount.rules
Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules
Reading rules file: /usr/lib/udev/rules.d/60-autosuspend.rules
Reading rules file: /usr/lib/udev/rules.d/60-block.rulesCounting backward from the end of the output to line 4, you will see that your rule is being read without error.
Now unplug your thumb drive, and reboot a Linux machine.
When your system is back online, plug in your thumb drive and run following command:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 115.2G 0 disk
└─sda1 8:1 1 115.2G 0 part /mnt/btr_backupYou should see /dev/sda1 mounted at /mnt/btr_backup.
Now if you look at /mnt/btr_backup/x509fa you will see the same number of snapshots as in /mnt/btr_pool/btrbk_snapshots.
ls /mnt/btr_backup/x509fa/
@.20250928T2345 @.20250929T0830 @.20250929T1000 @.20250929T1130 @.20250929T1300 @.20250929T1430 @.20250929T1445_1 @.20250929T1454 @.20250929T2035
@.20250929T0000 @.20250929T0900 @.20250929T1030 @.20250929T1200 @.20250929T1330 @.20250929T1441 @.20250929T1446 @.20250929T1454_1 @.20250929T2035_1
@.20250929T0800 @.20250929T0930 @.20250929T1100 @.20250929T1230 @.20250929T1400 @.20250929T1445 @.20250929T1447 @.20250929T1454_2
ls /mnt/btr_pool/btrbk_snapshots/
@.20250929T0800 @.20250929T1000 @.20250929T1200 @.20250929T1330 @.20250929T1430 @.20250929T1445 @.20250929T1446 @.20250929T1454 @.20250929T1454_2 @.20250929T2035_1
@.20250929T0900 @.20250929T1100 @.20250929T1300 @.20250929T1400 @.20250929T1441 @.20250929T1445_1 @.20250929T1447 @.20250929T1454_1 @.20250929T2035 @.20250929T2100Important
This incremental process may take time, depending on the number of your snapshots. You should wait until the last snapshot is received, which you can notice when the name of the last snapshot in the backup directory is the same as the one in the local snapshot directory.
Notice that my backup (/mnt/btr_backup/x509fa) has more snapshots than the local snapshots because my local snapshots are cleaned according to the configuration in /etc/btrbk/btrbk.conf.
Backup both local and USB while USB is plugged
Currently, when you plug in the USB drive, udev executes only once. This means that snapshots are taken to both local storage and the USB drive only one time when the drive is plugged in. If you wish to take snapshots to both local storage and the USB drive repeatedly while the USB is connected, you need to update the btrbk cron job (/etc/periodic/30min/btrbk) like this:
#!/bin/sh
# If /mnt/btr_backup is mounted do backup to local and usb
if mountpoint -q /mnt/btr_backup; then
exec /usr/bin/btrbk -c /etc/btrbk/btrbk-usb.conf -q run
else
exec /usr/bin/btrbk -q run
fiRestart crond
rc-service crond restartRestore backup
Btrbk does not provide any mechanism to restore your backups, this has to be done manually. In the instructions below, we assume that you have a btrfs volume mounted at /mnt/btr_pool, and the subvolume you want to restore is at /mnt/btr_pool/@.
Identify Subvolume
# list snapshots managed by btrbk
btrbk list snapshots
# alternative: list all subvolumes
btrbk ls /
btrbk ls -L /Restore Backup
# copy snapshots from local mounted backup drive
btrfs send /mnt/btr_backup/x509fa/@.20250928T2345 | btrfs receive /mnt/btr_pool/
# move (don't remove) current root subvolume away
mv /mnt/btr_pool/@ /mnt/btr_pool/@.CURRENT
# create read-write subvolume
btrfs subvolume snapshot /mnt/btr_pool/@.20250928T2345 /mnt/btr_pool/@Reboot a machine
- When USB is plugged, create dialog with 2 options, 1 for snapshot immediately with take name as argument, 2 select local snapshot that you want to send to usb