#! /bin/sh ### ### Make fake snapshots by remounting a filesystem readonly ### ### (c) 2011 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. set -e quis=${0##*/} ###-------------------------------------------------------------------------- ### Parse the command line. ## Provide help or version information. usage="usage: $quis DEVICE [KEY=VALUE ...]" version="$quis, version 1.0.0" case "$#,$1" in 0,*) echo >&2 "$usage"; exit 1 ;; *,-v | *,--version) echo "$version"; exit ;; *,-h | *,--help) cat <&2 "$quis: malformed option \`$i'"; exit 1 ;; esac k=${i%%=*} v=${i#*=} case "$k" in *.ro) k=${k%.ro} ;; ?*.?*) continue ;; esac case "$k" in op | tag | dir) eval "O$k=\$v" ;; *) echo >&2 "$quis: unknown option \`$k'"; win=nil ;; esac done case $win in nil) exit 1 ;; esac ## Find a mount point if none was given. sdn='s/^b[^ ]* *[^ ]* *[^ ]* *[^ ]* *\([0-9]*\), *\([0-9]*\) .*$/\1:\2/' case "${Odir+t}" in t) ;; *) exec 3&2 "$quis: $dev is not a block device"; exit 1 ;; esac while read <&3 d m fs hunoz; do if [ ! -b "$d" ]; then continue; fi dn=$(ls -lL "$d" | sed "$sdn") case "$dn" in "$devno") case "${Odir+t}" in t) echo >&2 "$quis: /dev/$dev mounted multiple times"; exit 1 ;; esac Odir=$m ;; esac done exec 3>&- ;; esac case "${Odir+t}" in t) ;; *) echo >&2 "$quis: /dev/$dev apparently not mounted"; exit 1 ;; esac ###-------------------------------------------------------------------------- ### Take or remove the snapshot. case "$Oop" in snap) echo "$Otag" >"$Odir/.snap" mount -oremount,ro "/dev/$dev" "$Odir" echo "$dev" ;; unsnap) if [ ! -f "$Odir/.snap" ]; then echo >&2 "$quis: no snapshot tag" exit 1 fi read tag <"$Odir/.snap" case "$tag" in "$Otag") ;; *) echo >&2 "$quis: tag mismatch (found \`$tag' but expected \`$Otag')" exit 1 ;; esac mount -oremount,rw "/dev/$dev" "$Odir" rm "$Odir/.snap" ;; *) echo >&2 "$quis: unknown operation \`$Oop'" exit 1 ;; esac ###----- That's all, folks --------------------------------------------------