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