Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 130701790bf2d95e902edf16031ff596 > files > 79

autofs-5.0.1-0.rc2.164.el5_8.src.rpm

autofs-5.0.1 - fix parse_sun() module init

From: Ian Kent <raven@themaw.net>

In the parse sun module we pre-open the NFS mount module and cache
the library handle because it is used so often. Since this is shared
amonst all the master map entries multiple threads can race when
accessing the instance counter, especially when there are many
master map entries, leading to a double close on the mount library
handle.
---

 modules/parse_sun.c |   37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)


--- autofs-5.0.1.orig/modules/parse_sun.c
+++ autofs-5.0.1/modules/parse_sun.c
@@ -47,6 +47,22 @@ int parse_version = AUTOFS_PARSE_VERSION
 
 static struct mount_mod *mount_nfs = NULL;
 static int init_ctr = 0;
+static int macro_init_done = 0;
+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void instance_mutex_lock(void)
+{
+	int status = pthread_mutex_lock(&instance_mutex);
+	if (status)
+		fatal(status);
+}
+
+static void instance_mutex_unlock(void)
+{
+	int status = pthread_mutex_unlock(&instance_mutex);
+	if (status)
+		fatal(status);
+}
 
 extern const char *global_options;
 
@@ -276,9 +292,12 @@ int parse_init(int argc, const char *con
 	unsigned int append_options;
 
 	/* Get processor information for predefined escapes */
-
-	if (!init_ctr)
+	macro_lock();
+	if (!macro_init_done) {
+		macro_init_done = 1;
 		macro_init();
+	}
+	macro_unlock();
 
 	/* Set up context and escape chain */
 
@@ -432,19 +451,21 @@ options_done:
 
 	/* We only need this once.  NFS mounts are so common that we cache
 	   this module. */
-	if (!mount_nfs) {
+	instance_mutex_lock();
+	if (mount_nfs)
+		init_ctr++;
+	else {
 		if ((mount_nfs = open_mount("nfs", MODPREFIX))) {
 			init_ctr++;
-			return 0;
 		} else {
 			kill_context(ctxt);
 			*context = NULL;
+			instance_mutex_unlock();
 			return 1;
 		}
-	} else {
-		init_ctr++;
-		return 0;
 	}
+	instance_mutex_unlock();
+	return 0;
 }
 
 static const char *parse_options(const char *str, char **ret, unsigned int logopt)
@@ -1729,10 +1750,12 @@ int parse_done(void *context)
 	int rv = 0;
 	struct parse_context *ctxt = (struct parse_context *) context;
 
+	instance_mutex_lock();
 	if (--init_ctr == 0) {
 		rv = close_mount(mount_nfs);
 		mount_nfs = NULL;
 	}
+	instance_mutex_unlock();
 	if (ctxt)
 		kill_context(ctxt);