Btrfs
2024-10-24
Create systemd.mount unit for Btrfs on external HDD
internet_archive is used here as an example.
Get the UUID of the Btrfs partition.
sudo blkid -s UUID -o value /dev/sda1
d3b5b724-a57a-49a5-ad1d-13ccf3acc52f
Edit ~/etc/systemd/system/mnt-internet_archive.mount.
[Unit]
Description=internet_archive Btrfs subvolume
DefaultDependencies=yes
[Mount]
What=/dev/disk/by-uuid/d3b5b724-a57a-49a5-ad1d-13ccf3acc52f
Where=/mnt/internet_archive
Type=btrfs
Options=subvol=@internet_archive,compress=zstd:1
[Install]
WantedBy=multi-user.target
DefaultDependencies=yes
: The mount unit automatically acquiresBefore=umount.target
andConflicts=umount.target
. Local filesystems automatically gainAfter=local-fs-pre.target
andBefore=local-fs.target
. Network mounts, such as NFS, automatically acquireAfter=remote-fs-pre.target network.target network-online.target
andBefore=remote-fs.target
.Options=subvol=@internet_archive,compress=zstd:1
: Use the subvolume@internet_archive
and use zstd compression level 1.
Note that the name of the unit file, e.g.
mnt-internet_archive.mount
, must correspond to theWhere=/mnt/internet_archive
directive, such that the filesystem path separator / in theWhere
directive is replaced by an en dash in the unit file name.
Reload the daemons and enable the mount unit.
sudo systemctl daemon-reload
sudo systemctl enable --now mnt-internet_archive.mount
Setup encrypted external drive for backups
Prepare the external drive
sudo cryptsetup --type luks2 -y -v luksFormat /dev/sda1
sudo cryptsetup -v luksOpen /dev/sda1 cryptbackup
sudo mkfs.btrfs /dev/mapper/cryptbackup
sudo mkdir /srv/backup
sudo mount -o noatime,compress=zstd:1 /dev/mapper/cryptbackup /srv/backup
sudo restorecon -Rv /srv/backup
Setup /etc/crypttab
sudo blkid -s UUID -o value /dev/sda1 | sudo tee -a /etc/crypttab
Add the following line to /etc/crypttab
:
cryptbackup UUID=<UUID of /dev/sda1> none discard
Setup /etc/fstab
sudo blkid -s UUID -o value /dev/mapper/cryptbackup | sudo tee -a /etc/fstab
Add the following line to /etc/fstab
:
UUID=<UUID of /dev/mapper/cryptbackup> /srv/backup btrfs compress=zstd:1,nofail 0 0
Reload the daemons:
sudo systemctl daemon-reload
Mount the filesystems:
sudo mount -av
btrfs-backup script
#!/usr/bin/env bash
LOGFILE="/var/log/btrfs-backup.log"
SNAP_DATE=$(date '+%Y-%m-%d_%H%M%S')
# Check if device is mounted
if ! grep "/srv/backup" /etc/mtab >/dev/null; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup device is not mounted." | tee -a "$LOGFILE"
notify-send -i computer-fail "Backup device is not mounted"
exit 1
fi
create_snapshot() {
if ! btrfs subvolume snapshot -r "$1" "${1}/.snapshots/$2-$SNAP_DATE" >/dev/null; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error creating snapshot of $1" | tee -a "$LOGFILE"
notify-send -i computer-fail "Error creating snapshot of $1"
exit 1
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Create snapshot of $1: OK" | tee -a "$LOGFILE"
fi
}
send_snapshot() {
mkdir -p "/srv/backup/$SNAP_DATE"
if ! btrfs send -q "${1}/.snapshots/$2-$SNAP_DATE" | btrfs receive -q "/srv/backup/$SNAP_DATE"; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error sending snapshot of $1 to /srv/backup" | tee -a "$LOGFILE"
notify-send -i computer-fail "Error sending snapshot of $1 to /srv/backup"
exit 1
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Send snapshot of $1 to /srv/backup: OK" | tee -a "$LOGFILE"
fi
}
# Create root and home snapshots
create_snapshot "/" "root"
create_snapshot "/home" "home"
# Send root and home snapshots
send_snapshot "/" "root"
send_snapshot "/home" "home"
Move/copy the script to /etc/cron.daily/btrfs-backup
.