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