Ian Kent 62ad96
autofs-5.0.3 - make handle_mounts startup condition distinct
Ian Kent 62ad96
Ian Kent 62ad96
From: Ian Kent <raven@themaw.net>
Ian Kent 62ad96
Ian Kent 62ad96
When starting a number of mounts we can get contention for the startup
Ian Kent 62ad96
condition used to synchronize the handle_mounts thread completion. This
Ian Kent 62ad96
patch makes the condition used distinct for each thread creation.
Ian Kent 62ad96
---
Ian Kent 62ad96
Ian Kent 62ad96
 CHANGELOG              |    1 
Ian Kent 62ad96
 daemon/automount.c     |   62 +++++++++++++++++++++++++++++++++++++++++++++----
Ian Kent 62ad96
 include/automount.h    |    4 +++
Ian Kent 62ad96
 lib/master.c           |   29 +++++++++++-----------
Ian Kent 62ad96
 modules/mount_autofs.c |   35 +++++++++++++--------------
Ian Kent 62ad96
 5 files changed, 93 insertions(+), 38 deletions(-)
Ian Kent 62ad96
Ian Kent 62ad96
Ian Kent 62ad96
--- autofs-5.0.3.orig/CHANGELOG
Ian Kent 62ad96
+++ autofs-5.0.3/CHANGELOG
Ian Kent 62ad96
@@ -23,6 +23,7 @@
Ian Kent 62ad96
 - fix couple of memory leaks.
Ian Kent 62ad96
 - add command line option to override check for daemon already running.
Ian Kent 62ad96
 - don't use proc file system when checking if the daemon is running.
Ian Kent 62ad96
+- make handle_mounts startup condition distinct.
Ian Kent 62ad96
  
Ian Kent 62ad96
 14/01/2008 autofs-5.0.3
Ian Kent 62ad96
 -----------------------
Ian Kent 62ad96
--- autofs-5.0.3.orig/daemon/automount.c
Ian Kent 62ad96
+++ autofs-5.0.3/daemon/automount.c
Ian Kent 62ad96
@@ -1461,6 +1461,55 @@ static void mutex_operation_wait(pthread
Ian Kent 62ad96
 	return;
Ian Kent 62ad96
 }
Ian Kent 62ad96
 
Ian Kent 62ad96
+int handle_mounts_startup_cond_init(struct startup_cond *suc)
Ian Kent 62ad96
+{
Ian Kent 62ad96
+	int status;
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_mutex_init(&suc->mutex, NULL);
Ian Kent 62ad96
+	if (status)
Ian Kent 62ad96
+		return status;
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_cond_init(&suc->cond, NULL);
Ian Kent 62ad96
+	if (status) {
Ian Kent 62ad96
+		status = pthread_mutex_destroy(&suc->mutex);
Ian Kent 62ad96
+		if (status)
Ian Kent 62ad96
+			fatal(status);
Ian Kent 62ad96
+		return status;
Ian Kent 62ad96
+	}
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_mutex_lock(&suc->mutex);
Ian Kent 62ad96
+	if (status) {
Ian Kent 62ad96
+		status = pthread_mutex_destroy(&suc->mutex);
Ian Kent 62ad96
+		if (status)
Ian Kent 62ad96
+			fatal(status);
Ian Kent 62ad96
+		status = pthread_cond_destroy(&suc->cond);
Ian Kent 62ad96
+		if (status)
Ian Kent 62ad96
+			fatal(status);
Ian Kent 62ad96
+	}
Ian Kent 62ad96
+
Ian Kent 62ad96
+	return 0;
Ian Kent 62ad96
+}
Ian Kent 62ad96
+
Ian Kent 62ad96
+void handle_mounts_startup_cond_destroy(void *arg)
Ian Kent 62ad96
+{
Ian Kent 62ad96
+	struct startup_cond *suc = (struct startup_cond *) arg;
Ian Kent 62ad96
+	int status;
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_mutex_unlock(&suc->mutex);
Ian Kent 62ad96
+	if (status)
Ian Kent 62ad96
+		fatal(status);
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_mutex_destroy(&suc->mutex);
Ian Kent 62ad96
+	if (status)
Ian Kent 62ad96
+		fatal(status);
Ian Kent 62ad96
+
Ian Kent 62ad96
+	status = pthread_cond_destroy(&suc->cond);
Ian Kent 62ad96
+	if (status)
Ian Kent 62ad96
+		fatal(status);
Ian Kent 62ad96
+
Ian Kent 62ad96
+	return;
Ian Kent 62ad96
+}
Ian Kent 62ad96
+
Ian Kent 62ad96
 static void handle_mounts_cleanup(void *arg)
