Blame SOURCES/autofs-5.0.7-fix-wildcard-multi-map-regression.patch

304803
autofs-5.0.7 - fix wildcard multi map regression
304803
304803
From: Ian Kent <raven@themaw.net>
304803
304803
A recent patch that removed code to add the current map entry when
304803
being parsed if it didn't already exist cause wildcard indirect
304803
multi-mount map entries to fail to mount.
304803
304803
Indirect multi-mount map entries need the entry matched by a wildcard
304803
lookup to be added to the map entry cache because subsequent operations
304803
expect a distinct map entry to be present or they will fail. This is
304803
what the code that was removed did but it did so in the wrong place
304803
which caused a deadlock situation.
304803
---
304803
 CHANGELOG                |    1 +
304803
 modules/lookup_file.c    |   23 ++++++++++++++++-------
304803
 modules/lookup_ldap.c    |   19 +++++++++++++++----
304803
 modules/lookup_nisplus.c |   21 ++++++++++++++++-----
304803
 modules/lookup_sss.c     |   17 ++++++++++++++---
304803
 modules/lookup_yp.c      |   21 ++++++++++++++++-----
304803
 6 files changed, 78 insertions(+), 24 deletions(-)
304803
304803
diff --git a/CHANGELOG b/CHANGELOG
304803
index 97d6f48..46ef335 100644
304803
--- a/CHANGELOG
304803
+++ b/CHANGELOG
304803
@@ -29,6 +29,7 @@
304803
 - modules/replicated.c: use sin6_addr.s6_addr32.
304803
 - workaround missing GNU versionsort extension.
304803
 - dont fail on master map self include.
304803
+- fix wildcard multi map regression.
304803
 
304803
 25/07/2012 autofs-5.0.7
304803
 =======================
304803
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
304803
index f37bed9..65e5ee6 100644
304803
--- a/modules/lookup_file.c
304803
+++ b/modules/lookup_file.c
304803
@@ -1040,7 +1040,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 			return NSS_STATUS_UNAVAIL;
304803
 		}
304803
 
304803
-		cache_readlock(mc);
304803
+		cache_writelock(mc);
304803
 		me = cache_lookup_first(mc);
