- add autofs_ldap_auth.conf man page. - fix random selection for host on different network. - make redhat init script more lsb compliant. - don't hold lock for simple mounts. - fix remount locking. - fix wildcard map entry match. - fix parse_sun() module init. - dont check null cache on expire. - fix null cache race. - fix cache_init() on source re-read. - fix mapent becomes negative during lookup. - check each dc server individually. - fix negative cache included map lookup. - remove state machine timed wait.
366 lines
9.6 KiB
Diff
366 lines
9.6 KiB
Diff
autofs-5.0.5 - fix remount locking
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
When autofs is restarted with active mounts it is possible, due
|
|
to possible recursion when mounting multi-mount map entries, that
|
|
a lookup module will take a write lock on the map entry cache
|
|
when a read lock is alreay held.
|
|
|
|
Since, during the re-mount, we are still essentially running
|
|
single threaded we need only take care to ensure we don't take
|
|
the write lock.
|
|
---
|
|
|
|
CHANGELOG | 1 +
|
|
modules/lookup_file.c | 27 +++++++++++++++++----------
|
|
modules/lookup_hosts.c | 24 +++++++++++++++---------
|
|
modules/lookup_ldap.c | 24 ++++++++++++++++--------
|
|
modules/lookup_nisplus.c | 29 ++++++++++++++++++-----------
|
|
modules/lookup_program.c | 29 +++++++++++++++++++++--------
|
|
modules/lookup_yp.c | 27 +++++++++++++++++----------
|
|
7 files changed, 105 insertions(+), 56 deletions(-)
|
|
|
|
|
|
--- autofs-5.0.5.orig/CHANGELOG
|
|
+++ autofs-5.0.5/CHANGELOG
|
|
@@ -33,6 +33,7 @@
|
|
- fix random selection for host on different network.
|
|
- make redhat init script more lsb compliant.
|
|
- don't hold lock for simple mounts.
|
|
+- fix remount locking.
|
|
|
|
03/09/2009 autofs-5.0.5
|
|
-----------------------
|
|
--- autofs-5.0.5.orig/modules/lookup_file.c
|
|
+++ autofs-5.0.5/modules/lookup_file.c
|
|
@@ -871,7 +871,6 @@ static int check_map_indirect(struct aut
|
|
if (ret == CHE_FAIL)
|
|
return NSS_STATUS_NOTFOUND;
|
|
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
exists = cache_lookup_distinct(mc, key);
|
|
/* Not found in the map but found in the cache */
|
|
@@ -882,7 +881,7 @@ static int check_map_indirect(struct aut
|
|
exists->status = 0;
|
|
}
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
|
|
if (ret == CHE_MISSING) {
|
|
struct mapent *we;
|
|
@@ -896,7 +895,6 @@ static int check_map_indirect(struct aut
|
|
* Check for map change and update as needed for
|
|
* following cache lookup.
|
|
*/
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
we = cache_lookup_distinct(mc, "*");
|
|
if (we) {
|
|
@@ -904,7 +902,7 @@ static int check_map_indirect(struct aut
|
|
if (we->source == source && (wild & CHE_MISSING))
|
|
cache_delete(mc, "*");
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
|
|
if (wild & (CHE_OK | CHE_UPDATED))
|
|
return NSS_STATUS_SUCCESS;
|
|
@@ -957,13 +955,22 @@ int lookup_mount(struct autofs_point *ap
|
|
if (me->status >= time(NULL)) {
|
|
cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
+
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, key);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, key);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
}
|
|
-
|
|
- /* Negative timeout expired for non-existent entry. */
|
|
- if (!me->mapent)
|
|
- cache_delete(me->mc, key);
|
|
-
|
|
- cache_unlock(me->mc);
|
|
}
|
|
|
|
/*
|
|
--- autofs-5.0.5.orig/modules/lookup_hosts.c
|
|
+++ autofs-5.0.5/modules/lookup_hosts.c
|
|
@@ -146,19 +146,25 @@ int lookup_mount(struct autofs_point *ap
|
|
/* Check if we recorded a mount fail for this key anywhere */
|
|
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
|
|
if (me) {
|
|
- struct mapent_cache *fmc = me->mc;
|
|
-
|
|
if (me->status >= time(NULL)) {
|
|
- cache_unlock(fmc);
|
|
+ cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
- }
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
|
|
- if (!me->mapent) {
|
|
- cache_delete(fmc, name);
|
|
- me = NULL;
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, name);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, name);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
}
|
|
-
|
|
- cache_unlock(fmc);
|
|
}
|
|
|
|
cache_readlock(mc);
|
|
--- autofs-5.0.5.orig/modules/lookup_ldap.c
|
|
+++ autofs-5.0.5/modules/lookup_ldap.c
|
|
@@ -2681,7 +2681,6 @@ next:
|
|
unbind_ldap_connection(ap->logopt, ldap, ctxt);
|
|
|
|
/* Failed to find wild entry, update cache if needed */
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
we = cache_lookup_distinct(mc, "*");
|
|
if (we) {
|
|
@@ -2707,7 +2706,7 @@ next:
|
|
}
|
|
}
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
free(query);
|
|
|
|
return ret;
|
|
@@ -2817,13 +2816,22 @@ int lookup_mount(struct autofs_point *ap
|
|
if (me->status >= time(NULL)) {
|
|
cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
+
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, key);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, key);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
}
|
|
-
|
|
- /* Negative timeout expired for non-existent entry. */
|
|
- if (!me->mapent)
|
|
- cache_delete(me->mc, key);
|
|
-
|
|
- cache_unlock(me->mc);
|
|
}
|
|
|
|
/*
|
|
--- autofs-5.0.5.orig/modules/lookup_nisplus.c
|
|
+++ autofs-5.0.5/modules/lookup_nisplus.c
|
|
@@ -421,7 +421,6 @@ static int check_map_indirect(struct aut
|
|
return NSS_STATUS_UNAVAIL;
|
|
}
|
|
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
t_last_read = ap->exp_runfreq + 1;
|
|
me = cache_lookup_first(mc);
|
|
@@ -442,8 +441,8 @@ static int check_map_indirect(struct aut
|
|
exists->status = 0;
|
|
}
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
-
|
|
+ cache_unlock(mc);
|
|
+
|
|
if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
|
|
source->stale = 1;
|
|
|
|
@@ -459,7 +458,6 @@ static int check_map_indirect(struct aut
|
|
* Check for map change and update as needed for
|
|
* following cache lookup.
|
|
*/
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
we = cache_lookup_distinct(mc, "*");
|
|
if (we) {
|
|
@@ -473,7 +471,7 @@ static int check_map_indirect(struct aut
|
|
if (wild & (CHE_OK | CHE_UPDATED))
|
|
source->stale = 1;
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
|
|
if (wild & (CHE_UPDATED | CHE_OK))
|
|
return NSS_STATUS_SUCCESS;
|
|
@@ -516,13 +514,22 @@ int lookup_mount(struct autofs_point *ap
|
|
if (me->status >= time(NULL)) {
|
|
cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
- }
|
|
-
|
|
- /* Negative timeout expired for non-existent entry. */
|
|
- if (!me->mapent)
|
|
- cache_delete(me->mc, key);
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
|
|
- cache_unlock(me->mc);
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, key);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, key);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
--- autofs-5.0.5.orig/modules/lookup_program.c
|
|
+++ autofs-5.0.5/modules/lookup_program.c
|
|
@@ -135,17 +135,26 @@ int lookup_mount(struct autofs_point *ap
|
|
if (me->status >= time(NULL)) {
|
|
cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
- }
|
|
-
|
|
- /* Negative timeout expired for non-existent entry. */
|
|
- if (!me->mapent)
|
|
- cache_delete(me->mc, name);
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
|
|
- cache_unlock(me->mc);
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, name);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, name);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/* Catch installed direct offset triggers */
|
|
- cache_writelock(mc);
|
|
+ cache_readlock(mc);
|
|
me = cache_lookup_distinct(mc, name);
|
|
if (!me) {
|
|
cache_unlock(mc);
|
|
@@ -191,7 +200,11 @@ int lookup_mount(struct autofs_point *ap
|
|
" key %s, returning fail", name);
|
|
return NSS_STATUS_UNAVAIL;
|
|
}
|
|
- cache_delete(mc, name);
|
|
+ cache_unlock(mc);
|
|
+ cache_writelock(mc);
|
|
+ me = cache_lookup_distinct(mc, name);
|
|
+ if (me)
|
|
+ cache_delete(mc, name);
|
|
cache_unlock(mc);
|
|
}
|
|
}
|
|
--- autofs-5.0.5.orig/modules/lookup_yp.c
|
|
+++ autofs-5.0.5/modules/lookup_yp.c
|
|
@@ -533,7 +533,6 @@ static int check_map_indirect(struct aut
|
|
source->stale = 1;
|
|
}
|
|
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
exists = cache_lookup_distinct(mc, key);
|
|
/* Not found in the map but found in the cache */
|
|
@@ -545,7 +544,7 @@ static int check_map_indirect(struct aut
|
|
exists->status = 0;
|
|
}
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
|
|
if (ret == CHE_MISSING) {
|
|
struct mapent *we;
|
|
@@ -559,7 +558,6 @@ static int check_map_indirect(struct aut
|
|
* Check for map change and update as needed for
|
|
* following cache lookup.
|
|
*/
|
|
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
cache_writelock(mc);
|
|
we = cache_lookup_distinct(mc, "*");
|
|
if (we) {
|
|
@@ -573,7 +571,7 @@ static int check_map_indirect(struct aut
|
|
if (wild & (CHE_OK | CHE_UPDATED))
|
|
source->stale = 1;
|
|
}
|
|
- pthread_cleanup_pop(1);
|
|
+ cache_unlock(mc);
|
|
|
|
if (wild & (CHE_OK | CHE_UPDATED))
|
|
return NSS_STATUS_SUCCESS;
|
|
@@ -616,13 +614,22 @@ int lookup_mount(struct autofs_point *ap
|
|
if (me->status >= time(NULL)) {
|
|
cache_unlock(me->mc);
|
|
return NSS_STATUS_NOTFOUND;
|
|
- }
|
|
-
|
|
- /* Negative timeout expired for non-existent entry. */
|
|
- if (!me->mapent)
|
|
- cache_delete(me->mc, key);
|
|
+ } else {
|
|
+ struct mapent_cache *smc = me->mc;
|
|
+ struct mapent *sme;
|
|
|
|
- cache_unlock(me->mc);
|
|
+ if (me->mapent)
|
|
+ cache_unlock(smc);
|
|
+ else {
|
|
+ cache_unlock(smc);
|
|
+ cache_writelock(smc);
|
|
+ sme = cache_lookup_distinct(smc, key);
|
|
+ /* Negative timeout expired for non-existent entry. */
|
|
+ if (sme && !sme->mapent)
|
|
+ cache_delete(smc, key);
|
|
+ cache_unlock(smc);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/*
|