From: Greg Ercolano <erco@(email surpressed)>
Subject: [OSX/ADMIN] Boot script to mount multiple file servers (NFS)
   Date: Wed, 03 Jun 2009 00:53:06 -0400
Msg# 1847
View Complete Thread (0 article) | All Threads
	Sometimes companies have multiple file servers/shares
	they want to have mounted up on boot of their OSX machines.

	The following shows a boot script for OSX that uses subroutines
	to handle the details of mounting, to make it easier to manage
	multiple mounts, so that there's just one mount command per line, eg:


    Mount 192.168.1.2:/jobs             /net/jobs     "intr,bg,resvport,vers=3"
    Mount 192.168.1.3:/Volumes/Prod1    /net/prod1    "intr,bg,tcp,vers=3"
    Mount 192.168.1.3:/Volumes/Prod2    /net/prod2    "intr,bg,tcp,vers=3"
    Mount 192.168.1.3:/Volumes/Prod3    /net/prod3    "intr,bg,tcp,vers=3"

	This is better for multiple mounts than the previous examples
	I posted last year, where to mount multiple servers you needed
	to have a paragraph of code for each mount, c.f.
        http://seriss.com/cgi-bin/rush/newsgroup-threaded.cgi?-view+1710+1710+1731+1783

	Use of IP addresses is recommended in place of hostnames
        when specifying mounts, as DNS is often unstable during
        the boot process.

	The following describes how to create and install this boot script.
	Once working, the script can be copied to all your OSX machines to
	ensure each boots up with the same mounting scheme.

* * *

	1) Login as root, create a boot script directory called "MountFileServers":

mkdir -m 755 /Library/StartupItems/MountFileServers
chown 0:0    /Library/StartupItems/MountFileServers

	   It's important the perms are 755 and owned by root/wheel, as shown.

	2) 'cd' into that directory and create a "StartupParameters.plist" file:
	   with the perms carefully set to 644 and owned by root/wheel:

cd /Library/StartupItems/MountFileServers
touch StartupParameters.plist
chown 0:0 StartupParameters.plist
chmod 644 StartupParameters.plist
vi StartupParameters.plist

	   Here's what to paste into that file (leave out the 'snip' lines!).

--------------------------------------------------------- snip
{
  Description     = "Mounts the File Servers";
  Provides        = ("MountFileServers");
  Requires        = ("Network", "System Log", "Resolver");
  OrderPreference = "Last";
  Messages =
  {
    start = "Mounting local file server";
    stop  = "Unmounting local file server";
  };
}
--------------------------------------------------------- snip

	3) While you're in that same directory, create an executable
	   script called "MountFileServers", with the perms 755, root/wheel:

cd /Library/StartupItems/MountFileServers
touch MountFileServers
chown 0:0 MountFileServers
chmod 755 MountFileServers
vi MountFileServers

	   What follows is the contents of the "MountFileServers" script. 
           Be sure to customize the "Mount" and "Umount" lines to suit your environment.

	   When specifying mounts, it's best to use IP addresses instead of
           hostnames, as DNS lookups might not be fully operational at boot time, eg:

Mount helium:/jobs  /net/jobs  "intr,bg"         # BAD
      ^^^^^^
Mount 192.168.0.2:/jobs  /net/jobs  "intr,bg"    # GOOD
      ^^^^^^^^^^^

	   Here's the script:

--------------------------------------------------------- snip
#!/bin/sh

###
### Mount File Servers -- Set up local mounts for our file server
###
###      Save this file as /Library/StartupItems/MountFileServers/MountFileServers
###      and make sure the files/dirs are owned by root/wheel and modes are 755
###      (rwx-r-xr-x).
###
### 05/27/2009 erco@(email surpressed)
###

# SUBROUTINE: MOUNT A REMOTE DRIVE
#
#    NOTE: Use ip addresses in the remote device name, do NOT use hostnames.
#          This avoids assuming DNS fully operational during boot.
#          Often DNS is unstable during boot, even with boot dependencies.
#
Mount()
{
    remdrive="$1"		# $1 -- the remote drive,  eg. "192.168.1.10:/jobs"
    localdir="$2"		# $2 -- local mount point, eg. "/net/jobs"
    nfsflags="$3"		# $3 -- nfs flags, eg. "rw,intr,bg,vers=3"

    # ENSURE MOUNT POINT EXISTS
    if [ ! -d "$localdir" ]; then
	$LOGGER "Creating mount point $localdir"
	mkdir -p -m 755 "$localdir"
    fi

    # ALREADY MOUNTED? DONT MOUNT TWICE
    if mount | grep -q "$localdir"; then
	$LOGGER "$localdir already mounted"
    else
	$LOGGER "Mounting '$remdrive' on '$localdir'"
	( mount -t nfs -o "$nfsflags" "$remdrive" "$localdir" ) 2>&1 | $LOGGER
    fi
}

