hyperreal.coffee

Create systemd.mount unit for Btrfs on external HDD

Get the UUID of the Btrfs partition:

1sudo blkid -s UUID -o value /dev/sda1
2
3d3b5b724-a57a-49a5-ad1d-13ccf3acc52f

Edit /etc/systemd/system/mnt-internet_archive.mount:

 1[Unit]
 2Description=internet_archive Btrfs subvolume
 3DefaultDependencies=yes
 4
 5[Mount]
 6What=/dev/disk/by-uuid/d3b5b724-a57a-49a5-ad1d-13ccf3acc52f
 7Where=/mnt/internet_archive
 8Type=btrfs
 9Options=subvol=@internet_archive,compress=zstd:1
10
11[Install]
12WantedBy=multi-user.target
DefaultDependencies=yesThe mount unit automatically acquires Before=umount.target and Conflicts=umount.target. Local filesystems automatically gain After=local-fs-pre.target and Before=local-fs.target. Network mounts, such as NFS, automatically acquire After=remote-fs-pre.target network.target network-online.target and Before=remote-fs.target.
Options=subvol=@internet_archive,compress=zstd:1Use 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 the Where=/mnt/internet_archive directive, such that the filesystem path separator / in the Where directive is replaced by an en dash in the unit file name.

Reload the daemons and enable the mount unit:

1sudo systemctl daemon-reload
2sudo systemctl enable --now mnt-internet_archive.mount

Setup encrypted external drive for backups

Prepare the external drive

1sudo cryptsetup --type luks2 -y -v luksFormat /dev/sda1
2sudo cryptsetup -v luksOpen /dev/sda1 cryptbackup
3sudo mkfs.btrfs /dev/mapper/cryptbackup
4sudo mkdir /srv/backup
5sudo mount -o noatime,compress=zstd:1 /dev/mapper/cryptbackup /srv/backup
6sudo restorecon -Rv /srv/backup

Setup /etc/crypttab

1sudo blkid -s UUID -o value /dev/sda1 | sudo tee -a /etc/crypttab

Add the following line to /etc/crypttab:

1cryptbackup UUID=<UUID of /dev/sda1> none discard

Setup /etc/fstab

1sudo blkid -s UUID -o value /dev/mapper/cryptbackup | sudo tee -a /etc/fstab

Add the following line to /etc/fstab:

1UUID=<UUID of /dev/mapper/cryptbackup> /srv/backup btrfs compress=zstd:1,nofail 0 0

Reload the daemons:

1sudo systemctl daemon-reload

Mount the filesystems:

1sudo mount -av

Btrfs backup script

 1#!/usr/bin/env bash
 2
 3LOGFILE="/var/log/btrfs-backup.log"
 4SNAP_DATE=$(date '+%Y-%m-%d_%H%M%S')
 5
 6# Check if device is mounted
 7if ! grep "/srv/backup" /etc/mtab >/dev/null; then
 8    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Backup device is not mounted." | tee -a "$LOGFILE"
 9    notify-send -i computer-fail "Backup device is not mounted"
10    exit 1
11fi
12
13create_snapshot() {
14    if ! btrfs subvolume snapshot -r "$1" "${1}/.snapshots/$2-$SNAP_DATE" >/dev/null; then
15        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error creating snapshot of $1" | tee -a "$LOGFILE"
16        notify-send -i computer-fail "Error creating snapshot of $1"
17        exit 1
18    else
19        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Create snapshot of $1: OK" | tee -a "$LOGFILE"
20    fi
21}
22
23send_snapshot() {
24    mkdir -p "/srv/backup/$SNAP_DATE"
25    if ! btrfs send -q "${1}/.snapshots/$2-$SNAP_DATE" | btrfs receive -q "/srv/backup/$SNAP_DATE"; then
26        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Error sending snapshot of $1 to /srv/backup" | tee -a "$LOGFILE"
27        notify-send -i computer-fail "Error sending snapshot of $1 to /srv/backup"
28        exit 1
29    else
30        echo "[$(date '+%Y-%m-%d %H:%M:%S')] Send snapshot of $1 to /srv/backup: OK" | tee -a "$LOGFILE"
31    fi
32}
33
34# Create root and home snapshots
35create_snapshot "/" "root"
36create_snapshot "/home" "home"
37
38# Send root and home snapshots
39send_snapshot "/" "root"
40send_snapshot "/home" "home"

Move/copy the script to /etc/cron.daily/btrfs-backup.

Reply to this post by email ↪