#!/bin/sh set -e imgloop= tmpfile= tmploop= dmname= cowlink= function cleanup () { set +e [ -n "$cowlink" ] && rm $cowlink [ -n "$dmname" ] && dmsetup remove $dmname [ -n "$tmploop" ] && losetup -d $tmploop [ -n "$tmpfile" ] && rm $tmpfile [ -n "$imgloop" ] && losetup -d $imgloop } trap cleanup EXIT imgfile=$1 ; shift command=$1 ; shift if [ -z "$imgfile" -o -z "$command" ] ; then echo Syntax: $0 /path/to/image/file command [args..] exit 1 fi # Set up image loop device x=`losetup -f` ; losetup -r $x $imgfile ; imgloop=$x # Create temporary file and set up temporary loop device tmpfile=`mktemp $imgfile.XXXXXXXXXX` truncate -r $imgfile $tmpfile x=`losetup -f` ; losetup $x $tmpfile ; tmploop=$x # Create snapshot device imgsize=`blockdev --getsz $imgloop` x=`basename $imgfile` ; echo 0 $imgsize snapshot $imgloop $tmploop N 16 | \ dmsetup create $x ; dmname=$x chown --reference=$imgfile /dev/mapper/$dmname chmod --reference=$imgfile /dev/mapper/$dmname # Create symlink x=$imgfile.cow ; ln -s /dev/mapper/$dmname $x ; cowlink=$x # Wait until killed echo "Created $cowlink" $command "$@" $cowlink