Ian Kent cc4062
autofs-5.0.5 - fix parse_sun() module init
Ian Kent cc4062
Ian Kent cc4062
From: Ian Kent <raven@themaw.net>
Ian Kent cc4062
Ian Kent cc4062
In the parse sun module we pre-open the NFS mount module and cache
Ian Kent cc4062
the library handle because it is used so often. Since this is shared
Ian Kent cc4062
amonst all the master map entries multiple threads can race when
Ian Kent cc4062
accessing the instance counter, especially when there are many
Ian Kent cc4062
master map entries, leading to a double close on the mount library
Ian Kent cc4062
handle.
Ian Kent cc4062
---
Ian Kent cc4062
Ian Kent cc4062
 CHANGELOG           |    1 +
Ian Kent cc4062
 modules/parse_sun.c |   37 ++++++++++++++++++++++++++++++-------
Ian Kent cc4062
 2 files changed, 31 insertions(+), 7 deletions(-)
Ian Kent cc4062
Ian Kent cc4062
Ian Kent cc4062
--- autofs-5.0.5.orig/CHANGELOG
Ian Kent cc4062
+++ autofs-5.0.5/CHANGELOG
Ian Kent cc4062
@@ -35,6 +35,7 @@
Ian Kent cc4062
 - don't hold lock for simple mounts.
Ian Kent cc4062
 - fix remount locking.
Ian Kent cc4062
 - fix wildcard map entry match.
Ian Kent cc4062
+- fix parse_sun() module init.
Ian Kent cc4062
 
Ian Kent cc4062
 03/09/2009 autofs-5.0.5
Ian Kent cc4062
 -----------------------
Ian Kent cc4062
--- autofs-5.0.5.orig/modules/parse_sun.c
Ian Kent cc4062
+++ autofs-5.0.5/modules/parse_sun.c
Ian Kent cc4062
@@ -45,6 +45,22 @@ int parse_version = AUTOFS_PARSE_VERSION
Ian Kent cc4062
 
Ian Kent cc4062
 static struct mount_mod *mount_nfs = NULL;
Ian Kent cc4062
 static int init_ctr = 0;
Ian Kent cc4062
+static int macro_init_done = 0;
Ian Kent cc4062
+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
Ian Kent cc4062
+
Ian Kent cc4062
+static void instance_mutex_lock(void)
Ian Kent cc4062
+{
Ian Kent cc4062
+	int status = pthread_mutex_lock(&instance_mutex);
Ian Kent cc4062
+	if (status)
Ian Kent cc4062
+		fatal(status);
Ian Kent cc4062
+}
Ian Kent cc4062
+
Ian Kent cc4062
+static void instance_mutex_unlock(void)
Ian Kent cc4062
+{
Ian Kent cc4062
+	int status = pthread_mutex_unlock(&instance_mutex);
Ian Kent cc4062
+	if (status)
Ian Kent cc4062
+		fatal(status);
Ian Kent cc4062
+}
Ian Kent cc4062
 
Ian Kent cc4062
 extern const char *global_options;
Ian Kent cc4062
 
Ian Kent cc4062
@@ -276,9 +292,12 @@ int parse_init(int argc, const char *con
Ian Kent cc4062
 	unsigned int append_options;
Ian Kent cc4062
 
Ian Kent cc4062
 	/* Get processor information for predefined escapes */
Ian Kent cc4062
-
Ian Kent cc4062
-	if (!init_ctr)
Ian Kent cc4062
+	macro_lock();
Ian Kent cc4062
+	if (!macro_init_done) {
Ian Kent cc4062
+		macro_init_done = 1;
Ian Kent cc4062
 		macro_init();
Ian Kent cc4062
+	}
Ian Kent cc4062
+	macro_unlock();
Ian Kent cc4062
 
Ian Kent cc4062
 	/* Set up context and escape chain */
Ian Kent cc4062
 
Ian Kent cc4062
@@ -434,19 +453,21 @@ options_done:
Ian Kent cc4062
 
Ian Kent cc4062
 	/* We only need this once.  NFS mounts are so common that we cache
Ian Kent cc4062
 	   this module. */
Ian Kent cc4062
-	if (!mount_nfs) {
Ian Kent cc4062
+	instance_mutex_lock();
Ian Kent cc4062
+	if (mount_nfs)
Ian Kent cc4062
+		init_ctr++;
Ian Kent cc4062
+	else {
Ian Kent cc4062
 		if ((mount_nfs = open_mount("nfs", MODPREFIX))) {
Ian Kent cc4062
 			init_ctr++;
Ian Kent cc4062
-			return 0;
Ian Kent cc4062
 		} else {
Ian Kent cc4062
 			kill_context(ctxt);
Ian Kent cc4062
 			*context = NULL;
Ian Kent cc4062
+			instance_mutex_unlock();
Ian Kent cc4062
 			return 1;
Ian Kent cc4062
 		}
Ian Kent cc4062
-	} else {
Ian Kent cc4062
-		init_ctr++;
Ian Kent cc4062
-		return 0;
Ian Kent cc4062
 	}
Ian Kent cc4062
+	instance_mutex_unlock();
Ian Kent cc4062
+	return 0;
Ian Kent cc4062
 }
Ian Kent cc4062
 
Ian Kent cc4062
 static const char *parse_options(const char *str, char **ret, unsigned int logopt)
Ian Kent cc4062
@@ -1734,10 +1755,12 @@ int parse_done(void *context)
Ian Kent cc4062
 	int rv = 0;
Ian Kent cc4062
 	struct parse_context *ctxt = (struct parse_context *) context;
Ian Kent cc4062
 
Ian Kent cc4062
+	instance_mutex_lock();
Ian Kent cc4062
 	if (--init_ctr == 0) {
Ian Kent cc4062
 		rv = close_mount(mount_nfs);
Ian Kent cc4062
 		mount_nfs = NULL;
Ian Kent cc4062
 	}
Ian Kent cc4062
+	instance_mutex_unlock();
Ian Kent cc4062
 	if (ctxt)
Ian Kent cc4062
 		kill_context(ctxt);
Ian Kent cc4062