3 # $Id: rc.autofs.in,v 1.58 2005/04/11 11:30:54 raven Exp $
5 # rc file for automount using a Sun-style "master map".
6 # We first look for a local /etc/auto.master, then a YP
9 # On most distributions, this file should be called:
10 # /etc/rc.d/init.d/autofs or /etc/init.d/autofs
14 # Required-Start: $local_fs
15 # Required-Stop: $local_fs
16 # Default-Start: 2 3 4 5
18 # Short-Description: automount daemon
19 # Description: daemon to mount (possibly remote) filesystems
20 # automatically upon entering the mountpoint
23 # For Redhat-ish systems
25 # chkconfig: 345 28 72
26 # processname: /usr/sbin/automount
27 # config: /etc/auto.master
28 # description: Automounts filesystems on demand
30 # This is used in the Debian distribution to determine the proper
31 # location for the S- and K-links to this init file.
32 # The following value is extracted by debstd to figure out how to
33 # generate the postinst script. Edit the field to change the way the
34 # script is registered through update-rc.d (see the manpage for
40 # Location of the automount daemon and the init directory
42 DAEMON=/usr/sbin/automount
43 prog=`basename $DAEMON`
46 test -e $DAEMON || exit 0
49 # Determine which kind of configuration we're using
52 if [ -f /etc/redhat-release ]; then
56 if [ $system = redhat ]; then
60 if [ $system = debian ]; then
62 if [ ! -f "$thisscript" ]; then
63 echo "$0: Cannot find myself" 1>&2
68 PATH=/sbin:/usr/sbin:/bin:/usr/bin
72 # We can add local options here
73 # e.g. localoptions='rsize=8192,wsize=8192'
84 # load custom settings
86 if [ "$system" = "redhat" ]; then
93 [ -f /etc/sysconfig/autofs ] && . /etc/sysconfig/autofs
95 # Over-ride localoptions if set
96 if [ -n "$LOCALOPTIONS" ]; then
97 localoptions=$LOCALOPTIONS
100 # Over-ride daemonoptions if set
101 if [ -n "$DAEMONOPTIONS" ]; then
102 daemonoptions=$DAEMONOPTIONS
104 elif [ "$system" = "debian" ]; then
109 [ -f /etc/default/autofs ] && . /etc/default/autofs
111 daemonoptions="$daemonoptions --timeout=$TIMEOUT"
115 # Check for all maps that are to be loaded
119 SOURCES=`grep ^automount: /etc/nsswitch.conf | \
120 sed -e 's/^.*://' -e 's/\[.*\]/ /g'`
122 if [ `echo $SOURCES | awk '{print NF}'` -gt 0 ]
132 if [ -z "$1" ] ; then
138 # Append the map's options at the _start_ if there are any options already
139 # (ie. myopt -> $2,myopt), otherwise just append them at the end.
141 /usr/bin/ypcat -k "$map" 2> /dev/null | sed -e '/^#/d' -e '/^$/d'
143 /usr/bin/ypcat -k "$map" 2> /dev/null |
144 sed -e '/^#/d' -e '/^$/d' \
145 -e "s/^[ \t]*\([^ \t]\+\)[ \t]\+\([^ \t]\+\)[ \t]\+-\([^ \t]\+\)/\1 \2 $2,\3/" \
146 -e "s/^[ \t]*\([^ \t]\+\)[ \t]\+\([^ \t]\+\)[ \t]*$/\1 \2 $2/"
152 if [ -f /etc/auto.master ] ; then
153 cat /etc/auto.master | awk '{print $0}' | sed -e '/^#/d' -e '/^$/d' | (
154 while read auto_master_in
156 if [ "`echo $auto_master_in | grep '^\+'`" = "" ]; then
159 cat /etc/auto.master | grep '^\+' | sed -e '/^#/d' -e '/^$/d' | (
160 while read map options; do
161 catnismap `echo "$map" | sed -e 's/^\+//'` $options
172 YPMAP=`catnismap auto.master`
173 if [ -z "$YPMAP" ]; then
176 catnismap auto.master
182 if [ -x /usr/lib/autofs/autofs-ldap-auto-master ]; then
183 [ ! -z $LDAPURI ] && export LDAPURI="$LDAPURI"
184 [ ! -z $LDAPBASE ] && export LDAPBASE="$LDAPBASE"
185 /usr/lib/autofs/autofs-ldap-auto-master 2> /dev/null
186 /usr/lib/autofs/autofs-ldap-auto-master -m automountMap \
187 -e automount -n ou -k cn -v automountInformation 2> /dev/null
193 for scheme in `getschemes` ; do
196 if [ -z "$filescheme" ] ; then
203 if [ -z "$nisscheme" ] ; then
210 if [ -z "$ldapscheme" ] ; then
222 # This function will build a list of automount commands to execute in
223 # order to activate all the mount points. It is used to figure out
224 # the difference of automount points in case of a reload
232 while read dir map options
234 # These checks screen out duplicates and skip over directories
235 # where the map is '-'.
236 # We can't do empty or direct host maps, so don't bother trying.
238 # Strip trailing slashes from the dir line if it exists to aid
239 # in checking for duplicate maps
240 dir=`echo "$dir" | sed -e "s/\/*$//"`
242 if [ ! -z "$map" -a "$map" = "-hosts" ] ; then
246 if [ $DISABLE_DIRECT -eq 1 \
247 -a x`echo $dir | grep -E "^/-"` != 'x' ]
252 # If possible, canonicalise the path so it will always unmount
254 link=`readlink -f "$dir"`
255 if [ ! -z "$link" ]; then
259 # Do not include a map if it is a duplicate, maps on top of
260 # another map or another map, maps on top of it.
261 for knownmap in $knownmaps
263 if [ "`echo $dir/ | grep ^$knownmap`" != "" \
264 -o "`echo $knownmap | grep ^$dir/`" != "" \]
270 if [ ! -z "$dir" -a ! -z "$map" \
271 -a x`echo "$map" | cut -c1` != 'x-' ]
273 # If the options include a -t or --timeout, a -g or --ghost,
274 # a -v or --verbose or a -d or --debug paramter, then pull
275 # those particular options out.
276 : echo DAEMONOPTIONS OPTIONS $daemonoptions $options
278 if echo "$options" | grep -qE -- '\B-(t\b|-timeout\b=)' ;
280 startupoptions="--timeout=$(echo $options |\
281 sed 's/.*-\(t[^0-9]*\|-timeout\)[ \t=]*\([0-9][0-9]*\).*$/\2/g')"
282 elif echo "$daemonoptions" | grep -q -- '-t' ;
284 # It's okay to be sloppy with DAEMONOPTIONS as there is no
285 # possibility of conflicting with mount or map options.
286 startupoptions="--timeout=$(echo $daemonoptions | \
287 sed 's/.*--*t\(imeout\)*[ \t=]*\([0-9][0-9]*\).*$/\2/g')"
290 # Check for the ghost option
291 if echo "$daemonoptions $options" | grep -qE -- '\B-(g\b|-ghost\b)' ;
293 startupoptions="$startupoptions --ghost"
295 # Dont even deal with conflicts between --ghost and [no]browse
296 # Its just insane to configure things like that.
297 if echo "$options" | grep -qE -- '\B-browse\b' ;
299 startupoptions="$startupoptions --ghost"
302 if echo "$daemonoptions $options" | \
303 grep -qE -- '\B-(v\b|-verbose\b)' ;
305 startupoptions="$startupoptions --verbose"
309 if echo "$daemonoptions $options" | \
310 grep -qE -- '\B-(d\b|-debug\b)' ;
312 startupoptions="$startupoptions --debug"
315 # Other option flags are intended for maps.
316 mapoptions="$(echo "$daemonoptions $options" |\
317 sed 's/-\(t[^0-9]*\|-timeout\)[ \t=]*\([0-9][0-9]*\)//g' |
318 sed 's/-\(g\b\|-ghost\b\)//g' |
319 sed 's/-\(v\b\|-verbose\b\)//g' |
320 sed 's/-\(d\b\|-debug\b\)//g' |
321 sed 's/-\b\(no\)\?browse\b//g')"
323 # Break up the maptype and map, if the map type is specified
324 maptype=`echo $map | cut -f1 -d:`
325 # Handle degenerate map specifiers
326 if [ "$maptype" = "$map" ] ; then
327 if [ "$map" = "hesiod" -o "$map" = "userhome" -o "$map" = "ldap" ] ; then
330 elif [ "$map" = "multi" ] ; then
333 # elif echo "$map" | grep -q '^!'; then
334 # map=`echo "$map"| sed -e 's/^!//g'`
335 elif `echo $map | grep -q "^/"` && [ -x "$map" ]; then
337 elif [ -x "/etc/$map" ]; then
339 map=`echo /etc/$map | sed 's^//^/^g'`
340 elif `echo $map | grep -q "^/"` && [ -f "$map" ]; then
342 elif [ -f "/etc/$map" ]; then
344 map=`echo /etc/$map | sed 's^//^/^g'`
347 if [ "$UNDERSCORETODOT" = "1" ] ; then
348 map=`basename $map | sed -e s/^auto_home/auto.home/ -e s/^auto_mnt/auto.mnt/`
350 map=`basename $map | sed 's^//^/^g'`
354 map=`echo $map | cut -f2- -d:`
356 : echo STARTUPOPTIONS $startupoptions
358 : echo MAPTYPE $maptype
360 : echo MAPOPTIONS $mapoptions
361 : echo LOCALOPTIONS $localoptions
366 if [ x"$m" = x"--" ]; then
367 NEWOPTIONS="$NEWOPTIONS $localoptions --"
369 NEWOPTIONS="$NEWOPTIONS $m"
372 mapoptions=$NEWOPTIONS
374 echo "$DAEMON $startupoptions $dir $maptype $map $mapoptions $localoptions" | sed -e 's/ / /g' -e 's/ */ /g'
376 : echo ------------------------
377 knownmaps=" $dir/ $knownmaps"
388 echo -e $"Configured Mount Points:\n------------------------"
391 echo -e $"Active Mount Points:\n--------------------"
392 ps axwww|grep "[0-9]:[0-9][0-9] $DAEMON " | (
393 while read pid tt stat time command; do echo $command; done
397 get_command_from_pid()
399 ps ax | grep "[0-9]:[0-9][0-9] $DAEMON " | (
400 while read pid tt stat time command; do
401 if [ "$pid" = "$1" ] ; then
402 echo `echo "$command" | \
403 sed 's/--pid-file.*\.pid/ /'`
411 # return true if at least one pid is alive
418 if kill -0 $i 2> /dev/null; then
427 # Find pids of process group leaders
431 ps -eo pid,pgrp,cmd|grep $DAEMON|\
432 awk '{print $1,$2}'|\
435 if [ $pid -eq $pgrp ]
443 # Signal each automount process group leader
448 pgrp_pids=`get_pgrp_pids`
449 for pid in $pgrp_pids
451 kill -USR2 $pid 2 > /dev/null
453 while ps ax|grep -v grep|grep $pid >/dev/null
456 count=$(expr $count + 1)
457 if [ $count -gt $DAEMON_EXIT_WAIT ]; then
463 if [ -n "`pidof $DAEMON`" ] ; then
472 loops=`LC_ALL=C awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}' /proc/mounts`
473 automounts=`LC_ALL=C awk '!/^#/ && $1 ~ /^automount/ {print $2}' /proc/mounts`
477 # If a loop device is mounted into a subdir of the automount point,
481 match=`echo $l | grep -E "^$a[\$|/]" || true`
482 if [ -n "$match" ]; then
484 echo -n $"Unmounting loopback filesystem $match: "
485 loopdev=`LC_ALL=C grep $l /proc/mounts | awk '{print $1}'`
487 if [ $? -eq 0 ]; then
496 # If the loop device file exists under the automount point, umount
498 loopmnts=`LC_ALL=C awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}' /proc/mounts`
501 loopmnt=`losetup $l | awk -F\( '{print $2}' | awk -F\) '{print $1}'`
504 match=`echo $loopmnt | grep -E "^$a[\$|/]" || true`
505 if [ -n "$match" ]; then
507 echo -n $"Unmounting loopback filesystem $match: "
509 if [ $? -eq 0 ]; then
520 # Redhat start/stop function.
526 # See how we were called.
530 # Make sure the autofs filesystem type is available.
531 (grep -q autofs /proc/filesystems || /sbin/modprobe -k autofs4 || /sbin/modprobe -k autofs) 2> /dev/null
532 echo -n $"Starting $prog: "
533 TMP=`mktemp /tmp/autofs.XXXXXX` || { echo $"could not make temp file" >& 2; exit 1; }
534 getmounts | tee $TMP | sh
536 if [ -s $TMP ] ; then
537 if [ $RETVAL -eq 0 ] ; then
538 success "$prog startup"
540 failure "$prog startup"
542 [ $RETVAL = 0 ] && touch /var/lock/subsys/autofs
544 echo -n $"No Mountpoints Defined"
545 success "$prog startup"
551 echo -n $"Stopping $prog:"
552 if [ -z "`pidofproc $prog`" -a -z "`getmounts`" ]; then
560 while [ -n "`/sbin/pidof $DAEMON`" -a $count -lt 10 ] ; do
561 killproc $DAEMON -USR2 >& /dev/null
563 [ $RETVAL = 0 -a -z "`/sbin/pidof $DAEMON`" ] || sleep 3
564 count=`expr $count + 1`
566 umount -a -f -t autofs
567 rm -f /var/lock/subsys/autofs
568 if [ -n "`/sbin/pidof $DAEMON`" ] ; then
569 failure "$prog shutdown"
571 success "$prog shutdown"
580 if [ ! -f /var/lock/subsys/autofs ]; then
581 echo $"$prog not running"
585 echo $"Checking for changes to /etc/auto.master ...."
586 TMP1=`mktemp /tmp/autofs.XXXXXX` || { echo $"could not make temp file" >& 2; exit 1; }
587 TMP2=`mktemp /tmp/autofs.XXXXXX` || { echo $"could not make temp file" >& 2; exit 1; }
589 ps axwww|grep "[0-9]:[0-9][0-9] $DAEMON " | (
590 while read pid tt stat time command; do
591 echo "$command" >>$TMP2
592 if ! grep -q "^$command" $TMP1; then
593 if ! echo "$command" | grep -q -e --submount; then
594 kill -USR2 $pid 2> /dev/null
595 echo $"Stop $command"
598 kill -HUP $pid 2> /dev/null
599 echo $"Reload map $command"
603 cat $TMP1 | ( while read x; do
604 if ! grep -q "^$x" $TMP2; then
615 [ -f /var/lock/subsys/autofs ] && redhat restart
619 echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
625 # Debian start/stop functions.
632 echo -n 'Starting automounter:'
634 # make sure autofs4 is loaded
635 if ! grep -q autofs /proc/filesystems
637 # autofs filesystem support not loaded
638 echo -n ' loading autofs4 kernel module,'
639 modprobe autofs4 || true
640 elif ([ -f /proc/modules ] && lsmod) | grep -q autofs[^4]; then
641 # wrong autofs filesystem module loaded
643 echo "WARNING: autofs kernel module is loaded, autofs4 needed"
644 echo " for correct behaviour. You might experience mount failures."
647 # Check that maps exist
648 if [ -z "$(getrawmounts)" ]
650 echo " no automount maps defined."
654 # ensure pid file directory exists
655 if [ ! -e /var/run/autofs ]
657 mkdir /var/run/autofs
660 getmounts | while read cmd rest
662 mnt=`echo $rest | sed 's/^.* \(\/[^ ]*\) [A-Za-z].*$/\1/'`
663 pidfile=/var/run/autofs/`echo $mnt | sed 's,/,_,g'`.pid
665 start-stop-daemon --start --pidfile $pidfile --quiet \
666 --exec $DAEMON -- --pid-file=$pidfile $rest
673 echo " failed to start automount point $mnt"
680 echo -n 'Stopping automounter:'
685 for file in `ls /var/run/autofs/*.pid 2>/dev/null`
690 pid=`head -n 1 $file`
691 mnt=`ps -wwo 'cmd=' $pid | sed -e \
692 's,.* --pid-file=/var/run/autofs/\([^ ]*\)\.pid.*,\1,; s,_,/,g'`
693 dname=`basename $DAEMON`
695 start-stop-daemon --stop --quiet \
696 --retry USR2/$DAEMON_EXIT_WAIT \
697 --pidfile $file --name $dname
707 echo -n -e "\n No process for automount $mnt"
711 echo -n -e "\n Couldn't stop automount for $mnt"
715 "\n Strange start-stop-daemon exit status: $ret"
724 echo "Reloading automounter: checking for changes ... "
726 TMP1=`mktemp -t autofs.XXXXXX`
727 TMP2=`mktemp -t autofs.XXXXXX`
731 for i in `ls /var/run/autofs/*.pid 2>/dev/null`
733 pid=`head -n 1 $i 2>/dev/null`
734 [ "$pid" = "" ] && continue
736 cmd=`get_command_from_pid $pid`
739 mnt=`ps -wwo 'cmd=' $pid | sed -e \
740 's,.* --pid-file=/var/run/autofs/\([^ ]*\)\.pid.*,\1,; s,_,/,g'`
742 if ! grep -q "$cmd" $TMP1; then
743 echo "Stopping automounter for: $mnt"
744 kill -USR2 $pid 2> /dev/null
746 echo "Reloading automounter map for: $mnt"
747 kill -HUP $pid 2> /dev/null
751 cat $TMP1 | (while read x; do
752 if ! grep -q "^$x" $TMP2; then
753 echo $x | while read cmd rest; do
755 mnt=`echo $rest | sed 's/^.* \(\/[^ ]*\) [A-Za-z].*$/\1/'`
756 pidfile=/var/run/autofs/`echo $mnt | sed 's,/,_,g'`.pid
758 start-stop-daemon --start --pidfile $pidfile --quiet \
759 --exec $DAEMON -- --pid-file=$pidfile $rest
766 echo " failed to start automount point $mnt"
768 echo "Started automounter: $mnt"
776 force-reload|restart)
790 echo "Usage: $initdir/autofs {start|stop|restart|reload|status|getmounts|active}" >&2
797 if [ $system = debian ]; then
799 elif [ $system = redhat ]; then