A collection of scripts

add btrsnp

Changed files
+119
scritps
+119
scritps/btrsnp
···
+
#!/bin/sh
+
# Create a BTRFS snapshot of a subvolume
+
+
# This script is possibly highly specific to my current BTRFS setup and may not
+
# work the way you want it to for your system
+
+
# My current (2021-09-27) BTRFS is as follows:
+
# BTRFS Partition (mounted to /mnt/nvme0n1p2 for easy access to subvolumes)
+
# - gentoo (mounted either to / or /mnt/gentoo)
+
# - home (mounted to /home)
+
# - sys-misc (mounted to /mnt/sys-misc)
+
# - void (mounted either to / or /mnt/void)
+
+
# Snapshots will be saved with the name `SUBVOLUMENAME-$(date +%F-%H_$M_%S)`
+
+
[ "$BTRSNP_DEVICE" ] || BTRSNP_DEVICE=$(findmnt -nvo SOURCE /)
+
[ "$BTRSNP_READ" ] || BTRSNP_READ=ro
+
[ "$BTRSNP_SUBVOL" ] || {
+
BTRSNP_SUBVOL=$(findmnt -no SOURCE /)
+
BTRSNP_SUBVOL=${BTRSNP_SUBVOL##*/}
+
BTRSNP_SUBVOL=${BTRSNP_SUBVOL%]}
+
}
+
+
usage() {
+
while read -r line
+
do printf '%b\n' "$line"
+
done <<-USAGE
+
usage: ${0##*/} [OPTIONS]
+
+
options:
+
\t-d DEVICE - select which partition the subvolume is on
+
\t-h - displays this message
+
\t-r [ro|rw] - determine if the snapshot should be readonly
+
\t-s SUBVOL - select which subvolume to snapshot
+
+
environment variables:
+
\tBTRSNP_DEVICE - selects which partition the subvolume is on
+
\t defaults to the root partition
+
\tBTRSNP_READ - determine if the snapshot should be readonly
+
\t defaults to \`ro\`
+
\tBTRSNP_SUBVOL - selects which subvolume to snapshot
+
\t defaults to the subvolume mounted at as /
+
USAGE
+
+
exit "${1:-1}"
+
}
+
+
msg() {
+
case $1 in
+
e ) printf '%b\n' "${0##*/}: $*" 1>&2 ;;
+
* ) printf '%b\n' "${0##*/}: $*" ;;
+
esac
+
}
+
+
while [ "$*" ]
+
do
+
case $1 in
+
- ) shift; continue ;;
+
-- ) shift; break ;;
+
-* ) flag=${1#-}; shift ;;
+
* ) shift; continue ;;
+
esac
+
+
while [ "$flag" ]
+
do
+
arg=${flag%"${flag#?}"}
+
+
case $arg in
+
d ) BTRSNP_DEVICE="$1"; shift ;;
+
h ) usage 0 ;;
+
s ) BTRSNP_SUBVOL="$1"; shift ;;
+
r )
+
[ "$1" ] || BTRSNP_READ="rw" && {
+
case $1 in
+
ro ) BTRSNP_READ="ro" ;;
+
rw ) BTRSNP_READ="rw" ;;
+
* ) msg e "$1: invalid option argument for -$arg"; usage 1 ;;
+
esac
+
shift
+
}
+
;;
+
* ) msg e "-$arg: invalid argument"; usage 1 ;;
+
esac
+
+
flag=${flag#?}
+
done
+
done
+
+
# shellcheck disable=SC2015
+
[ "$BTRSNP_DEVICE" ] && [ "$BTRSNP_SUBVOL" ] || {
+
msg e "a device and subvolume are required"
+
usage 1
+
}
+
+
# Look for the raw BTRFS mount in /mnt this may be changeable in the future
+
BTRSNP_DEVICE=${BTRSNP_DEVICE##*/}
+
if findmnt "/mnt/$BTRSNP_DEVICE" > /dev/null 2>&1
+
then btrfs_partition_path=/mnt/$BTRSNP_DEVICE
+
else
+
msg e "BTRFS partition is not mounted at /mnt/$BTRSNP_DEVICE"
+
exit 1
+
fi
+
+
# If I find a more accurate way to check if a directory is a subvolume I will implement it, but for
+
# now, just check if it's a directory
+
if [ -d "$btrfs_partition_path/$BTRSNP_SUBVOL" ]
+
then btrfs_subvolume_path="$btrfs_partition_path/$BTRSNP_SUBVOL"
+
else
+
msg e "This is not a BTRFS subvolume"
+
exit 1
+
fi
+
+
case $BTRSNP_READ in
+
ro ) ro="-r" ;;
+
rw ) ;;
+
esac
+
+
btrfs subvolume snapshot $ro "$btrfs_subvolume_path" \
+
"${btrfs_subvolume_path}-$(date +'%F-%H_%M_%S')"