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:
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
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.)
2. Copy the following code and (using sudo and your favorite editor), create a file called /usr/local/bin/automount:
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
then:
Code:
sudo chmod 755 /usr/local/bin/automount
to make it executable.
3: Copy the following and (using sudo and your favorite editor) paste it into a file called /etc/init.d/automount:
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
then:
Code:
sudo chmod 755 /etc/init.d/automount
to make it executable.
then:
Code:
sudo update-rc.d automount defaults 99 01
to automatically start and stop the (un)mounting script upon boot and shutdown.
Uninstallation:
Delete the three files you created, then:
Code:
sudo update-rc.d automount remove
---Additional notes---
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:
Code:
automount start FILE
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.
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
Code:
sudo /usr/local/bin/automount start /etc/automount.conf -v
or (assuming /usr/local/bin is in your path, which it should be)
Code:
sudo automount start /etc/automount.conf -v
to troubleshoot mounts that don't appear to be working.
---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.
Bookmarks