Skip to content

Instantly share code, notes, and snippets.

@vuolter
Created March 22, 2014 22:37
Show Gist options
  • Save vuolter/9715488 to your computer and use it in GitHub Desktop.
Save vuolter/9715488 to your computer and use it in GitHub Desktop.
Unmount and spin down all scsi devices
#!/bin/sh
#
# Shutscsi v0.1 - Unmount and spin down all scsi devices
# @author: Walter Purcaro <[email protected]>
#
###############################################################################
#
# This script needs fuser and sdparm softwares to run correctly.
# Install psmisc and sdparm packages to get them.
#
# Don't forget to execute as root!
#
###############################################################################
#
# Ignore devices
# Ex.: IGNORE="abc" (to ignore sda, sdb, sdc device)
IGNORE=""
#
# Kill all processes even if device is not busy
KILL=0
#
# Force unmount sending SIGKILL
FORCE=0
#
###############################################################################
# Declare log function
log(){
#echo "$1"
case "$2" in
"EMERG") E=0;;
"ALERT") E=1;;
"CRITICAL") E=2;;
"ERROR") E=3;;
"WARNING") E=4;;
"NOTICE") E=5;;
"INFO") E=6;;
"DEBUG") E=7;;
*) E=6;;
esac
logger -i -p $E -t "Shutscsi" "$1"
}
# Check software dependencies
packages="awk df echo fuser grep logger sed sort sdparm umount"
for dep in $packages
do which "$dep" || log "Package $dep not found!" CRITICAL && EXIT=1
done
[ $EXIT -eq 1 ] && exit 2
# Get devices to unmount
fss="$(df | grep -e "^/dev/sd" | awk {'print $1'})"
[ -z "$fss" ] && log "No scsi devices found mounted! Exit now." && exit 0
if [ -n "$IGNORE" ]
then
pn="$(echo $IGNORE | sed -e 's/ //g' | grep -o "." | awk {'print tolower("^/dev/sd"$1"|")'})"
excpn="$(echo -n "${pn%?}" | sed -e 's/ //g')"
fss=$($fss | grep -ve "$excpn")
fi
# Start umount loop
for device in $(echo "$fss" | sed -e 's/[0-9]*//g' | sort -u)
do
SPINDOWN=1
# Try to unmount filesystems on the pool
for fs in $(echo "$fss" | grep -e "^$device")
do
umountfs=$(umount "$fs")
# First try to unmount directly
$umountfs
# Go to the next filesystem if unmount succeeds and KILL argument was not set
if [ $? -ne 0 -o $KILL -eq 1 ]
then
# Kill processes keeping busy current filesystem
fuser -mk -signal SIGTERM "$fs"
# Force killing if previous task fails and FORCE argument was set
[ $? -ne 0 -a $FORCE -eq 1 ] && fuser -mk -signal SIGKILL "$fs"
# Retry unmount
$umountfs
fi
# Exitcode
if [ $? -ne 0 ]
then
log "Unable to unmount busy filesystem $fs" ERROR
SPINDOWN=0
else
log "Successfully unmounted filesystem $fs" DEBUG
fi
done
# Spin-down device if all its filesystems was sucessfully unmounted
if [ $SPINDOWN -eq 1 ]
then
log "Spinning down device $device"
err="$(sdparm --flexible --command=stop --quiet "$device" 2>&1)"
[ $? -ne 0 ] && log "$err" ERROR
else
log "Spin-down not performed for device $device" ERROR
fi
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment