#!/bin/bash PATH=/usr/bin:/sbin:/opt/VRTS/bin; export PATH # Dusan U. Baljevic dusan.baljevic@ieee.org # # The original script was published in # "XP StorageWorks Summary Guide for Thin Provisioning" # # 18 Apr 2012 # # The script could be improved much more, # but that is left for the next exercise. umask 022 ARGCNT="$#" SCRIPT="`basename $0`" USAGE="USAGE: $SCRIPT -f filesystem [ -p percent-fill] [-h] -h Print help file -f filesystem Filesystem in which to reclaim thin-provisioned space -p percent-fill Threshold to fill filesystem " # Process command line arguments. # while getopts hf:p: c do case $c in f) FS="$OPTARG" ;; h) echo "$USAGE"; exit 0 ;; p) PCTFILL="$OPTARG" ;; \?) echo "$USAGE"; exit 1 ;; esac done shift `expr $OPTIND - 1` if [ ! "$PCTFILL" ]; then PCTFILL=90 fi # Tunables # zfile="zeroreclaimfile.raw" SLEEPTIME=5 if [ ! "$FS" ]; then printf "ERROR: Filesystem argument not supplied\n" echo "$USAGE" exit 1 fi if [ "$ARGCNT" -lt 2 ]; then printf "ERROR: Must supply one filesystem mount point\n"; exit 1 fi FSTYP=$(df -n $FS | nawk '{print $3}') MOUNT=$(df -k $FS | nawk '!/Filesystem/ {print $6}') if [ "$MOUNT" != "$FS" ]; then printf "INFO: Filesystem argument supplied \"$FS\" is not a mount point\n" printf "INFO: It is contained within \"$MOUNT\"\n" exit 1 fi ####### SETUP SIGNAL HANDLING ############## # trap "INTERRUPT_HANDLER" 1 2 3 9 15 # Catch interrupts and handle them # INTERRUPT_HANDLER() { trap "" 1 2 3 9 15 printf "\n\nWARN: Interrupt received... Terminating program and cleaning up\n" # killing child processes # for PID in `ps -f | nawk -v PPID=$$ '{if ( $3 == PPID ) print $2}'` ; do if [ "$PID" != "PID" -a $PID -ne $$ ] ; then echo "INFO: Executing termination of process ID $PID 2>/dev/null" kill $PID 2>/dev/null fi done cleanup $FS exit 0 } status() { PCT=$(df -k $1 | nawk '!/Filesystem/ {print $5}' | sed 's/%//g') printf "INFO: Initial filesystem \"$1\" utilization: $PCT percent\n\n" while true do PCT=$(df -k $1 | nawk '!/Filesystem/ {print $5}' | sed 's/%//g') printf "INFO: Current filesystem \"$1\" utilization: $PCT percent...\n" if [ $PCT -gt $(expr $PCTFILL + 1 ) ]; then printf "\nINFO: Filesystem \"$1\" exceeded the threshold of $PCTFILL percent\n" printf "INFO: Stopping space reclamation process and continuing with cleanup\n" #Send term signal to myself kill -1 $$ fi printf "INFO: Running filesystem space reclamation process...\n" ps -ef | egrep -v grep | grep $(cat $1/$zfile.pid) if [ $? -eq 0 ]; then sleep $SLEEPTIME else return fi done } cleanup() { printf "\nINFO: Calling sync...\n" sync sync sleep $SLEEPTIME printf "INFO: Completed Successfully... removing temporary files...\n" rm $1/${zfile} $1/${zfile}.pid 2>/dev/null 2>&1 sleep $SLEEPTIME df -k $1 } case $FSTYP in vxfs|VXFS) fsadm -R $FS >/dev/null 2>&1 if [ $? -eq 0 ]; then exit 0 else continue fi ;; esac if [ -f $FS/$zfile ]; then printf "ERROR: \"$FS/$zfile\" exists (previous run did not complete?)... exiting\n" exit 1 fi line=$(df -k $FS | nawk '!/Filesystem/ {print}') CURCAP=$(echo $line | nawk '{print $5}' | sed 's/%//g') CAPKB=$(echo $line | nawk '{print $2}') CAPUSEDKB=$(echo $line | nawk '{print $3}') if [ $CURCAP -gt $(expr $PCTFILL + 1 ) ]; then printf "INFO: Current capacity of \"$FS\" exceeds threshold of fill capacity currently set at $PCTFILL\n" printf "INFO: No operation will be performend on \"$FS\"\n" else printf "INFO: Filesystem \"$FS\" has capacity $(expr $CAPKB / 1024) MB\n" printf "INFO: Filling filesystem \"$FS\" utilization to $PCTFILL percent\n\n" FSEND=$(expr $CAPKB \* $PCTFILL / 100) KB=$(expr $FSEND - $CAPUSEDKB) COUNT=$(echo "$KB / 1024" | bc) echo "INFO: Running dd if=/dev/zero of=$FS/$zfile bs=1024k count=$COUNT > /dev/null 2>&1 &" dd if=/dev/zero of=$FS/$zfile bs=1024k count=$COUNT > /dev/null 2>&1 & echo $! > $FS/$zfile.pid status $FS cleanup $FS fi exit 0