autofs-5.0.3 - library reload fix From: Ian Kent During a map re-read autofs needs to re-open its lookup libraries but dependent shared libraries can't handle being unloaded and then re-loaded by the same process. This patch preventis dependent libraries from being unloaded during this re-open. --- CHANGELOG | 1 + daemon/automount.c | 1 - daemon/lookup.c | 21 +++++++++------------ daemon/state.c | 3 +++ include/master.h | 17 +++-------------- lib/master.c | 28 ++++++++++++++++++++++------ 6 files changed, 38 insertions(+), 33 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index aec8c49..9869245 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -43,6 +43,7 @@ - fix rootless direct multi-mount expire. - wait submount expire thread completion. - add missing uris list locking. +- fix segv during library re-open. 14/01/2008 autofs-5.0.3 ----------------------- diff --git a/daemon/automount.c b/daemon/automount.c index 5b6a561..d8e5f68 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -85,7 +85,6 @@ int aquire_flag_file(void); void release_flag_file(void); static int umount_all(struct autofs_point *ap, int force); -extern pthread_mutex_t master_mutex; extern struct master *master_list; static int do_mkdir(const char *parent, const char *path, mode_t mode) diff --git a/daemon/lookup.c b/daemon/lookup.c index db3b636..2233ac8 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -267,17 +267,17 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a struct lookup_mod *lookup; int status; - if (!map->lookup) { - lookup = open_lookup(map->type, "", - map->format, map->argc, map->argv); - if (!lookup) { - debug(ap->logopt, "lookup module %s failed", map->type); - return NSS_STATUS_UNAVAIL; - } - map->lookup = lookup; + lookup = open_lookup(map->type, "", map->format, map->argc, map->argv); + if (!lookup) { + debug(ap->logopt, "lookup module %s failed", map->type); + return NSS_STATUS_UNAVAIL; } - lookup = map->lookup; + master_source_writelock(ap->entry); + if (map->lookup) + close_lookup(map->lookup); + map->lookup = lookup; + master_source_unlock(ap->entry); /* If we don't need to create directories then there's no use * reading the map. We just need to test that the map is valid @@ -463,8 +463,6 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time * point in the master map) do the nss lookup to * locate the map and read it. */ - pthread_cleanup_push(master_source_lock_cleanup, entry); - master_source_readlock(entry); if (source) map = source; else @@ -557,7 +555,6 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time map = map->next; } - pthread_cleanup_pop(1); if (!result || at_least_one) return 1; diff --git a/daemon/state.c b/daemon/state.c index 0042a74..1915a9f 100644 --- a/daemon/state.c +++ b/daemon/state.c @@ -387,9 +387,12 @@ static void *do_readmap(void *arg) info(ap->logopt, "re-reading map for %s", ap->path); + pthread_cleanup_push(master_mutex_lock_cleanup, NULL); + master_mutex_lock(); status = lookup_nss_read_map(ap, NULL, now); if (!status) pthread_exit(NULL); + pthread_cleanup_pop(1); if (ap->type == LKP_INDIRECT) { lookup_prune_cache(ap, now); diff --git a/include/master.h b/include/master.h index e62c67b..6d801a9 100644 --- a/include/master.h +++ b/include/master.h @@ -70,6 +70,9 @@ int master_parse_entry(const char *, unsigned int, unsigned int, time_t); /* From master.c master parser utility routines */ +void master_mutex_lock(void); +void master_mutex_unlock(void); +void master_mutex_lock_cleanup(void *); void master_set_default_timeout(void); void master_set_default_ghost_mode(void); int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, int); @@ -108,18 +111,4 @@ extern inline unsigned int master_get_logopt(void); int master_list_empty(struct master *); int master_kill(struct master *); -#define master_mutex_lock() \ -do { \ - int status = pthread_mutex_lock(&master_mutex); \ - if (status) \ - fatal(status); \ -} while (0) - -#define master_mutex_unlock() \ -do { \ - int status = pthread_mutex_unlock(&master_mutex); \ - if (status) \ - fatal(status); \ -} while (0) - #endif diff --git a/lib/master.c b/lib/master.c index ce5b987..8bc1248 100644 --- a/lib/master.c +++ b/lib/master.c @@ -41,8 +41,28 @@ static struct map_source * __master_find_map_source(struct master_mapent *, const char *, const char *, int, const char **); -pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t master_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; + +void master_mutex_lock(void) +{ + int status = pthread_mutex_lock(&master_mutex); + if (status) + fatal(status); +} + +void master_mutex_unlock(void) +{ + int status = pthread_mutex_unlock(&master_mutex); + if (status) + fatal(status); +} + +void master_mutex_lock_cleanup(void *arg) +{ + master_mutex_unlock(); + return; +} int master_add_autofs_point(struct master_mapent *entry, time_t timeout, unsigned logopt, unsigned ghost, int submount) @@ -1109,10 +1129,6 @@ int master_mount_mounts(struct master *master, time_t age, int readall) continue; } - master_source_writelock(ap->entry); - lookup_close_lookup(ap); - master_source_unlock(ap->entry); - cache_readlock(nc); ne = cache_lookup_distinct(nc, this->path); if (ne && this->age > ne->age) {