# SUBROUTINE: UNMOUNT THE SPECIFIED DRIVE
Umount()
{
    localdir="$1"		# $1 -- local mount point, eg. "/net/jobs"
    $LOGGER "Un-mounting '$localdir'"
    umount "$localdir" 2>&1 | $LOGGER
}

###
### MAIN
###
if [ -x /etc/rc.common ]; then . /etc/rc.common; fi
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec

if [ "`tty`" = "not a tty" ]; then LOGGER="logger    -t MountFileServers"
else                               LOGGER="logger -s -t MountFileServers"; fi

# Handle stop/start/restart
ARG1=${1:-start}                 # assume 'start' if unset
case "$ARG1" in

    start)
        ### MOUNT ALL SERVERS ON BOOT
	Mount 192.168.1.2:/jobs             /net/jobs     "intr,bg,resvport,vers=3"   # LINUX
	Mount 192.168.1.3:/Volumes/Prod1    /net/prod1    "intr,bg,tcp,vers=3"        # OSX/TCP
	Mount 192.168.1.3:/Volumes/Prod2    /net/prod2    "intr,bg,tcp,vers=3"        # OSX/TCP
	Mount 192.168.1.3:/Volumes/Prod3    /net/prod3    "intr,bg,tcp,vers=3"        # OSX/TCP
	Mount 192.168.1.3:/Volumes/STOCK    /net/stock    "intr,bg,tcp,vers=3"        # OSX/TCP
	Mount 192.168.1.4:/Volumes/admin    /net/admin    "intr,bg,vers=3"            # OSX
	Mount 192.168.1.4:/Volumes/personal /net/personal "intr,bg,vers=3"            # OSX
        ;;

    stop)
        ### UN-MOUNT ALL SERVERS ON SHUTDOWN
	Umount /net/jobs
	Umount /net/prod1
	Umount /net/prod2
	Umount /net/prod3
	Umount /net/stock
	Umount /net/admin
	Umount /net/personal
	;;

    restart)
        $0 stop
        $0 start
        ;;
    *)
        echo "usage: $0 {start|stop|restart}"
        exit 1
        ;;
esac
exit 0
--------------------------------------------------------- snip

        4) Now configure Rush to start *after* your mount script.

           Edit the Rush boot file /Library/StartupItems/Rush/StartupParameters.plist:

               vi /Library/StartupItems/Rush/StartupParameters.plist

           ..then find the line that reads:

                   Requires        = ("Network", "System Log", "Resolver");

           ..and add "MountFileServer" to the list, so that it now reads:

                   Requires        = ("Network", "System Log", "Resolver", "MountFileServers");

           Be sure to include the extra comma, so that the syntax is consistent.

	5) That's it.

	   You can test if the script works by running it as root
	   from your terminal with the start/stop options.

    To test the script to see that it mounts properly:

/Library/StartupItems/MountFileServers/MountFileServers start

    ..and to test that it unmounts properly, run:

/Library/StartupItems/MountFileServers/MountFileServers stop

    After each command, run 'mount' to verify the mounts appear
    and disappear correctly.

    Once working, test by actually rebooting the machine,
    and when you get a login, check the /var/log/system.log
    to make sure there are no errors, eg:

grep MountFileServers /var/log/system.log

    This is where any errors from your mount commands will appear,
    if there are any.

    Then you can install the boot script directory on the other
    OSX machines with a simple scp command, eg:

scp -rp /Library/StartupItems/MountFileServers HOST1:/Library/StartupItems/MountFileServers
scp -rp /Library/StartupItems/MountFileServers HOST2:/Library/StartupItems/MountFileServers
...etc..

    If you modified the Rush StartupParameters.plist file, you'll want to
    copy that change to the network as well:

scp -p /Library/StartupItems/Rush/StartupParameters.plist HOST1:/Library/StartupItems/Rush/
scp -p /Library/StartupItems/Rush/StartupParameters.plist HOST2:/Library/StartupItems/Rush/
...etc..

    Replace "HOST1" and "HOST2" with the remote hostnames.

    [The above has been tested to work equally well on Tiger (10.4),
     Leopard (10.5), Snow Leopard (10.6), Lion (10.7).. -erco 07/11/12]