Here's a patch, I've tested it on my system and tried a few contrived mount scenarios and it works better than pioodl(). Here's a way to break pioodl():
mkdir -p /tmp/1/2/3 mount LABEL=disk3 /tmp/1/2/3 mount LABEL=disk2 /tmp/1/2 mount LABEL=disk1 /tmp/1 You get a /proc/mounts that looks like this: /dev/md3 /dev/shm/tmp/1/2/3 ext3 rw,errors=panic,data=ordered 0 0 /dev/md6 /dev/shm/tmp/1/2 ext3 rw,errors=panic,data=ordered 0 0 /dev/md7 /dev/shm/tmp/1 ext3 rw,errors=panic,data=ordered 0 0 pioodl() tries to umount /tmp/1/2/3 /tmp/1/2 /tmp/1 and fails. With this patch the script tries to umount /tmp/1 /tmp/1/2 /tmp/1/2/3 and succeeds. /etc/init.d/umountnfs.sh does it this way too and looking at the source /bin/umount takes the mountpoint and examines /etc/mtab backwards which sort of ties in with my thinking. Cheers, Tim.
--- /etc/init.d/umountfs.orig 2008-03-01 23:14:14.000000000 +0000 +++ /etc/init.d/umountfs 2009-06-03 13:33:23.526666879 +0100 @@ -16,48 +16,6 @@ umask 022 -# Print in order of decreasing length -# -# Algorithm: Find and print longest argument, then call self -# to print remaining arguments in order of decreasing length -# -# This function runs at one tenth the speed of the sort program -# but we use the function because we don't want to rely on any -# programs in /usr/. -# -# N.B.: Arguments must not be null and must not contain whitespace -# -pioodl() { - [ "$1" ] || return 0 - ARGNUM=1 - ARGNUM_LONGEST=0 - ARGLENGTH_LONGEST=0 - for ARG in "$@" - do - ARGLENGTH="${#ARG}" - if [ "$ARGLENGTH" -gt "$ARGLENGTH_LONGEST" ] - then - ARGLENGTH_LONGEST="$ARGLENGTH" - ARGNUM_LONGEST="$ARGNUM" - fi - ARGNUM=$(($ARGNUM + 1)) - done - # The method of passing prevargs assumes that args can be - # delimited with spaces - ARGNUM=1 - PREVARGS="" - while [ "$ARGNUM" -lt "$ARGNUM_LONGEST" ] - do - PREVARGS="$PREVARGS $1" - shift - ARGNUM=$(($ARGNUM + 1)) - done - echo "$1" - shift - pioodl $PREVARGS "$@" -} - - do_stop () { exec 9<&0 </proc/mounts @@ -85,10 +43,10 @@ continue ;; tmpfs) - TMPFS_MTPTS="$TMPFS_MTPTS $MTPT" + TMPFS_MTPTS="$MTPT $TMPFS_MTPTS" ;; *) - REG_MTPTS="$REG_MTPTS $MTPT" + REG_MTPTS="$MTPT $REG_MTPTS" ;; esac done @@ -102,7 +60,6 @@ # if [ "$TMPFS_MTPTS" ] then - TMPFS_MTPTS="$(pioodl $TMPFS_MTPTS)" if [ "$VERBOSE" = no ] then log_action_begin_msg "Unmounting temporary filesystems" @@ -134,7 +91,6 @@ # if [ "$REG_MTPTS" ] then - REG_MTPTS="$(pioodl $REG_MTPTS)" if [ "$VERBOSE" = no ] then log_action_begin_msg "Unmounting local filesystems"