Sunday, October 4, 2009

Wake-on-lan (WOL) & NFS Mounts (3)

Fixed the script up to work with autofs & made sure that we use Bash (got an Ubuntu machine here that uses Dash by default and it doesn't like the substring directive ${var:0:3} in the script.

So here it is:

--
#!/bin/bash                          

# require: nmap, etherwake, nfs-common, bash, hostname, bsdutils and some other core packages.

# perform a WOL before doing an NFS-mount.
# This scripts extends mount.nfs to also understand a wol= option to wake
# a specific machine before performing the mount. The mount is performed     
# after the machine is actually detected on the network. For this a nmap     
# scan is performed 10 times with a 30 second interval to see if the mac     
# becomes alive.                                                             
#                                                                            
# After a mount is performed  file is written to the local mountpoint in     
# a subdirectory active-clients/ with the name of the host (hostname)        
# When an unmount is received this file is removed and the unmount is performed.
#                                                                              
# Installation:                                                                
# Store the script in /usr/local/sbin/mount.nfs.wol                            
# move /sbin/mount.nfs to /sbin/mount.nfs.orig                                 
# make a symlink for /sbin/mount.nfs to this script                            
# make a symlink for /sbin/umount.nfs to this script                           

# Parameters
ORIG_MOUNT=/sbin/mount.nfs.orig
ORIG_UMOUNT=/sbin/umount.nfs.orig
ETHER_SEGMENT=192.168.200.0/24  

# No user servicable parts below
progname=`basename $0`         

case "$progname" in
        mount.nfs)
                # $1=remotetarget, $2=dir, $3+ are the arguments. We only want to read the -o argument in detail.
                remotetarget=$1                                                                                 
                localtarget=$2                                                                                  
                shift                                                                                           
                # shift # we start the loop with a shift, so skip this one.                                     
                target_args=                                                                                    

                while shift
                do        
                        case "$1" in
                        -o)        
                                # We need to parse the argument passed to -o
                                shift

                                o_args=
                                args=`echo $1 | tr ',' ' '`
                                for f in ${args}
                                do
                                        optpart=${f:0:3}
                                        if [ "wol" = "${optpart}" ]
                                        then
                                                wol=`echo ${f} | cut -f 2 -d=`
                                        else
                                                if [ ! -z "${o_args}" ]
                                                then
                                                        o_args="${o_args},"
                                                fi
                                                o_args="${o_args}${f}"
                                        fi

                                done
                                target_args="${target_args} -o ${o_args}"
                                ;;
                        *)
                                target_args=${target_args}" "${1}
                                ;;
                        esac
                done

                # Only try to wake the target server if a wol is specified.
                if [ ! -z "${wol}" ]
                then
                        # Wol is specified with a dot instead of a colon: autofs makes a mess of it.
                        wol=`echo ${wol} | tr [:lower:] [:upper:] | tr '.' ':'`
                        logger nfs-mount requires WOL of ${wol}
                        # Wake the machine and loop a while
                        for counter in 0 1 2 3 4 5 6 7 8 9
                        do
                                etherwake ${wol}
                                nmap -sP ${ETHER_SEGMENT} 2>&1 | fgrep ${wol} >/dev/null
                                if  [ "$?" = "0" ]
                                then
                                        break
                                else
                                        sleep 30
                                fi
                        done
                fi

                # Call the original binary & set a lockfile
                ${ORIG_MOUNT} ${remotetarget} ${localtarget} ${target_args} && su -c "touch ${localtarget}/active-clients/`hostname`" mythtv
                ;;

        umount.nfs)
                localtarget=$1
                su -c "rm ${localtarget}/active-clients/`hostname`" mythtv
                exec ${ORIG_UMOUNT} $@
                ;;
        *)
                echo "Unknown command: ${progname}"
                exit 1
                ;;
esac

--

No comments:

Post a Comment