Ian Kent 62ad96
 {
Ian Kent 62ad96
 	struct autofs_point *ap;
Ian Kent 62ad96
@@ -1512,17 +1561,20 @@ static void handle_mounts_cleanup(void *
Ian Kent 62ad96
 
Ian Kent 62ad96
 void *handle_mounts(void *arg)
Ian Kent 62ad96
 {
Ian Kent 62ad96
+	struct startup_cond *suc;
Ian Kent 62ad96
 	struct autofs_point *ap;
Ian Kent 62ad96
 	int cancel_state, status = 0;
Ian Kent 62ad96
 
Ian Kent 62ad96
-	ap = (struct autofs_point *) arg;
Ian Kent 62ad96
+	suc = (struct startup_cond *) arg;
Ian Kent 62ad96
+
Ian Kent 62ad96
+	ap = suc->ap;
Ian Kent 62ad96
 
Ian Kent 62ad96
-	pthread_cleanup_push(return_start_status, &suc);
Ian Kent 62ad96
+	pthread_cleanup_push(return_start_status, suc);
Ian Kent 62ad96
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
Ian Kent 62ad96
 
Ian Kent 62ad96
 	state_mutex_lock(ap);
Ian Kent 62ad96
 
Ian Kent 62ad96
-	status = pthread_mutex_lock(&suc.mutex);
Ian Kent 62ad96
+	status = pthread_mutex_lock(&suc->mutex);
Ian Kent 62ad96
 	if (status) {
Ian Kent 62ad96
 		logerr("failed to lock startup condition mutex!");
Ian Kent 62ad96
 		fatal(status);
Ian Kent 62ad96
@@ -1530,7 +1582,7 @@ void *handle_mounts(void *arg)
Ian Kent 62ad96
 
Ian Kent 62ad96
 	if (mount_autofs(ap) < 0) {
Ian Kent 62ad96
 		crit(ap->logopt, "mount of %s failed!", ap->path);
Ian Kent 62ad96
-		suc.status = 1;
Ian Kent 62ad96
+		suc->status = 1;
Ian Kent 62ad96
 		state_mutex_unlock(ap);
Ian Kent 62ad96
 		umount_autofs(ap, 1);
Ian Kent 62ad96
 		pthread_setcancelstate(cancel_state, NULL);
Ian Kent 62ad96
@@ -1540,7 +1592,7 @@ void *handle_mounts(void *arg)
Ian Kent 62ad96
 	if (ap->ghost && ap->type != LKP_DIRECT)
Ian Kent 62ad96
 		info(ap->logopt, "ghosting enabled");
Ian Kent 62ad96
 
Ian Kent 62ad96
-	suc.status = 0;
Ian Kent 62ad96
+	suc->status = 0;
Ian Kent 62ad96
 	pthread_cleanup_pop(1);
Ian Kent 62ad96
 
Ian Kent 62ad96
 	/* We often start several automounters at the same time.  Add some
Ian Kent 62ad96
--- autofs-5.0.3.orig/include/automount.h
Ian Kent 62ad96
+++ autofs-5.0.3/include/automount.h
Ian Kent 62ad96
@@ -331,10 +331,14 @@ int ncat_path(char *buf, size_t len,
Ian Kent 62ad96
 struct startup_cond {
Ian Kent 62ad96
 	pthread_mutex_t mutex;
Ian Kent 62ad96
 	pthread_cond_t  cond;
Ian Kent 62ad96
+	struct autofs_point *ap;
Ian Kent 62ad96
 	unsigned int done;
Ian Kent 62ad96
 	unsigned int status;
Ian Kent 62ad96
 };
Ian Kent 62ad96
 
Ian Kent 62ad96
+int handle_mounts_startup_cond_init(struct startup_cond *suc);
Ian Kent 62ad96
+void handle_mounts_startup_cond_destroy(void *arg);
Ian Kent 62ad96
+
Ian Kent 62ad96
 struct master_readmap_cond {
Ian Kent 62ad96
 	pthread_mutex_t mutex;
Ian Kent 62ad96
 	pthread_cond_t  cond;
Ian Kent 62ad96
--- autofs-5.0.3.orig/lib/master.c
Ian Kent 62ad96
+++ autofs-5.0.3/lib/master.c
Ian Kent 62ad96
@@ -997,28 +997,31 @@ next:
Ian Kent 62ad96
 
Ian Kent 62ad96
 static int master_do_mount(struct master_mapent *entry)
Ian Kent 62ad96
 {
Ian Kent 62ad96
+	struct startup_cond suc;
Ian Kent 62ad96
 	struct autofs_point *ap;
Ian Kent 62ad96
 	pthread_t thid;
Ian Kent 62ad96
 	int status;
Ian Kent 62ad96
 
Ian Kent 62ad96
-	status = pthread_mutex_lock(&suc.mutex);
Ian Kent 62ad96
-	if (status)
Ian Kent 62ad96
-		fatal(status);
Ian Kent 62ad96
+	ap = entry->ap;
Ian Kent 62ad96
+
Ian Kent 62ad96
+	if (handle_mounts_startup_cond_init(&suc)) {
Ian Kent 62ad96
+		crit(ap->logopt,
Ian Kent 62ad96
+		     "failed to init startup cond for mount %s", entry->path);
Ian Kent 62ad96
+		return 0;
Ian Kent 62ad96
+	}
Ian Kent 62ad96
 
Ian Kent 62ad96
+	suc.ap = ap;
Ian Kent 62ad96
 	suc.done = 0;
Ian Kent 62ad96
 	suc.status = 0;
Ian Kent 62ad96
 
Ian Kent 62ad96
-	ap = entry->ap;
Ian Kent 62ad96
-
Ian Kent 62ad96
 	debug(ap->logopt, "mounting %s", entry->path);
Ian Kent 62ad96
 
Ian Kent 62ad96
-	if (pthread_create(&thid, &thread_attr, handle_mounts, ap)) {
Ian Kent 62ad96
+	status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
Ian Kent 62ad96
+	if (status) {
Ian Kent 62ad96
 		crit(ap->logopt,
Ian Kent 62ad96
 		     "failed to create mount handler thread for %s",
Ian Kent 62ad96
 		     entry->path);
Ian Kent 62ad96
-		status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-		if (status)
Ian Kent 62ad96
-			fatal(status);
Ian Kent 62ad96
+		handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 		return 0;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
 	entry->thid = thid;
Ian Kent 62ad96
@@ -1031,15 +1034,11 @@ static int master_do_mount(struct master
Ian Kent 62ad96
 
Ian Kent 62ad96
 	if (suc.status) {
Ian Kent 62ad96
 		error(ap->logopt, "failed to startup mount");
Ian Kent 62ad96
-		status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-		if (status)
Ian Kent 62ad96
-			fatal(status);
Ian Kent 62ad96
+		handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 		return 0;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
 
Ian Kent 62ad96
-	status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-	if (status)
Ian Kent 62ad96
-		fatal(status);
Ian Kent 62ad96
+	handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 
Ian Kent 62ad96
 	return 1;
Ian Kent 62ad96
 }
Ian Kent 62ad96
--- autofs-5.0.3.orig/modules/mount_autofs.c
Ian Kent 62ad96
+++ autofs-5.0.3/modules/mount_autofs.c
Ian Kent 62ad96
@@ -46,6 +46,7 @@ int mount_mount(struct autofs_point *ap,
Ian Kent 62ad96
 		int name_len, const char *what, const char *fstype,
Ian Kent 62ad96
 		const char *c_options, void *context)
Ian Kent 62ad96
 {
Ian Kent 62ad96
+	struct startup_cond suc;
Ian Kent 62ad96
 	pthread_t thid;
Ian Kent 62ad96
 	char *fullpath;
Ian Kent 62ad96
 	const char **argv;
Ian Kent 62ad96
@@ -210,34 +211,34 @@ int mount_mount(struct autofs_point *ap,
Ian Kent 62ad96
 	source->mc = cache_init(entry->ap, source);
Ian Kent 62ad96
 	if (!source->mc) {
Ian Kent 62ad96
 		error(ap->logopt, MODPREFIX "failed to init source cache");
Ian Kent 62ad96
+		master_free_map_source(source, 0);
Ian Kent 62ad96
 		master_free_mapent(entry);
Ian Kent 62ad96
 		return 1;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
 
Ian Kent 62ad96
 	mounts_mutex_lock(ap);
Ian Kent 62ad96
 
Ian Kent 62ad96
-	status = pthread_mutex_lock(&suc.mutex);
Ian Kent 62ad96
-	if (status) {
Ian Kent 62ad96
-		crit(ap->logopt,
Ian Kent 62ad96
-		     MODPREFIX "failed to lock startup condition mutex!");
Ian Kent 62ad96
-		cache_release(source);
Ian Kent 62ad96
+	if (handle_mounts_startup_cond_init(&suc)) {
Ian Kent 62ad96
+		crit(ap->logopt, MODPREFIX
Ian Kent 62ad96
+		     "failed to init startup cond for mount %s", entry->path);
Ian Kent 62ad96
+		mounts_mutex_unlock(ap);
Ian Kent 62ad96
+		master_free_map_source(source, 1);
Ian Kent 62ad96
 		master_free_mapent(entry);
Ian Kent 62ad96
 		return 1;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
 
Ian Kent 62ad96
+	suc.ap = nap;
Ian Kent 62ad96
 	suc.done = 0;
Ian Kent 62ad96
 	suc.status = 0;
Ian Kent 62ad96
 
Ian Kent 62ad96
-	if (pthread_create(&thid, NULL, handle_mounts, nap)) {
Ian Kent 62ad96
+	if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
Ian Kent 62ad96
 		crit(ap->logopt,
Ian Kent 62ad96
 		     MODPREFIX
Ian Kent 62ad96
 		     "failed to create mount handler thread for %s",
Ian Kent 62ad96
 		     fullpath);
Ian Kent 62ad96
+		handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 		mounts_mutex_unlock(ap);
Ian Kent 62ad96
-		status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-		if (status)
Ian Kent 62ad96
-			fatal(status);
Ian Kent 62ad96
-		cache_release(source);
Ian Kent 62ad96
+		master_free_map_source(source, 1);
Ian Kent 62ad96
 		master_free_mapent(entry);
Ian Kent 62ad96
 		return 1;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
@@ -246,8 +247,10 @@ int mount_mount(struct autofs_point *ap,
Ian Kent 62ad96
 	while (!suc.done) {
Ian Kent 62ad96
 		status = pthread_cond_wait(&suc.cond, &suc.mutex);
Ian Kent 62ad96
 		if (status) {
Ian Kent 62ad96
+			handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 			mounts_mutex_unlock(ap);
Ian Kent 62ad96
-			pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
+			master_free_map_source(source, 1);
Ian Kent 62ad96
+			master_free_mapent(entry);
Ian Kent 62ad96
 			fatal(status);
Ian Kent 62ad96
 		}
Ian Kent 62ad96
 	}
Ian Kent 62ad96
@@ -255,10 +258,9 @@ int mount_mount(struct autofs_point *ap,
Ian Kent 62ad96
 	if (suc.status) {
Ian Kent 62ad96
 		crit(ap->logopt,
Ian Kent 62ad96
 		     MODPREFIX "failed to create submount for %s", fullpath);
Ian Kent 62ad96
+		handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 		mounts_mutex_unlock(ap);
Ian Kent 62ad96
-		status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-		if (status)
Ian Kent 62ad96
-			fatal(status);
Ian Kent 62ad96
+		master_free_map_source(source, 1);
Ian Kent 62ad96
 		master_free_mapent(entry);
Ian Kent 62ad96
 		return 1;
Ian Kent 62ad96
 	}
Ian Kent 62ad96
@@ -266,12 +268,9 @@ int mount_mount(struct autofs_point *ap,
Ian Kent 62ad96
 	ap->submnt_count++;
Ian Kent 62ad96
 	list_add(&nap->mounts, &ap->submounts);
Ian Kent 62ad96
 
Ian Kent 62ad96
+	handle_mounts_startup_cond_destroy(&suc);
Ian Kent 62ad96
 	mounts_mutex_unlock(ap);
Ian Kent 62ad96
 
Ian Kent 62ad96
-	status = pthread_mutex_unlock(&suc.mutex);
Ian Kent 62ad96
-	if (status)
Ian Kent 62ad96
-		fatal(status);
Ian Kent 62ad96
-
Ian Kent 62ad96
 	return 0;
Ian Kent 62ad96
 }
Ian Kent 62ad96