changeset 4092:c859d126a342

6513455 automounter is not responding to interrupts correctly 6537615 autofs can initialize the global data structure in multiple places
author evanl
date Mon, 23 Apr 2007 18:54:07 -0700
parents dba66edc4d9d
children 0cffd8004e71
files usr/src/uts/common/fs/autofs/auto_subr.c usr/src/uts/common/fs/autofs/auto_sys.c usr/src/uts/common/fs/autofs/auto_vfsops.c usr/src/uts/common/sys/fs/autofs.h
diffstat 4 files changed, 59 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/autofs/auto_subr.c	Mon Apr 23 18:01:19 2007 -0700
+++ b/usr/src/uts/common/fs/autofs/auto_subr.c	Mon Apr 23 18:54:07 2007 -0700
@@ -88,8 +88,6 @@
 static int auto_mount_request(fninfo_t *, char *, action_list **, cred_t *,
     bool_t);
 
-extern struct autofs_globals *autofs_zone_init(void);
-
 /*
  * Clears the MF_INPROG flag, and wakes up those threads sleeping on
  * fn_cv_mount if MF_WAITING is set.
@@ -314,7 +312,6 @@
 	autofs_thr_success++;
 }
 
-
 int
 auto_calldaemon(
 	zoneid_t 		zoneid,
@@ -337,6 +334,8 @@
 	int			orig_reslen = reslen;
 	autofs_door_args_t	*xdr_argsp;
 	int			xdr_len = 0;
+	int			printed_not_running_msg = 0;
+	klwp_t			*lwp = ttolwp(curthread);
 
 	/*
 	 * We know that the current thread is doing work on
@@ -354,10 +353,37 @@
 		return (ECONNREFUSED);
 	}
 
-	if ((fngp = zone_getspecific(autofs_key, curproc->p_zone)) ==
-	    NULL) {
-		fngp = autofs_zone_init();
-		(void) zone_setspecific(autofs_key, curproc->p_zone, fngp);
+	do {
+		retry = 0;
+		mutex_enter(&autofs_minor_lock);
+		fngp = zone_getspecific(autofs_key, curproc->p_zone);
+		mutex_exit(&autofs_minor_lock);
+		if (fngp == NULL) {
+			if (hard) {
+				AUTOFS_DPRINT((5,
+				    "auto_calldaemon: "\
+				    "failed to get door handle\n"));
+				if (!printed_not_running_msg) {
+					printed_not_running_msg = 1;
+					zprintf(zoneid, "automountd not "\
+					    "running, retrying\n");
+				}
+				delay(hz);
+				retry = 1;
+			} else {
+				/*
+				 * There is no global data so no door.
+				 * There's no point in attempting to talk
+				 * to automountd if we can't get the door
+				 * handle.
+				 */
+				return (ECONNREFUSED);
+			}
+		}
+	} while (retry);
+
+	if (printed_not_running_msg) {
+		fngp->fng_printed_not_running_msg = printed_not_running_msg;
 	}
 
 	ASSERT(fngp != NULL);
@@ -434,8 +460,19 @@
 		case EINTR:
 			/*
 			 * interrupts should be handled properly by the
-			 * door upcall.
-			 *
+			 * door upcall. If the door doesn't handle the
+			 * interupt completely then we need to bail out.
+			 */
+			if (lwp && (ISSIG(curthread,
+			    JUSTLOOKING) || MUSTRETURN(curproc, curthread))) {
+				if (ISSIG(curthread, FORREAL) ||
+				    lwp->lwp_sysabort ||
+				    MUSTRETURN(curproc, curthread)) {
+					lwp->lwp_sysabort = 0;
+					return (EINTR);
+				}
+			}
+			/*
 			 * We may have gotten EINTR for other reasons
 			 * like the door being revoked on us. Instead
 			 * of trying to extract this out of the door
@@ -443,6 +480,7 @@
 			 * revoked we will get EBADF next time
 			 * through.
 			 */
+			/* FALLTHROUGH */
 		case EAGAIN:    /* process may be forking */
 			/*
 			 * Back off for a bit
--- a/usr/src/uts/common/fs/autofs/auto_sys.c	Mon Apr 23 18:01:19 2007 -0700
+++ b/usr/src/uts/common/fs/autofs/auto_sys.c	Mon Apr 23 18:54:07 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -53,14 +53,17 @@
 			return (set_errno(EPERM));
 		if ((zone = zone_find_by_id(zoneid)) == NULL)
 			return (set_errno(EINVAL));
+		mutex_enter(&autofs_minor_lock);
 		fngp = zone_getspecific(autofs_key, zone);
 		if (fngp == NULL) {
+			mutex_exit(&autofs_minor_lock);
 			zone_rele(zone);
 			/*
 			 * There were no mounts, so no work to do. Success.
 			 */
 			return (0);
 		}
+		mutex_exit(&autofs_minor_lock);
 		unmount_tree(fngp, 1);
 		zone_rele(zone);
 		break;
@@ -69,12 +72,17 @@
 		uint_t did;
 		struct autofs_globals *fngp;
 
+		/*
+		 * We need to use the minor_lock to serialize setting this.
+		 */
+		mutex_enter(&autofs_minor_lock);
 		fngp = zone_getspecific(autofs_key, curproc->p_zone);
 		if (fngp == NULL) {
 			fngp = autofs_zone_init();
 			(void) zone_setspecific(autofs_key,
 						curproc->p_zone, fngp);
 		}
+		mutex_exit(&autofs_minor_lock);
 		ASSERT(fngp != NULL);
 
 		if (copyin((uint_t *)arg, &did, sizeof (uint_t)))
--- a/usr/src/uts/common/fs/autofs/auto_vfsops.c	Mon Apr 23 18:01:19 2007 -0700
+++ b/usr/src/uts/common/fs/autofs/auto_vfsops.c	Mon Apr 23 18:54:07 2007 -0700
@@ -57,8 +57,8 @@
 
 static major_t autofs_major;
 static minor_t autofs_minor;
-static kmutex_t autofs_minor_lock;
 
+kmutex_t autofs_minor_lock;
 zone_key_t autofs_key;
 
 static mntopts_t auto_mntopts;
--- a/usr/src/uts/common/sys/fs/autofs.h	Mon Apr 23 18:01:19 2007 -0700
+++ b/usr/src/uts/common/sys/fs/autofs.h	Mon Apr 23 18:54:07 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -232,6 +232,7 @@
 	door_handle_t		fng_autofs_daemon_dh;
 };
 
+extern kmutex_t autofs_minor_lock;
 extern zone_key_t autofs_key;
 
 /*