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