You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
9.7 KiB
283 lines
9.7 KiB
autofs-5.0.7 - fix fix wildcard multi map regression |
|
|
|
From: Ian Kent <raven@themaw.net> |
|
|
|
A recent patch to fix a wildcard multi map mount regression has a |
|
side effect of causing a deadlock at startup when trying to re-connect |
|
to existing mounts. |
|
|
|
The patch required the map entry cache write lock be taken so the cache |
|
could be updated. But when starting and trying to re-connect to existing |
|
mounts there's no need to update the cache. |
|
--- |
|
CHANGELOG | 1 + |
|
modules/lookup_file.c | 25 ++++++++++++++++++++----- |
|
modules/lookup_ldap.c | 23 +++++++++++++++++++---- |
|
modules/lookup_nisplus.c | 26 +++++++++++++++++++++----- |
|
modules/lookup_sss.c | 22 ++++++++++++++++++---- |
|
modules/lookup_yp.c | 23 +++++++++++++++++++---- |
|
6 files changed, 98 insertions(+), 22 deletions(-) |
|
|
|
--- autofs-5.0.7.orig/CHANGELOG |
|
+++ autofs-5.0.7/CHANGELOG |
|
@@ -57,6 +57,7 @@ |
|
- fix a couple of compiler warnings. |
|
- add after sssd dependency to unit file. |
|
- fix syncronize handle_mounts() shutdown. |
|
+- fix fix wildcard multi map regression. |
|
|
|
25/07/2012 autofs-5.0.7 |
|
======================= |
|
--- autofs-5.0.7.orig/modules/lookup_file.c |
|
+++ autofs-5.0.7/modules/lookup_file.c |
|
@@ -1042,7 +1042,7 @@ int lookup_mount(struct autofs_point *ap |
|
return NSS_STATUS_UNAVAIL; |
|
} |
|
|
|
- cache_writelock(mc); |
|
+ cache_readlock(mc); |
|
me = cache_lookup_first(mc); |
|
if (me && st.st_mtime <= me->age) { |
|
/* |
|
@@ -1084,7 +1084,18 @@ int lookup_mount(struct autofs_point *ap |
|
} |
|
} |
|
|
|
- cache_writelock(mc); |
|
+ /* |
|
+ * We can't take the writelock for direct mounts. If we're |
|
+ * starting up or trying to re-connect to an existing direct |
|
+ * mount we could be iterating through the map entries with |
|
+ * the readlock held. But we don't need to update the cache |
|
+ * when we're starting up so just take the readlock in that |
|
+ * case. |
|
+ */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ cache_readlock(mc); |
|
+ else |
|
+ cache_writelock(mc); |
|
do_cache_lookup: |
|
me = cache_lookup(mc, key); |
|
/* |
|
@@ -1102,10 +1113,11 @@ do_cache_lookup: |
|
} |
|
if (me && me->mapent) { |
|
/* |
|
- * Add wildcard match for later validation checks and |
|
- * negative cache lookups. |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
*/ |
|
- if (ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && |
|
+ ap->type == LKP_INDIRECT && *me->key == '*') { |
|
ret = cache_update(mc, source, key, me->mapent, me->age); |
|
if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
me = NULL; |
|
@@ -1130,6 +1142,9 @@ do_cache_lookup: |
|
ret = ctxt->parse->parse_mount(ap, key, key_len, |
|
mapent, ctxt->parse->context); |
|
if (ret) { |
|
+ /* Don't update negative cache when re-connecting */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ return NSS_STATUS_TRYAGAIN; |
|
cache_writelock(mc); |
|
cache_update_negative(mc, source, key, ap->negative_timeout); |
|
cache_unlock(mc); |
|
--- autofs-5.0.7.orig/modules/lookup_ldap.c |
|
+++ autofs-5.0.7/modules/lookup_ldap.c |
|
@@ -2975,7 +2975,18 @@ int lookup_mount(struct autofs_point *ap |
|
return status; |
|
} |
|
|
|
- cache_writelock(mc); |
|
+ /* |
|
+ * We can't take the writelock for direct mounts. If we're |
|
+ * starting up or trying to re-connect to an existing direct |
|
+ * mount we could be iterating through the map entries with |
|
+ * the readlock held. But we don't need to update the cache |
|
+ * when we're starting up so just take the readlock in that |
|
+ * case. |
|
+ */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ cache_readlock(mc); |
|
+ else |
|
+ cache_writelock(mc); |
|
me = cache_lookup(mc, key); |
|
/* Stale mapent => check for entry in alternate source or wildcard */ |
|
if (me && !me->mapent) { |
|
@@ -2987,10 +2998,11 @@ int lookup_mount(struct autofs_point *ap |
|
} |
|
if (me && me->mapent) { |
|
/* |
|
- * Add wildcard match for later validation checks and |
|
- * negative cache lookups. |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
*/ |
|
- if (ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && |
|
+ ap->type == LKP_INDIRECT && *me->key == '*') { |
|
ret = cache_update(mc, source, key, me->mapent, me->age); |
|
if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
me = NULL; |
|
@@ -3012,6 +3024,9 @@ int lookup_mount(struct autofs_point *ap |
|
ret = ctxt->parse->parse_mount(ap, key, key_len, |
|
mapent, ctxt->parse->context); |
|
if (ret) { |
|
+ /* Don't update negative cache when re-connecting */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ return NSS_STATUS_TRYAGAIN; |
|
cache_writelock(mc); |
|
cache_update_negative(mc, source, key, ap->negative_timeout); |
|
cache_unlock(mc); |
|
--- autofs-5.0.7.orig/modules/lookup_nisplus.c |
|
+++ autofs-5.0.7/modules/lookup_nisplus.c |
|
@@ -561,7 +561,18 @@ int lookup_mount(struct autofs_point *ap |
|
return status; |
|
} |
|
|
|
- cache_writelock(mc); |
|
+ /* |
|
+ * We can't take the writelock for direct mounts. If we're |
|
+ * starting up or trying to re-connect to an existing direct |
|
+ * mount we could be iterating through the map entries with |
|
+ * the readlock held. But we don't need to update the cache |
|
+ * when we're starting up so just take the readlock in that |
|
+ * case. |
|
+ */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ cache_readlock(mc); |
|
+ else |
|
+ cache_writelock(mc); |
|
me = cache_lookup(mc, key); |
|
/* Stale mapent => check for entry in alternate source or wildcard */ |
|
if (me && !me->mapent) { |
|
@@ -573,10 +584,11 @@ int lookup_mount(struct autofs_point *ap |
|
} |
|
if (me && me->mapent) { |
|
/* |
|
- * Add wildcard match for later validation checks and |
|
- * negative cache lookups. |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
*/ |
|
- if (ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && |
|
+ ap->type == LKP_INDIRECT && *me->key == '*') { |
|
ret = cache_update(mc, source, key, me->mapent, me->age); |
|
if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
me = NULL; |
|
@@ -603,6 +615,11 @@ int lookup_mount(struct autofs_point *ap |
|
time_t now = time(NULL); |
|
int rv = CHE_OK; |
|
|
|
+ free(mapent); |
|
+ |
|
+ /* Don't update negative cache when re-connecting */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ return NSS_STATUS_TRYAGAIN; |
|
cache_writelock(mc); |
|
me = cache_lookup_distinct(mc, key); |
|
if (!me) |
|
@@ -612,7 +629,6 @@ int lookup_mount(struct autofs_point *ap |
|
me->status = time(NULL) + ap->negative_timeout; |
|
} |
|
cache_unlock(mc); |
|
- free(mapent); |
|
return NSS_STATUS_TRYAGAIN; |
|
} |
|
free(mapent); |
|
--- autofs-5.0.7.orig/modules/lookup_sss.c |
|
+++ autofs-5.0.7/modules/lookup_sss.c |
|
@@ -635,7 +635,17 @@ int lookup_mount(struct autofs_point *ap |
|
return status; |
|
} |
|
|
|
- cache_readlock(mc); |
|
+ /* |
|
+ * We can't take the writelock for direct mounts. If we're |
|
+ * starting up or trying to re-connect to an existing direct |
|
+ * mount we could be iterating through the map entries with |
|
+ * the readlock held. But we don't need to update the cache |
|
+ * when we're starting up so just take the readlock in that |
|
+ */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ cache_writelock(mc); |
|
+ else |
|
+ cache_readlock(mc); |
|
me = cache_lookup(mc, key); |
|
/* Stale mapent => check for entry in alternate source or wildcard */ |
|
if (me && !me->mapent) { |
|
@@ -647,10 +657,11 @@ int lookup_mount(struct autofs_point *ap |
|
} |
|
if (me && me->mapent) { |
|
/* |
|
- * Add wildcard match for later validation checks and |
|
- * negative cache lookups. |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
*/ |
|
- if (ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ if (ap->type == LKP_INDIRECT && *me->key == '*' && |
|
+ !(ap->flags & MOUNT_FLAG_REMOUNT)) { |
|
ret = cache_update(mc, source, key, me->mapent, me->age); |
|
if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
me = NULL; |
|
@@ -672,6 +683,9 @@ int lookup_mount(struct autofs_point *ap |
|
ret = ctxt->parse->parse_mount(ap, key, key_len, |
|
mapent, ctxt->parse->context); |
|
if (ret) { |
|
+ /* Don't update negative cache when re-connecting */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ return NSS_STATUS_TRYAGAIN; |
|
cache_writelock(mc); |
|
cache_update_negative(mc, source, key, ap->negative_timeout); |
|
cache_unlock(mc); |
|
--- autofs-5.0.7.orig/modules/lookup_yp.c |
|
+++ autofs-5.0.7/modules/lookup_yp.c |
|
@@ -662,7 +662,18 @@ int lookup_mount(struct autofs_point *ap |
|
return status; |
|
} |
|
|
|
- cache_writelock(mc); |
|
+ /* |
|
+ * We can't take the writelock for direct mounts. If we're |
|
+ * starting up or trying to re-connect to an existing direct |
|
+ * mount we could be iterating through the map entries with |
|
+ * the readlock held. But we don't need to update the cache |
|
+ * when we're starting up so just take the readlock in that |
|
+ * case. |
|
+ */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ cache_readlock(mc); |
|
+ else |
|
+ cache_writelock(mc); |
|
me = cache_lookup(mc, key); |
|
/* Stale mapent => check for entry in alternate source or wildcard */ |
|
if (me && !me->mapent) { |
|
@@ -674,10 +685,11 @@ int lookup_mount(struct autofs_point *ap |
|
} |
|
if (me && me->mapent) { |
|
/* |
|
- * Add wildcard match for later validation checks and |
|
- * negative cache lookups. |
|
+ * If this is a lookup add wildcard match for later validation |
|
+ * checks and negative cache lookups. |
|
*/ |
|
- if (ap->type == LKP_INDIRECT && *me->key == '*') { |
|
+ if (ap->type == LKP_INDIRECT && *me->key == '*' && |
|
+ !(ap->flags & MOUNT_FLAG_REMOUNT)) { |
|
ret = cache_update(mc, source, key, me->mapent, me->age); |
|
if (!(ret & (CHE_OK | CHE_UPDATED))) |
|
me = NULL; |
|
@@ -698,6 +710,9 @@ int lookup_mount(struct autofs_point *ap |
|
ret = ctxt->parse->parse_mount(ap, key, key_len, |
|
mapent, ctxt->parse->context); |
|
if (ret) { |
|
+ /* Don't update negative cache when re-connecting */ |
|
+ if (ap->flags & MOUNT_FLAG_REMOUNT) |
|
+ return NSS_STATUS_TRYAGAIN; |
|
cache_writelock(mc); |
|
cache_update_negative(mc, source, key, ap->negative_timeout); |
|
cache_unlock(mc);
|
|
|