UPD btrfs-snapshot script

This commit is contained in:
2025-06-13 12:51:35 +02:00
parent 3430a5c0da
commit 5773295f2d
3 changed files with 168 additions and 0 deletions

151
btrfs-snapshot/btrfs-snapshot Executable file
View File

@ -0,0 +1,151 @@
#!/bin/bash
# By Thomas KUSCHEL <oe1tkt@gmail.com>
# MIT License 2015
VERSION="v6.15"
set -o errexit # to make script exit when a command fails / a.k.a. set -e
# then add "|| true" to commands that you allow to fail.
set -o nounset # to exit when script tries to use undeclared variables / set -u
# set -o xtrace # to trace when gets executed for debugging / a.k.a. set -x
set -o pipefail
SCRIPTNAME=${0##*/}
SCRIPTPATH=$(dirname "$0")
# echo $SCRIPTNAME
# where the btrfs is found (use command: which btrfs)
WHICH="/usr/bin/which"
BTRFS_ALT="/sbin/btrfs"
BTRFS="/usr/local/bin/btrfs"
# Function to install this script:
installation() {
# you have to switch to administrator
#`${WHICH} ${PATHINSTALL}`
PATHINSTALL="/usr/local/bin"
SNAPSYSTEMDCFG="/etc/systemd/system/"
SCRIPTPATH=$(dirname "$0")
# echo "Installation of ${SCRIPTNAME} to ${PATHINSTALL} and create systemd timer/service examples in ${SNAPSYSTEMDCFG}"
read -n 1 -p "Install ${SCRIPTNAME} to ${PATHINSTALL}? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
sudo cp $0 ${PATHINSTALL}/${SCRIPTNAME}
fi
read -n 1 -p "Do you want to create systemd timer/service examples in ${SNAPSYSTEMDCFG}? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
sudo cp -a ${SCRIPTPATH}/system/. ${SNAPSYSTEMDCFG}.
path=`$WHICH $SCRIPTNAME`
fi
}
deinstallation() {
PATHINSTALL="/usr/local/bin"
read -n 1 -p "Do you want to remove (deinstallation) of ${SCRIPTNAME} in ${PATHINSTALL}? [Y/n] " reply;
if [ "$reply" != "" ]; then echo; fi
if [ "$reply" = "${reply#[Nn]}" ]; then
sudo rm -f ${PATHINSTALL}/${SCRIPTNAME}
fi
}
# Function to display usage:
usage() {
path=`${WHICH} ${SCRIPTNAME}` || installation
if [ -z "${path}" ] ; then
path="/usr/local/bin/"
echo "Please install $SCRIPTNAME to \"$path\""
path="${path}${SCRIPTNAME}"
fi
cat <<EOF
$SCRIPTNAME: Take and rotate snapshots on a btrfs file system
usage: $SCRIPTNAME [--version] source target snap_name count [-q]
source: path to make snaphots of
target: snapshot directory
snap_name: Base name for snapshots, to be appended to
date "+%F-%H%M"
count: Number of snapshots in the timestamp-@snap_name format to
keep at one time for a given snap_name.
[-q]: Be quiet.
--install: Force a new installation of this script.
--version: Print the version of this script,
additionally the version of btrfs-progs.
Example for crontab:
15,30,45 * * * * root $0 /home /snap quarterly 4 -q
0 * * * * root $0 /home /snap hourly 8 -q
Example for anacrontab:
1 15 daily_snap $0 /home /snap daily 8
7 17 weekly_snap $0 /home /snap weekly 5
@monthly 19 monthly_snap $0 /home /snap monthly 3
NEW: If you are using systemd on your linux system, see http://f0x.at/btrfs
EOF
exit
}
if [ ! -f "$BTRFS" ] ; then
if [ -f "$BTRFS_ALT" ] ; then
# fallback
BTRFS="$BTRFS_ALT"
else
echo "$BTRFS system file not found,"
echo "please install btrfs-progs:"
echo "Arch Linux: # sudo pacman -S btrfs-progs"
echo "Debian/Ubuntu: # sudo apt-get install btrfs-tools"
exit
fi
fi
# Basic argument checks:
if [ $# -gt 0 ] && [ "x$1" == "x--version" ] ; then
echo "$SCRIPTNAME $VERSION"
echo `$BTRFS --version`
exit
fi
if [ $# -gt 0 ] && [ "x$1" == "x--install" ] ; then
installation
exit
fi
if [ $# -gt 0 ] && [ "x$1" == "x--deinstall" ] ; then
deinstallation
exit
fi
# Check count of arguments
if [ "$#" -ge 4 ]; then
SOURCE=$1
TARGET=$2
SNAP=$3
COUNT=$4
QUIET=""
if [ "$#" -gt 4 ]; then
QUIET=$5
fi
else
echo "You need some arguments."
usage
fi
if [ $# -gt 5 ] ; then
echo "Too many parameters."
usage
fi
if [ -n "$QUIET" ] && [ "x$QUIET" != "x-q" ] ; then
echo "Parameter 4 is either -q or empty. Given: \"$QUIET\""
usage
fi
# $max_snap is the highest number of snapshots that will be kept for $SNAP.
max_snap=$(($COUNT -1))
# Check if $TARGET already exists - if NOT then create subdir
[ -d $TARGET ] || mkdir $TARGET
# Clean up older snapshots:
for i in `ls $TARGET|sort |grep @${SNAP}|head -n -${max_snap}`; do
cmd="$BTRFS subvolume delete $TARGET/$i"
if [ -z $QUIET ]; then
echo $cmd
fi
$cmd >/dev/null
done
# Create new snapshot:
cmd="$BTRFS subvolume snapshot -r $SOURCE $TARGET/`date "+%F-%H%M-@${SNAP}"`"
if [ -z $QUIET ]; then
echo $cmd
fi
$cmd >/dev/null

View File

@ -0,0 +1,8 @@
[Unit]
Description=rolling snapshot for /home/user
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
ExecStart=/usr/local/bin/btrfs-snapshot /home/user /home/snap/user daily 4

View File

@ -0,0 +1,9 @@
[Unit]
Description=daily snapshot
[Timer]
# see systemd.time(7) manual page for other scheduling options
OnCalendar=01:00
# run immediately if we missed a backup for some reason
Persistent=true
[Install]
WantedBy=timers.target