Blame SOURCES/autofs-5.0.7-syncronize-handle_mounts-shutdown.patch

ab3a3d
autofs-5.0.7 - syncronize handle_mounts() shutdown
ab3a3d
ab3a3d
From: Ian Kent <ikent@redhat.com>
ab3a3d
ab3a3d
When re-reading the master map the signal handler thread receives
ab3a3d
a SIGTERM signal from handle_mounts_cleanup() for map entries that
ab3a3d
have been removed. This is done to allow joining with handle_mounts()
ab3a3d
threads before shutting down to ensure clean up has been completed
ab3a3d
before the thread terminates.
ab3a3d
ab3a3d
But, if more than one map entry is removed, multiple threads may be
ab3a3d
cleaned up during the handling of a single signal so there can be no
ab3a3d
work to do when a subsequent signal is received. In this case the
ab3a3d
signal handler thread interprets the additional SIGTERM signal as a
ab3a3d
request to shutdown and exits.
ab3a3d
---
ab3a3d
 CHANGELOG          |    1 +
ab3a3d
 daemon/automount.c |    9 +++++++--
ab3a3d
 2 files changed, 8 insertions(+), 2 deletions(-)
ab3a3d
ab3a3d
diff --git a/CHANGELOG b/CHANGELOG
ab3a3d
index 488ad1e..f1ec1e5 100644
ab3a3d
--- a/CHANGELOG
ab3a3d
+++ b/CHANGELOG
ab3a3d
@@ -38,6 +38,7 @@
ab3a3d
 - fix systemd unidir in spec file.
ab3a3d
 - document browse option in man page.
ab3a3d
 - fix some automount(8) typos.
ab3a3d
+- syncronize handle_mounts() shutdown.
ab3a3d
 
ab3a3d
 25/07/2012 autofs-5.0.7
ab3a3d
 =======================
ab3a3d
diff --git a/daemon/automount.c b/daemon/automount.c
ab3a3d
index 4c651cf..3f9337f 100644
ab3a3d
--- a/daemon/automount.c
ab3a3d
+++ b/daemon/automount.c
ab3a3d
@@ -1285,7 +1285,8 @@ static int do_hup_signal(struct master *master, time_t age)
ab3a3d
 	nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check);
ab3a3d
 
ab3a3d
 	master_mutex_lock();
ab3a3d
-	if (master->reading) {
ab3a3d
+	/* Already doing a map read or shutdown or no mounts */
ab3a3d
+	if (master->reading || list_empty(&master->mounts)) {
ab3a3d
 		status = pthread_mutex_unlock(&mrc.mutex);
ab3a3d
 		if (status)
ab3a3d
 			fatal(status);
ab3a3d
@@ -1449,6 +1450,7 @@ static void handle_mounts_cleanup(void *arg)
ab3a3d
 	char path[PATH_MAX + 1];
ab3a3d
 	char buf[MAX_ERR_BUF];
ab3a3d
 	unsigned int clean = 0, submount, logopt;
ab3a3d
+	unsigned int pending = 0;
ab3a3d
 
ab3a3d
 	ap = (struct autofs_point *) arg;
ab3a3d
 
ab3a3d
@@ -1466,6 +1468,9 @@ static void handle_mounts_cleanup(void *arg)
ab3a3d
 		list_del_init(&ap->mounts);
ab3a3d
 	}
ab3a3d
 
ab3a3d
+	/* Don't signal the handler if we have already done so */
ab3a3d
+	if (!list_empty(&master_list->completed))
ab3a3d
+		pending = 1;
ab3a3d
 	master_remove_mapent(ap->entry);
ab3a3d
 	master_source_unlock(ap->entry);
ab3a3d
 
ab3a3d
@@ -1498,7 +1503,7 @@ static void handle_mounts_cleanup(void *arg)
ab3a3d
 	 * so it can join with any completed handle_mounts() threads and
ab3a3d
 	 * perform final cleanup.
ab3a3d
 	 */
ab3a3d
-	if (!submount)
ab3a3d
+	if (!submount && !pending)
ab3a3d
 		pthread_kill(state_mach_thid, SIGTERM);
ab3a3d
 
ab3a3d
 	master_mutex_unlock();