| 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 |
| |
| |
| @@ -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 |
| |
| |
| @@ -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(); |