armkbdotcom DD-WRT User
Joined: 09 Feb 2009 Posts: 61
|
Posted: Sat Mar 14, 2009 14:49 Post subject: Shutdown script for any USB mounted drive |
|
Hi,
Want to share with my shutdown script.
- Using forced umount algorithm including calling init.d K* scripts, sending -TERM signal, sending -KILL signal and using lazy umount. As base script I use this
- As argument takes mount points to unmount eg. shutdown.sh /mmc /opt. So in your web gui shutdown command you can specify this:
shutdown.sh /mmc /opt
Note that /opt should be umounted at last point, because fuser is located there, unless you have different structure.
- Logs messages to system log. You can also monitor shutdown process remote on syslog server.
- Edit script and put prefixumnt to dir of umount, usually /bin. Put prefixfusr to dir containing fuser. You can install fuser from psmisc package Optware, eg.
ipkg-opt install psmisc
- Tested with mini 11218, works like a charm in every situation, even when my hard drive is busy r/w with multiple applications, never had anything corrupted.
Quote: | #!/bin/sh
#Please put trailing slash
prefixumnt=/bin/
prefixfusr=/opt/bin/
# Kill daemons
for f in /opt/etc/init.d/K* ; do
[ -x $f ] && $f stop
done
if [ $# -eq 0 ]; then
printf "shutdown: mount point(s) are not specified, terminating script" | /usr/bin/logger
exit 1
fi
# Get rid of swap partitions
/jffs/usr/sbin/run.sh /jffs/usr/sbin/swapoff -a
index=0
eval mntpoint=\$$index
while [ 1 ]; do
index=`expr $index + 1`
eval mntpoint=\$$index
if [ ${#mntpoint} -eq 0 ]; then
exit
fi
printf "shutdown: trying to umount %s" $mntpoint | /usr/bin/logger
# attempt a regular umount
tryumount=`${prefixumnt}umount $mntpoint 2>&1`
ret=$?
# did the umount succeed?
if [ $ret -eq 0 ]; then
printf "shutdown: %s successfully unmounted at first attempt" "$mntpoint" | /usr/bin/logger
continue
else
printf "shutdown: busy... killing all processes accessing the filesystem" | /usr/bin/logger
${prefixfusr}fuser -TERM -k -v -m $mntpoint
fi
# Let the program cleanup and exit
sleep 3
# try to umount again
tryumount=`${prefixumnt}umount $mntpoint 2>&1`
ret=$?
if [ $ret -eq 0 ]; then
printf "shutdown: %s successfully unmounted at second attempt" "$mntpoint" | /usr/bin/logger
continue
else
# get the name of the device that is mounted
exec 6<&0 # save stdin... better way to do this?
exec < /proc/mounts
while read line; do
mnt=`echo $line |awk '{print $2}'`
if [ "$mnt" = "$mntpoint" ]; then
device=`echo $line |awk '{print $1}'`
break
fi
done
exec 0<&6 6<&- # restore stdin
# our first attempt didn't work, do lazy umount to make it easier
printf "shutdown: %s still busy, doing lazy umount" "$mntpoint" | /usr/bin/logger
${prefixumnt}umount -l $mntpoint
# keep trying to kill processes accessing the device. don't exit until
# we succeed
while [ -n "$device" -a -e "$device" ]; do
printf "shutdown: attempting to kill all processes accessing $device" | /usr/bin/logger
${prefixfusr}fuser -KILL -k -m $device &> /dev/null
if [ -z "`${prefixfusr}fuser -m $device`" ]; then
printf "shutdown: %s successfully unmounted after lazy umount" "$mntpoint" | /usr/bin/logger
break
fi
sleep 1
done
fi
sleep 1
done
exit 0 |
_________________ Asus WL-500W. DD-WRT v24-sp2 (11/25/09) mini - build 13309M NEWD Eko |
|