Anyone who might be intersted,
I have the situation where, using submounts to simulate direct mounts,
automount 3.1.7 exits leaving busy mounts when one of our Solaris NFS
servers is rebooted. This is bad because I cannot unmount the busy mount
(long runing job) and so the automounter cannot recover. There may be a
problem with the client NFS but I have not looked into that yet. Instead
I have chosen to try to get the automounter to handle the situation.
After examining the 3.1.7 and 4.0.0pre10 source I concluded that the
later is less likely to exit under adverse conditions.
In using submounts with 4.0.0pre10 I found a couple of problems. My
changes to the source are in the attached patch(es).
1. Submount points have a "/" appended to them causing the expire not to
work.
parse_sun.c @@ -522,7 +522,10 @@
2. The assertion in st_prepare_shutdown is incorrect as the automounter
can go from a state ST_EXPIRE to ST_PREPARE_SHUTDOWN in the case of a
submount.
automount.c @@ -764,7 +764,7 @@
3. The timeout is not propagated to submounts and is always the default
for submounts (also the case in 3.1.7). My code for this is tacky, but
it is simple and it works for me.
The rest of the patch.
Another problem is, when shuting down, it is necessary to umount the
submounts depth first to avoid error messages and allow a clean
shutdown. This probably should ne handled by the daemon. I have only
changed the rc script to handle this (second patch).
Any suggestions or comments are welcome.
--
,-._|\ Ian Kent
/ \ Perth, Western Australia
*_.--._/ E-mail: [EMAIL PROTECTED], [EMAIL PROTECTED]
v Web: http://pobox.com/~ian.kent
diff -Nur autofs-4.0.0pre10.orig/daemon/automount.c
autofs-4.0.0pre10/daemon/automount.c
--- autofs-4.0.0pre10.orig/daemon/automount.c Wed Mar 28 13:08:23 2001
+++ autofs-4.0.0pre10/daemon/automount.c Sun Aug 26 19:19:17 2001
@@ -764,7 +764,7 @@
DB(syslog(LOG_INFO, "prep_shutdown: state = %d\n",
ap.state));
- assert(ap.state == ST_READY);
+ assert(ap.state == ST_READY || (submount && ap.state == ST_EXPIRE));
/* Turn off timeouts */
alarm(0);
@@ -1235,6 +1235,10 @@
return val;
}
+unsigned get_timeout(void) {
+ return ap.exp_timeout;
+}
+
static void usage(void)
{
fprintf(stderr, "Usage: %s [options] path map_type [args...]\n", program);
diff -Nur autofs-4.0.0pre10.orig/modules/mount_autofs.c
autofs-4.0.0pre10/modules/mount_autofs.c
--- autofs-4.0.0pre10.orig/modules/mount_autofs.c Wed Mar 28 13:08:23 2001
+++ autofs-4.0.0pre10/modules/mount_autofs.c Sun Aug 26 19:16:51 2001
@@ -27,6 +27,19 @@
#define MODPREFIX "mount(autofs): "
int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
+extern int get_timeout(void);
+
+int num_length(unsigned num) {
+ int i = 1;
+ int divisor = 10;
+
+ while (num / divisor) {
+ i++;
+ divisor *= 10;
+ }
+ return i;
+}
+
int mount_init(void **context)
{
return 0;
@@ -40,7 +53,17 @@
int argc, status;
char *options, *p;
pid_t slave, wp;
+ unsigned timeout = get_timeout();
+ char *option_timeout;
+ /* Allocate space for --timeout option */
+ option_timeout = alloca(num_length(timeout)+11+1);
+ if ( !option_timeout ) {
+ syslog(LOG_ERR, MODPREFIX "alloca: %m");
+ return 1;
+ }
+ sprintf(option_timeout, "--timeout=%d", timeout);
+
fullpath = alloca(strlen(root)+name_len+2);
if ( !fullpath ) {
syslog(LOG_ERR, MODPREFIX "alloca: %m");
@@ -65,12 +88,12 @@
return 1;
}
- syslog(LOG_DEBUG, MODPREFIX "fullpath=%s what=%s options=%s",
- fullpath, what, options);
+ syslog(LOG_DEBUG, MODPREFIX "option_timeout=%s fullpath=%s what=%s options=%s",
+ option_timeout,fullpath, what, options);
/* Build our argument vector. */
- argc = 5;
+ argc = 6;
if ( options ) {
char *p = options;
do {
@@ -83,6 +106,7 @@
argc = 0;
argv[argc++] = PATH_AUTOMOUNT;
argv[argc++] = "--submount";
+ argv[argc++] = option_timeout;
argv[argc++] = fullpath;
argv[argc++] = strcpy(alloca(strlen(what)+1), what);
diff -Nur autofs-4.0.0pre10.orig/modules/parse_sun.c
autofs-4.0.0pre10/modules/parse_sun.c
--- autofs-4.0.0pre10.orig/modules/parse_sun.c Wed Mar 28 13:08:23 2001
+++ autofs-4.0.0pre10/modules/parse_sun.c Sun Aug 26 19:16:51 2001
@@ -522,7 +522,10 @@
}
mountpoint = alloca(namelen + pathlen + 2);
- sprintf(mountpoint, "%.*s/%.*s", namelen, name, pathlen, path);
+ if (pathlen)
+ sprintf(mountpoint, "%.*s/%.*s", namelen, name, pathlen, path);
+ else
+ sprintf(mountpoint, "%.*s", namelen, name);
what = alloca(loclen + 1);
memcpy(what, loc, loclen);
diff -Nur autofs-4.0.0pre10.orig/samples/rc.autofs.in
autofs-4.0.0pre10/samples/rc.autofs.in
--- autofs-4.0.0pre10.orig/samples/rc.autofs.in Wed Mar 28 13:08:23 2001
+++ autofs-4.0.0pre10/samples/rc.autofs.in Mon Aug 27 23:58:31 2001
@@ -159,6 +159,41 @@
}
#
+# Find pid of deepest nested submount
+#
+function get_deepest_submount()
+{
+ ps axw|grep $DAEMON|\
+ grep submount|\
+ sed -e 's/--timeout[ =][0-9]*//g'|\
+ awk '{print $7,$1}'|\
+ sort -r|\
+ awk 'BEGIN {ORS=" "} {print $2}'|\
+ awk '{print $1}'
+}
+
+#
+# Signal each nested submount
+#
+function signal_submounts()
+{
+ tries=0
+ pid=`get_deepest_submount`
+ while [ -n "$pid" -a $tries -lt 3 ]; do
+ oldpid=$pid
+ kill -USR2 $pid
+ sleep 1
+ pid=`get_deepest_submount`
+ if [ "$oldpid" = "$pid" ]; then
+ tries=`expr $tries + 1`
+ else
+ tries=0
+ fi
+ done
+ echo $pid
+}
+
+#
# Redhat start/stop function.
#
function redhat()
@@ -177,22 +212,27 @@
fi
;;
stop)
- pids=$(/sbin/pidof $DAEMON)
- kill -TERM $pids 2> /dev/null && sleep 1
- count=1
- while alive $pids; do
- sleep 5
- count=$(expr $count + 1)
- if [ $count -gt 5 ]; then
- echo "Giving up on automounter"
- break;
- fi
- echo "Automounter not stopped yet: retrying... (attempt $count)"
- done
- if [ $count -gt 1 -a $count -le 10 ]; then
- echo "Automounter stopped"
+ # Clear submounts first ...
+ if [ -z "`signal_submounts`" ]; then
+ pids=$(/sbin/pidof $DAEMON)
+ kill -TERM $pids 2> /dev/null && sleep 1
+ count=1
+ while alive $pids; do
+ sleep 5
+ count=$(expr $count + 1)
+ if [ $count -gt 5 ]; then
+ echo "Giving up on automounter"
+ break;
+ fi
+ echo "Automounter not stopped yet: retrying... (attempt $count)"
+ done
+ if [ $count -gt 1 -a $count -le 10 ]; then
+ echo "Automounter stopped"
+ fi
+ rm -f /var/lock/subsys/autofs
+ else
+ echo "Automounter submounts busy ... manual stop needed"
fi
- rm -f /var/lock/subsys/autofs
;;
reload|restart)
if [ ! -f /var/lock/subsys/autofs ]; then