#!/bin/bash # # purge old zfs snapshots# work on Solaris 10, not tested in other environment# by Igor Velkov <dober-aeons.lv># v 0.2.1# based on snap_zfs by trevor.pretty@sun.comSCRIPT_NAME=$0FILESYSTEM=$1ID=/usr/xpg4/bin/idZFS=/usr/sbin/zfsNOW="date +%Y-%m-%d.%H:%M:%S "DEBUG=N# very bad!!!!!# get the current date in unixtime formatDATE=`/usr/bin/truss /usr/bin/date 2>&1 | nawk -F= '/^time\(\)/ {gsub(/ /,"",$2);print $2}'`## Usage# Usage(){ echo "Recursively removes all snapshots of filesystem " echo "older min_age, or between (min_age..max_age)" echo "Usage: $SCRIPT_NAME filesystem @snapprefix min_age [max_age]" echo "" echo "Examples" echo " $SCRIPT_NAME pool/name @snap 3" echo " $SCRIPT_NAME pool/name @snap 3 10" echo "" echo "Note: The filesystem cannot have a trailing \"/\"" echo "snapprefix must always start with \"@\"" echo "" exit 1}########### Main Part ##################### Check Usage#if [ $# -lt 3 ]; then echo 'You have to provide at least 3 arguments' Usagefi# check if parameter 3 is number# [0-9]+case "$3" in*[^0-9]*) echo '3rd argument must be a number' Usage exit 1 ;;*) MIN="$3" ;;esac# check if parameter 4 is present and is number# [0-9]+case "$4" in*[^0-9]*) echo '4rd argument must be a number if present' Usage exit 1 ;;# 4rd parametr is number[0-9]*) MAX=$4 ;;*) ;;esac# sheck for snapshot pattern starts with "@" ant not contain more @# it must for not erase filesystem if no "@" will be suppliedSNAPPTN="$2"if [ "@${SNAPPTN#@}" != "$SNAPPTN" ]; then echo "Second parameter must start with @ and not contain \"@\" more" Usagefi## See if we have right authorization: Either we are root or allowed to manage ZFS#WHO=`/usr/xpg4/bin/id -n -u`PROF=`/bin/profiles | grep "ZFS File System Management"`if [ "$PROF" != "ZFS File System Management" ]; then if [ "$WHO" != "root" ]; then echo "$SCRIPT_NAME: ERROR: you are not authorized to run this script." exit 1 fifi# get list in format fsname, used bytes, creation time, mountpoint# we will work only where type=snapshot$ZFS get -H -o value -rp name,used,creation,type "$FILESYSTEM" \ | sed '$!N;s/\n/ /' | sed '$!N;s/\n/ /' | grep "$SNAPPTN" \ | while read SNNAME SNUSED SNTIME SNTYPE; do if [ "$DEBUG" = 'Y' ] ; then echo "$SNNAME $SNUSED $SNTIME $SNTYPE" fi #work only with snapshots, not filesystem or something other if [ "$SNTYPE" != 'snapshot' ]; then if [ "$DEBUG" = 'Y' ] ; then echo "type is \"$SNTYPE\", not processed" fi continue; fi # AGE is snapshot age in days, count from unixtime dy /sec in min/min in a hour/hour in a day AGE=`expr \( $DATE - $SNTIME \) / 60 / 60 / 24` # target expression (!$MAX & ($AGE >= $MIN)) | ($MAX & ($AGE < $MAX) & ($AGE >= $MIN)) # inverse: not remove if $AGE < $MIN or (isset($MAX) and $AGE>$MAX) ERASE=Y if [ "$AGE" -lt "$MIN" ]; then ERASE=N elif [ "$MAX" ]; then if [ "$AGE" -gt "$MAX" ]; then ERASE="N" fi fi if [ "$DEBUG" = 'Y' ] ; then echo "snap:$SNNAME snaptime:$SNAPTIME age:$AGE min:$MIN max:$MAX erase:$ERASE" fi if [ "$ERASE" != 'N' ]; then if [ "$DEBUG" = 'Y' ] ; then echo "want run zfs remove $SNNAME" else # not using -R swich to protect child objects if exists $ZFS destroy "$SNNAME" if [ $? -gt 0 ] ; then echo "error destroying $SNNAME" else echo "$SNNAME destroyed" fi fi fidoneexit