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

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