snap.lvm2 (1391B)
1 #!/bin/sh 2 # usage: snapshot.lvm2 vg/lv executable [args] 3 if test $# -lt 2; then 4 echo 'usage: snap.lvm2 vg/lv executable [args]' 5 exit 6 fi 7 SRC="$1" 8 shift 9 S_VOL="${SRC}.snaprep" 10 S_DEV="/dev/mapper/${SRC//\//-}.snaprep" 11 SNAPSHOT="/mnt/snaprep/${SRC//\//-}" 12 export SNAPSHOT 13 LOCKDIR=/var/lock/snaprep 14 test -d "$LOCKDIR" || mkdir -p "$LOCKDIR" || exit $? 15 LOCKFILE="$LOCKDIR/lvm2.${SRC//\//-}" 16 # since LVM implies Linux, I'm assuming the presence of the flock utility 17 if ! flock -n "$LOCKFILE" true; then 18 echo >&2 "locked: $SRC" 19 exit 1 20 fi 21 ( 22 flock -n 3 || exit $? 23 echo $$ >&3 24 if test -b "$S_DEV"; then 25 echo >&2 "removing stale snapshot" 26 if grep -qF "$S_DEV" /proc/mounts; then # TODO match only on start of line 27 umount $S_DEV || exit $? 28 fi 29 lvremove -f "$S_DEV" || exit $? 30 fi 31 if test -d "$SNAPSHOT"; then 32 # make sure it's empty and unused 33 rmdir "$SNAPSHOT" || exit $? 34 fi 35 mkdir -p "$SNAPSHOT" || exit $? 36 lvcreate -n "${SRC##*/}.snaprep" -L "${SNAPSHOT_SIZE:-10G}" -s "$SRC" || exit $? 37 die_lvremove() { 38 lvremove -f "$S_VOL" 39 exit $? 40 } 41 magic="$(file -b -s "$(realpath "$S_DEV")")" 42 case "$magic" in 43 (*XFS*) mount -t xfs -o nouuid "$S_DEV" "$SNAPSHOT" || die_lvremove $?;; 44 (*) mount "$S_DEV" "$SNAPSHOT" || die_lvremove $?;; 45 esac 46 SNAP_SRC=$SNAPSHOT 47 export SNAP_SRC 48 touch $SNAP_SRC/.snapshot.$(date +%s) 49 "$@" 50 RETCODE=$? 51 umount "$SNAPSHOT" 52 lvremove -f "$S_VOL" 53 ) 3> "$LOCKFILE" 54 exit $RETCODE