304803
 		if (me && st.st_mtime <= me->age) {
304803
 			/*
304803
@@ -1082,7 +1082,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 		}
304803
 	}
304803
 
304803
-	cache_readlock(mc);
304803
+	cache_writelock(mc);
304803
 do_cache_lookup:
304803
 	me = cache_lookup(mc, key);
304803
 	/*
304803
@@ -1098,11 +1098,20 @@ do_cache_lookup:
304803
 		if (!me)
304803
 			me = cache_lookup_distinct(mc, "*");
304803
 	}
304803
-	if (me && me->mapent && (me->source == source || *me->key == '/')) {
304803
-		pthread_cleanup_push(cache_lock_cleanup, mc);
304803
-		strcpy(mapent_buf, me->mapent);
304803
-		mapent = mapent_buf;
304803
-		pthread_cleanup_pop(0);
304803
+	if (me && me->mapent) {
304803
+		/*
304803
+		 * Add wildcard match for later validation checks and
304803
+		 * negative cache lookups.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT && *me->key == '*') {
304803
+			ret = cache_update(mc, source, key, me->mapent, me->age);
304803
+			if (!(ret & (CHE_OK | CHE_UPDATED)))
304803
+				me = NULL;
304803
+		}
304803
+		if (me && (me->source == source || *me->key == '/')) {
304803
+			strcpy(mapent_buf, me->mapent);
304803
+			mapent = mapent_buf;
304803
+		}
304803
 	}
304803
 	cache_unlock(mc);
304803
 
304803
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
304803
index 431e50d..83e3215 100644
304803
--- a/modules/lookup_ldap.c
304803
+++ b/modules/lookup_ldap.c
304803
@@ -2969,7 +2969,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 			return status;
304803
 	}
304803
 
304803
-	cache_readlock(mc);
304803
+	cache_writelock(mc);
304803
 	me = cache_lookup(mc, key);
304803
 	/* Stale mapent => check for entry in alternate source or wildcard */
304803
 	if (me && !me->mapent) {
304803
@@ -2979,9 +2979,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 		if (!me)
304803
 			me = cache_lookup_distinct(mc, "*");
304803
 	}
304803
-	if (me && me->mapent && (me->source == source || *me->key == '/')) {
304803
-		strcpy(mapent_buf, me->mapent);
304803
-		mapent = mapent_buf;
304803
+	if (me && me->mapent) {
304803
+		/*
304803
+		 * Add wildcard match for later validation checks and
304803
+		 * negative cache lookups.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT && *me->key == '*') {
304803
+			ret = cache_update(mc, source, key, me->mapent, me->age);
304803
+			if (!(ret & (CHE_OK | CHE_UPDATED)))
304803
+				me = NULL;
304803
+		}
304803
+		if (me && (me->source == source || *me->key == '/')) {
304803
+			strcpy(mapent_buf, me->mapent);
304803
+			mapent = mapent_buf;
304803
+		}
304803
 	}
304803
 	cache_unlock(mc);
304803
 
304803
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
304803
index 9fced96..8237a1e 100644
304803
--- a/modules/lookup_nisplus.c
304803
+++ b/modules/lookup_nisplus.c
304803
@@ -561,7 +561,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 			return status;
304803
 	}
304803
 
304803
-	cache_readlock(mc);
304803
+	cache_writelock(mc);
304803
 	me = cache_lookup(mc, key);
304803
 	/* Stale mapent => check for entry in alternate source or wildcard */
304803
 	if (me && !me->mapent) {
304803
@@ -571,10 +571,21 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 		if (!me)
304803
 			me = cache_lookup_distinct(mc, "*");
304803
 	}
304803
-	if (me && me->mapent && (me->source == source || *me->key == '/')) {
304803
-		mapent_len = strlen(me->mapent);
304803
-		mapent = malloc(mapent_len + 1);
304803
-		strcpy(mapent, me->mapent);
304803
+	if (me && me->mapent) {
304803
+		/*
304803
+		 * Add wildcard match for later validation checks and
304803
+		 * negative cache lookups.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT && *me->key == '*') {
304803
+			ret = cache_update(mc, source, key, me->mapent, me->age);
304803
+			if (!(ret & (CHE_OK | CHE_UPDATED)))
304803
+				me = NULL;
304803
+		}
304803
+		if (me && (me->source == source || *me->key == '/')) {
304803
+			mapent_len = strlen(me->mapent);
304803
+			mapent = malloc(mapent_len + 1);
304803
+			strcpy(mapent, me->mapent);
304803
+		}
304803
 	}
304803
 	cache_unlock(mc);
304803
 
304803
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
304803
index e0b84cc..5c2ed0a 100644
304803
--- a/modules/lookup_sss.c
304803
+++ b/modules/lookup_sss.c
304803
@@ -645,9 +645,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 		if (!me)
304803
 			me = cache_lookup_distinct(mc, "*");
304803
 	}
304803
-	if (me && me->mapent && (me->source == source || *me->key == '/')) {
304803
-		strcpy(mapent_buf, me->mapent);
304803
-		mapent = mapent_buf;
304803
+	if (me && me->mapent) {
304803
+		/*
304803
+		 * Add wildcard match for later validation checks and
304803
+		 * negative cache lookups.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT && *me->key == '*') {
304803
+			ret = cache_update(mc, source, key, me->mapent, me->age);
304803
+			if (!(ret & (CHE_OK | CHE_UPDATED)))
304803
+				me = NULL;
304803
+		}
304803
+		if (me && (me->source == source || *me->key == '/')) {
304803
+			strcpy(mapent_buf, me->mapent);
304803
+			mapent = mapent_buf;
304803
+		}
304803
 	}
304803
 	cache_unlock(mc);
304803
 
304803
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
304803
index 720df2e..a716e1f 100644
304803
--- a/modules/lookup_yp.c
304803
+++ b/modules/lookup_yp.c
304803
@@ -662,7 +662,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 			return status;
304803
 	}
304803
 
304803
-	cache_readlock(mc);
304803
+	cache_writelock(mc);
304803
 	me = cache_lookup(mc, key);
304803
 	/* Stale mapent => check for entry in alternate source or wildcard */
304803
 	if (me && !me->mapent) {
304803
@@ -672,10 +672,21 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
304803
 		if (!me)
304803
 			me = cache_lookup_distinct(mc, "*");
304803
 	}
304803
-	if (me && me->mapent && (me->source == source || *me->key == '/')) {
304803
-		mapent_len = strlen(me->mapent);
304803
-		mapent = alloca(mapent_len + 1);
304803
-		strcpy(mapent, me->mapent);
304803
+	if (me && me->mapent) {
304803
+		/*
304803
+		 * Add wildcard match for later validation checks and
304803
+		 * negative cache lookups.
304803
+		 */
304803
+		if (ap->type == LKP_INDIRECT && *me->key == '*') {
304803
+			ret = cache_update(mc, source, key, me->mapent, me->age);
304803
+			if (!(ret & (CHE_OK | CHE_UPDATED)))
304803
+				me = NULL;
304803
+		}
304803
+		if (me && (me->source == source || *me->key == '/')) {
304803
+			mapent_len = strlen(me->mapent);
304803
+			mapent = alloca(mapent_len + 1);
304803
+			strcpy(mapent, me->mapent);
304803
+		}
304803
 	}
304803
 	cache_unlock(mc);
304803