Here is a script you can run in the background that will automatically detect your network shares as they dynamically come and go from the network, and respond accordingly (i.e., mounting them when the networked connection is available, and unmount it when it disappears). I find this useful for my laptop (which travels) and my desktop (which doesn't, but connects to several other computers that may or may not be on/present at any moment). This approach does not require editing /etc/fstab, so may be of interest to those who simply do not wish to mess with that file, even if the network connects are always active. This method also addresses a bug in Ubuntu 7.04 and below, and sometimes 7.10, where active network shares create large delays in the shutdown process. As this approach uses only tools available to most/all Linux distros (certainly any Debian-based distro), it does not really depend on any particular version of Ubuntu.
Updated 27 June 2008 (see bottom of post for history/changes).
Note to those who used versions prior to 27 June 2008: the /etc/automount.bash script is now /usr/local/bin/automount; remove the /etc/automount.bash file and replace with the new /usr/local/bin/automount and update /etc/init.d/automount.
Please post all requests for help to the forum rather than as a private message, as if you have the question, chances are others will as well.
This howto replaces a previous howto of a similar nature for most, but not all applications, so I've created this new thread instead of replacing the old one: http://ubuntuforums.org/showpost.php?p=2243984
I am not going to explain how to get operational mounts. There are already several locations that do a good job of explaining the process, such as:
http://ubuntuforums.org/showthread.php?t=288534
http://doc.gwos.org/index.php/HowToM...resPermanently
http://www.ubuntuforums.org/showthread.php?t=280473
Three pieces are necessary for your shares to connect dynamically, aside from working network connections and the like. I will not explain how to generate a working mount command line, as there are already several guides in the forums and elsewhere (see above). Assuming that you have a working mount command line and wish to automate the (un)mounting:
1. Copy the following code and create a file called /etc/automount.conf (using sudo and your favorite editor), then replace my sample configuration with your own, using the examples and comments for guidance:
The .credentials files are a more secure way of storing username and password; see links below for details. In the example cases (which are all samba/cifs, but need not be), the first mount does not automtaically create and destroy the mount point, so the folder must exist. The other two will automatically create and destroy the mount point as the connections come and go. Note that although I use IP addresses in the examples above, if you are running a wins server, have a local dns server, run dnsmasq on your router, or have the necessary information in your /etc/hosts file, you can use relative names instead of IP addresses directly. (If you use relative addresses using wins and/or dns, you may get "unknown host" errors when trying to ping computers that are not currently online, but this is not a problem.)Code:# all lines that begin with comments (#) or are entirely blank are ignored # the order of the options, share, and mount do not matter; autocreate cannot be first # avoid excess white space at beginning or end of the options, share, and mount lines # lines beginning with autocreate turn on autocreation (and auto removal) of the last mount directory # Note that autocreation may sometimes fail to remove the mount directory if unmounting # is not complete when it tries to delete it. This will not cause any side effects. # lines beginning with - are options lines # lines beginning with // are share lines # lines beginning with delay= set the delay between pings on the shares (in seconds) # This line can appear anywhere, and multiple times, but only the last value is saved # If the line is absent, the script defaults to a value of 60 # all other lines are assumed to be the mount location line # Due to limitations in matching existing mounts, no mount location should be a match # for a substring of a second mount # e.g., don't mount /media/blah and /media/blah2 or /blah # e.g., /media/blah, /media/2blah, and /mount/blah are all fine concurrently delay=60 # desktopwired -t cifs -o credentials=/etc/.credentials2,user,rw,uid=1000 //192.168.10.171/c /media/deskwired # laptop -t cifs -o credentials=/etc/.credentials1,user,rw,uid=1000 //192.168.10.180/c /media/laptop autocreate # laptop2 -t cifs -o credentials=/etc/.credentials0,user,rw,uid=1000 //192.168.100.181/c /media/laptop2 autocreate
2. Copy the following code and (using sudo and your favorite editor), create a file called /usr/local/bin/automount:
then:Code:#! /bin/bash # This periodically reads mtab check the status of nework shares, # and unmounts recently inactive shares. All inactive shares are then issued a # ping. Responsive systems are then mounted. if [ $1 == start ] then Command=0 # start else if [ $1 == stop ] then Command=1 # stop else echo "Usage: automount {start|stop} FILE [-v]" echo " Recommend usage is via /etc/init.d/automount." echo " FILE is requried and should be the location of the configuration file." echo " -v enables verbose mode to monitor process." echo exit 1 fi fi Delay=60 # default number of seconds between checks ConfFile=$2 if [ "$3" == "-v" ] then VerboseMode=1 else VerboseMode=0 fi # Read configuration file to get shares i=0 # tracks number of shares/mounts j=0 # tracks information for each share/mount to ensure gathers enough while read line do if [ `echo ${line}|grep -c '^[[:blank:]]*#'` -eq 0 ] # not a comment then if [ `echo ${line}|grep -c '[[:alnum:]]'` -eq 1 ] # not a blank line (strictly, a line that contains letters or numbers) then if [ `echo ${line}|grep -c '^[[:blank:]]*autocreate'` -eq 1 ] # autocreate tag then ShareMountAuto[$i]=1 # set autocreate on else if [ `echo ${line}|grep -c '^delay='` -eq 1 ] # delay line then Delay=`echo ${line}|awk -F = '{print $2;}'` else if [ $j == 3 ] # last share has completed information, start a new share then (( i++ )) # increment shares j=1 # reset information counter ShareMountAuto[$i]=0 # default no autocreate else (( j++ )) # increment information counter fi if [ `echo ${line}|grep -c '^//'` -eq 1 ] # share line then ShareAddresses[$i]=`echo "${line}"|awk -F / '{print $3;}'` Shares[$i]=${line} else if [ `echo ${line}|grep -c '^-'` -eq 1 ] # mount options line then ShareMountOptions[$i]=${line} else ShareMounts[$i]=${line} # assume mount line fi fi fi fi fi fi done < $ConfFile if [ $VerboseMode == 1 ] then # output result of parsing configuration file echo "Parsing $ConfFile produced following mount commands:" for (( i = 0 ; i < ${#Shares[@]} ; i++ )) do if [ ${ShareMountAuto[$i]} == 1 ] then echo " (Autocreate)" ${ShareMountOptions[$i]} "${Shares[$i]}" "${ShareMounts[$i]}" else echo " " ${ShareMountOptions[$i]} "${Shares[$i]}" "${ShareMounts[$i]}" fi done fi if [ $Command -eq 0 ] # start then # Check status of all shares, every Delay seconds while [ 1 ] do for (( i = 0 ; i < ${#Shares[@]} ; i++ )) do if [ $VerboseMode == 1 ] then echo echo "Checking ${Shares[$i]}" fi if [ `grep -c "${ShareMounts[$i]}" /etc/mtab` -ne 0 ] # share is mounted, make sure still live then if [ $VerboseMode == 1 ] then echo " ${Shares[$i]} is mounted" fi if [ $VerboseMode == 1 ] then ping -c 1 "${ShareAddresses[$i]}" else ping -c 1 "${ShareAddresses[$i]}" > /dev/null fi if [ $? -ne 0 ] # ping failed then if [ $VerboseMode == 1 ] then echo " ${ShareAddresses[$i]} ping failed, beginning unmount" fi if [ $VerboseMode == 1 ] then umount -l "${ShareMounts[$i]}" # unmount else umount -l "${ShareMounts[$i]}" > /dev/null # unmount fi if [ ${ShareMountAuto[$i]} == 1 ] # auto create directory then if [ $VerboseMode == 1 ] then echo " removing ${ShareMounts[$i]}" fi if [ $VerboseMode == 1 ] then rmdir ${ShareMounts[$i]} # delete mount directory else rmdir ${ShareMounts[$i]} 2> /dev/null # delete mount directory fi fi else if [ $VerboseMode == 1 ] then echo " ${ShareAddresses[$i]} ping succeeded, keeping mount" fi fi else # share is not mounted if [ $VerboseMode == 1 ] then echo " ${Shares[$i]} is not mounted" fi if [ $VerboseMode == 1 ] then ping -c 1 "${ShareAddresses[$i]}" else ping -c 1 "${ShareAddresses[$i]}" > /dev/null fi if [ $? -eq 0 ] # ping succeeded then if [ $VerboseMode == 1 ] then echo " ${ShareAddresses[$i]} ping succeeded, beginning mount" fi if [ ${ShareMountAuto[$i]} == 1 ] # auto create directory then if [ $VerboseMode == 1 ] then echo " creating ${ShareMounts[$i]}" fi mkdir "${ShareMounts[$i]}" # create mount directory fi if [ $VerboseMode == 1 ] then echo " mounting ${ShareAddresses[$i]}" fi mount ${ShareMountOptions[$i]} "${Shares[$i]}" "${ShareMounts[$i]}" # mount else if [ $VerboseMode == 1 ] then echo " ${ShareAddresses[$i]} ping failed, not mounting" fi fi fi done if [ $VerboseMode == 1 ] then echo echo "Waiting $Delay seconds...." fi sleep $Delay # sleep until next round of pings done else # stop # Unmount all shares, whether known to be mounted or not if [ $VerboseMode == 1 ] then echo echo "Unmounting all automount shares..." fi for (( i = 0 ; i < ${#ShareMounts[@]} ; i++ )) do umount -l "${ShareMounts[$i]}" 2> /dev/null # unmount if [ ${ShareMountAuto[$i]} == 1 ] # auto create directory then if [ $VerboseMode == 1 ] then rmdir "${ShareMounts[$i]}" # remove mount directory else rmdir "${ShareMounts[$i]}" 2> /dev/null # remove mount directory fi fi done fi exit 0
to make it executable.Code:sudo chmod 755 /usr/local/bin/automount
3: Copy the following and (using sudo and your favorite editor) paste it into a file called /etc/init.d/automount:
then:Code:#! /bin/sh ### BEGIN INIT INFO # Provides: N/A # Required-Start: $remote_fs # Required-Stop: $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Automounts SAMBA shares # Description: Dynamically (un)mounts specific SAMBA shares. ### END INIT INFO # Set info for messages DESC="Automount shares" NAME=automount SCRIPTNAME=/etc/init.d/$NAME DAEMON=/usr/local/bin/$NAME PIDFILE=/var/run/$NAME.pid # Exit if the daemon script is not installed [ -x "$DAEMON" ] || exit 0 # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions do_start() { echo "Starting automount..." start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1 start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- start $ConfFile || return 2 } do_stop() { echo "Stopping automount and unmounting..." start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Execute again w/ stop to unmount all $DAEMON stop $ConfFile rm -f $PIDFILE return "$RETVAL" } do_pause() { echo "Stopping automount..." start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 rm -f $PIDFILE return "$RETVAL" } if [ "$2" = "" ] # no config file passed then ConfFile=/etc/automount.conf # default configuration file else ConfFile=$2 fi case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac exit "$?" ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac exit "$?" ;; force-reload|restart) [ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 1) [ "$VERBOSE" != no ] && log_end_msg 1 ;; # Old process is still running *) [ "$VERBOSE" != no ] && log_end_msg 1 ;; # Failed to start esac exit "$?" ;; *) # Failed to stop [ "$VERBOSE" != no ] && log_end_msg 1 exit "$?" ;; esac ;; pause) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_pause case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac exit "$?" ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|pause} [FILE]" echo " /etc/automount.conf will be used if FILE is not specified." exit 3 ;; esac exit
to make it executable.Code:sudo chmod 755 /etc/init.d/automount
then:
to automatically start and stop the (un)mounting script upon boot and shutdown.Code:sudo update-rc.d automount defaults 99 01
Uninstallation:
Delete the three files you created, then:
---Additional notes---Code:sudo update-rc.d automount remove
This approach assumes that either the computer is used by a single user, or that all users will share the shares. Unfortunately, due to the fact that mount requires root access, there is not a simple way to implement this in user space. I am working on a revised script that will deal with this problem, but it may take a while. In the meantime, you can either use the old version linked above, or a similar approach using these files. First, create your automount.conf in a local directory. Skip step 3; instead, use:
to invoke the script upon logging in, where FILE is the path to your automount.conf file. (For logging out, replace "start" with "stop" in your logout script file, or just ignore it and let the shares be taken of by normal procedures upon shutdown.) You will then also need to chmod +s the appropriate mount commands as described in http://ubuntuforums.org/showpost.php?p=2243984.Code:automount start FILE
You could also make use of the ability to pass a config file to automount, so that intead of the above, you can use the full setup only without creating the /etc/automount.conf file, so that /etc/init.d/automount simply fails to start upon boot, then invoke /etc/init.d/automount start FILE upon each user login, where FILE is their personal config file, the problem being that /etc/init.d/automount must be started with root priveleges, so users need to enter the root password - it may be possible to set up a system using keyring logins, etc. to avoid the need for manual entry here, but I'm going to leave that purely as an exercise for anyone wanting to try it.
See http://ubuntuforums.org/showpost.php...5&postcount=14 for an example of how to start/stop the script only when connected to the network, so you aren't pinging endlessly for no reason. The example uses the old version of this script, but you can use /etc/init.d/automount start and /etc/init.d/automount stop to start and stop the scripts instead of the commands given.
automount can be invoked directly with detailed monitoring of processes using
or (assuming /usr/local/bin is in your path, which it should be)Code:sudo /usr/local/bin/automount start /etc/automount.conf -v
to troubleshoot mounts that don't appear to be working.Code:sudo automount start /etc/automount.conf -v
---History---
2007-12-10: Original post
2008-01-21: Fixed issue with paths containing spaces in automount.bash
2008-01-25: Added verbose mode to automount.bash, made passing of config file to automount.bash mandatory, and added ability to pass config file to automount
2008-05-11: Minor updates to text, no changes to scripts.
2008-06-27: Revised /etc/init.d script to conform to Debian standards. Relocated main script to /usr/local/bin/automount instead of /etc/automount.bash, and modified output to silence most errors/standard out messages unless -v passed to script.



Adv Reply



Bookmarks