#!/bin/bash -e BTRFS_VOLUMES=${BTRFS_VOLUMES:-$(awk '!/^#/ && $3=="btrfs" {print $2}' /etc/fstab | tr '\n' ' ' | sed 's, $,,')} TMP_MNT=${TMP_MNT:-/var/tmp/btrfs-backup} vols=() del= dryrun=0 while test $# -gt 0; do case "$1" in (-h|--help) cat < add a path that contains a btrfs (sub-) volume (defaults to: ${BTRFS_VOLUMES}) -m, --mnt temporary mount point (default: ${TMP_MNT}) not yet implemented: -d, --del delete snapshots older than given number of days ENVIRONMENT BTRFS_VOLUMES specify all volume pathes (instead of -p) TMP_MNT temporary mount point (instead of -m) DESCRIPTION Creates a snapshot for all btrfs volumes specified. Snapshot is named from the subvol name or if there is no subvol, from the path by appending -snapshot-YYYY-MM-DD-HH-mm. EOF exit;; (-n|--dry-run) dryrun=1;; (-p|--path) shift; vols+=( "$1" );; (-m|--mnt) shift; TMP_MNT="$1";; (-d|--del) shift; del="$1";; (*) echo "ERROR: unknown option $1, try $0 --help" 1>&2 exit 1;; esac if test $# -lt 1; then echo "ERROR: missing argument, try $0 --help" 1>&2 exit 1 fi shift done BTRFS_VOLUMES=${BTRFS_VOLUMES:-$(awk '!/^#/ && $3=="btrfs" {print $2}' /etc/fstab)} TMP_MNT=${TMP_MNT:-/var/tmp/btrfs-backup} test -d "${TMP_MNT}" || mkdir -p "${TMP_MNT}" for fs in ${BTRFS_VOLUMES}; do device=$(mount | awk '$3=="'$fs'" && $5=="btrfs" {print $1}') subvol=$(mount | awk '$3=="'$fs'" && $5=="btrfs" {split(substr($6, 2, length($6)-2), res, ","); for (r in res) {if (res[r]~/^subvol=/) {sub(/^subvol=/,"" , res[r]); print res[r]}}}') if test -n "$subvol"; then name=${subvol} else if test "$fs" = "/"; then name="@root" else name=${fs#/} name=${name%/} name=${name//\//-} fi fi target="${name}-snapshot-$(date +%Y-%m-%d-%H-%M)" if test $dryrun -eq 1; then echo btrfs subvolume snapshot "${TMP_MNT}${subvol}" "${TMP_MNT}/${target}" else if mount | grep -q " on $TMP_MNT type "; then sudo umount "$TMP_MNT" fi sudo mount "$device" "$TMP_MNT" sudo btrfs subvolume snapshot "${TMP_MNT}${subvol}" "${TMP_MNT}/${target}" sudo umount "$TMP_MNT" fi done