Skip to content

Instantly share code, notes, and snippets.

@matgou
Last active August 29, 2015 14:13
Show Gist options
  • Save matgou/3034f46d68645565ec60 to your computer and use it in GitHub Desktop.
Save matgou/3034f46d68645565ec60 to your computer and use it in GitHub Desktop.
Take the snapshot of btrfs filesystem
#!/bin/bash
#
# usage: snapshot.sh create|delete|list [snapshotname]
#
#
btrfs_root=/
DST_BACKUPDIR=/backup
# **************************************************************************
# create()
# ARGS: <no>
# RC: 0 if OK
#
create()
{
sync
if [ -z $1 ]
then
path_to_snapshots=${DST_BACKUPDIR}/`date +%Y%m%d_%H%m%S`
else
path_to_snapshots=${DST_BACKUPDIR}/$1
fi
mkdir -pv ${DST_BACKUPDIR}
subvolumes="$(/usr/bin/btrfs subvolume list '/' | /usr/bin/awk '{print $NF}' | grep -vE '^backup')" # rescan
for subvolume in $subvolumes
do
snapshot_directory="${btrfs_root}/${path_to_snapshots}/$(/usr/bin/dirname ${subvolume})"
rm -rf ${btrfs_root}/${path_to_snapshots}/${subvolume}
if [ ! -d "${snapshot_directory}" ]
then
/usr/bin/mkdir -p "${snapshot_directory}"
fi
/usr/bin/btrfs subvolume snapshot "${btrfs_root}/${subvolume}" "${btrfs_root}/${path_to_snapshots}/${subvolume}"
TRANSACTION_ID=`btrfs subvolume find-new "${btrfs_root}/${subvolume}" 9999999`
TRANSACTION_ID=${TRANSACTION_ID#transid marker was }
echo "${subvolume};${TRANSACTION_ID}" >> $path_to_snapshots/transaction.db
done
return 0
}
# **************************************************************************
# list()
# ARGS: <no>
# RC: 0 if OK
#
list()
{
cd $DST_BACKUPDIR
ls -ltrd */
}
# **************************************************************************
# remove()
# ARGS: <no>
# RC: 0 if OK
#
delete()
{
if [ -z $1 ]
then
echo echo "usage: snapshot.sh delete snapshotname"
return 1
else
path_to_snapshots=${DST_BACKUPDIR}/$1
fi
if [ ! -d $path_to_snapshots ]
then
echo "$path_to_snapshots : No such directory"
echo "usage: snapshot.sh delete snapshotname"
return 1
fi
subvolumes=`btrfs subvolume list $path_to_snapshots | /usr/bin/awk '{print $NF}' | tac`
for subvolume in $subvolumes
do
btrfs subvolume delete ${btrfs_root}/${path_to_snapshots}/$subvolume
done
rm -rvf $path_to_snapshots
}
# **************************************************************************
# diff()
# ARGS: <no>
# RC: 0 if OK
#
diff ()
{
SNAPSHOT_OLD=${DST_BACKUPDIR}/$1;
SNAPSHOT_NEW=${DST_BACKUPDIR}/$2;
if [ ! -d $SNAPSHOT_OLD ]
then
echo "$SNAPSHOT_OLD does not exist";
return 1
fi
if [ ! -d $SNAPSHOT_NEW ]
then
echo "$SNAPSHOT_NEW does not exist";
return 1
fi
cat $SNAPSHOT_OLD/transaction.db | while read line
do
OLD_TRANSID=`echo $line | cut -d";" -f2`
SUBVOL=`echo $line | cut -d";" -f1`
btrfs subvolume find-new "$SNAPSHOT_NEW/$SUBVOL" $OLD_TRANSID | sed '$d' | cut -f17- -d' ' | sort | uniq | while read file
do
echo $SUBVOL/$file
done
done
}
case "$1" in
create)
create $2
RC=$?
;;
delete)
delete $2
RC=$?
;;
list)
list
RC=$?
;;
diff)
diff $2 $3
RC=$?
;;
*)
echo "usage: snapshot.sh create|delete|list [snapshotname]"
RC=1
;;
esac;
/usr/bin/sync
exit $RC
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment