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

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