| #!/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 |