AutoFS development
 help / color / mirror / Atom feed
From: Ian Kent <raven@themaw.net>
To: autofs mailing list <autofs@vger.kernel.org>
Cc: Gordon Lack <gordon.m.lack@gsk.com>,
	"Lan Yixun (dlan)" <dennis.yxun@gmail.com>,
	Leonardo Chiquitto <leonardo.lists@gmail.com>,
	Dustin Polke <DuPol@gmx.de>
Subject: [PATCH 21/25] autofs-5.0.7 - fix fix wildcard multi map regression
Date: Mon, 19 Aug 2013 09:14:16 +0800	[thread overview]
Message-ID: <20130819011415.6472.48682.stgit@perseus.fritz.box> (raw)
In-Reply-To: <20130819010909.6472.32512.stgit@perseus.fritz.box>

A recent patch to fix a wildcard multi map mount regression has a
side effect of causing a deadlock at startup when trying to re-connect
to existing mounts.

The patch required the map entry cache write lock be taken so the cache
could be updated. But when starting and trying to re-connect to existing
mounts there's no need to update the cache.
---
 CHANGELOG                |    1 +
 modules/lookup_file.c    |   25 ++++++++++++++++++++-----
 modules/lookup_ldap.c    |   23 +++++++++++++++++++----
 modules/lookup_nisplus.c |   26 +++++++++++++++++++++-----
 modules/lookup_sss.c     |   22 ++++++++++++++++++----
 modules/lookup_yp.c      |   23 +++++++++++++++++++----
 6 files changed, 98 insertions(+), 22 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 618ac20..c3f12e5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -72,6 +72,7 @@
 - try and cleanup after dumpmaps.
 - teach dumpmaps to output simple key value pairs.
 - fix syncronize handle_mounts() shutdown.
+- fix fix wildcard multi map regression.
 
 25/07/2012 autofs-5.0.7
 =======================
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 4b4ee89..83ef048 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1042,7 +1042,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			return NSS_STATUS_UNAVAIL;
 		}
 
-		cache_writelock(mc);
+		cache_readlock(mc);
 		me = cache_lookup_first(mc);
 		if (me && st.st_mtime <= me->age) {
 			/*
@@ -1084,7 +1084,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 		}
 	}
 
-	cache_writelock(mc);
+	/*
+	 * We can't take the writelock for direct mounts. If we're
+	 * starting up or trying to re-connect to an existing direct
+	 * mount we could be iterating through the map entries with
+	 * the readlock held. But we don't need to update the cache
+	 * when we're starting up so just take the readlock in that
+	 * case.
+	 */
+	if (ap->flags & MOUNT_FLAG_REMOUNT)
+		cache_readlock(mc);
+	else
+		cache_writelock(mc);
 do_cache_lookup:
 	me = cache_lookup(mc, key);
 	/*
@@ -1102,10 +1113,11 @@ do_cache_lookup:
 	}
 	if (me && me->mapent) {
 		/*
-		 * Add wildcard match for later validation checks and
-		 * negative cache lookups.
+		 * If this is a lookup add wildcard match for later validation
+		 * checks and negative cache lookups.
 		 */
-		if (ap->type == LKP_INDIRECT && *me->key == '*') {
+		if (!(ap->flags & MOUNT_FLAG_REMOUNT) &&
+		    ap->type == LKP_INDIRECT && *me->key == '*') {
 			ret = cache_update(mc, source, key, me->mapent, me->age);
 			if (!(ret & (CHE_OK | CHE_UPDATED)))
 				me = NULL;
@@ -1130,6 +1142,9 @@ do_cache_lookup:
 	ret = ctxt->parse->parse_mount(ap, key, key_len,
 				       mapent, ctxt->parse->context);
 	if (ret) {
+		/* Don't update negative cache when re-connecting */
+		if (ap->flags & MOUNT_FLAG_REMOUNT)
+			return NSS_STATUS_TRYAGAIN;
 		cache_writelock(mc);
 		cache_update_negative(mc, source, key, ap->negative_timeout);
 		cache_unlock(mc);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index d05098f..2ab1e8c 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -3016,7 +3016,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			return status;
 	}
 
-	cache_writelock(mc);
+	/*
+	 * We can't take the writelock for direct mounts. If we're
+	 * starting up or trying to re-connect to an existing direct
+	 * mount we could be iterating through the map entries with
+	 * the readlock held. But we don't need to update the cache
+	 * when we're starting up so just take the readlock in that
+	 * case.
+	 */
+	if (ap->flags & MOUNT_FLAG_REMOUNT)
+		cache_readlock(mc);
+	else
+		cache_writelock(mc);
 	me = cache_lookup(mc, key);
 	/* Stale mapent => check for entry in alternate source or wildcard */
 	if (me && !me->mapent) {
@@ -3028,10 +3039,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	}
 	if (me && me->mapent) {
 		/*
-		 * Add wildcard match for later validation checks and
-		 * negative cache lookups.
+		 * If this is a lookup add wildcard match for later validation
+		 * checks and negative cache lookups.
 		 */
-		if (ap->type == LKP_INDIRECT && *me->key == '*') {
+		if (!(ap->flags & MOUNT_FLAG_REMOUNT) &&
+		    ap->type == LKP_INDIRECT && *me->key == '*') {
 			ret = cache_update(mc, source, key, me->mapent, me->age);
 			if (!(ret & (CHE_OK | CHE_UPDATED)))
 				me = NULL;
@@ -3053,6 +3065,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	ret = ctxt->parse->parse_mount(ap, key, key_len,
 				       mapent, ctxt->parse->context);
 	if (ret) {
+		/* Don't update negative cache when re-connecting */
+		if (ap->flags & MOUNT_FLAG_REMOUNT)
+			return NSS_STATUS_TRYAGAIN;
 		cache_writelock(mc);
 		cache_update_negative(mc, source, key, ap->negative_timeout);
 		cache_unlock(mc);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index ef942a7..08878bb 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -561,7 +561,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			return status;
 	}
 
-	cache_writelock(mc);
+	/*
+	 * We can't take the writelock for direct mounts. If we're
+	 * starting up or trying to re-connect to an existing direct
+	 * mount we could be iterating through the map entries with
+	 * the readlock held. But we don't need to update the cache
+	 * when we're starting up so just take the readlock in that
+	 * case.
+	 */
+	if (ap->flags & MOUNT_FLAG_REMOUNT)
+		cache_readlock(mc);
+	else
+		cache_writelock(mc);
 	me = cache_lookup(mc, key);
 	/* Stale mapent => check for entry in alternate source or wildcard */
 	if (me && !me->mapent) {
@@ -573,10 +584,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	}
 	if (me && me->mapent) {
 		/*
-		 * Add wildcard match for later validation checks and
-		 * negative cache lookups.
+		 * If this is a lookup add wildcard match for later validation
+		 * checks and negative cache lookups.
 		 */
-		if (ap->type == LKP_INDIRECT && *me->key == '*') {
+		if (!(ap->flags & MOUNT_FLAG_REMOUNT) &&
+		    ap->type == LKP_INDIRECT && *me->key == '*') {
 			ret = cache_update(mc, source, key, me->mapent, me->age);
 			if (!(ret & (CHE_OK | CHE_UPDATED)))
 				me = NULL;
@@ -603,6 +615,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 		time_t now = time(NULL);
 		int rv = CHE_OK;
 
+		free(mapent);
+
+		/* Don't update negative cache when re-connecting */
+		if (ap->flags & MOUNT_FLAG_REMOUNT)
+			return NSS_STATUS_TRYAGAIN;
 		cache_writelock(mc);
 		me = cache_lookup_distinct(mc, key);
 		if (!me)
@@ -612,7 +629,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			me->status = time(NULL) + ap->negative_timeout;
 		}
 		cache_unlock(mc);
-		free(mapent);
 		return NSS_STATUS_TRYAGAIN;
 	}
 	free(mapent);
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index 1fe740b..4a9cfd2 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -635,7 +635,17 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			return status;
 	}
 
-	cache_readlock(mc);
+	/*
+	 * We can't take the writelock for direct mounts. If we're
+	 * starting up or trying to re-connect to an existing direct
+	 * mount we could be iterating through the map entries with
+	 * the readlock held. But we don't need to update the cache
+	 * when we're starting up so just take the readlock in that
+	 */
+	if (ap->flags & MOUNT_FLAG_REMOUNT)
+		cache_writelock(mc);
+	else
+		cache_readlock(mc);
 	me = cache_lookup(mc, key);
 	/* Stale mapent => check for entry in alternate source or wildcard */
 	if (me && !me->mapent) {
@@ -647,10 +657,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	}
 	if (me && me->mapent) {
 		/*
-		 * Add wildcard match for later validation checks and
-		 * negative cache lookups.
+		 * If this is a lookup add wildcard match for later validation
+		 * checks and negative cache lookups.
 		 */
-		if (ap->type == LKP_INDIRECT && *me->key == '*') {
+		if (ap->type == LKP_INDIRECT && *me->key == '*' &&
+		   !(ap->flags & MOUNT_FLAG_REMOUNT)) {
 			ret = cache_update(mc, source, key, me->mapent, me->age);
 			if (!(ret & (CHE_OK | CHE_UPDATED)))
 				me = NULL;
@@ -672,6 +683,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	ret = ctxt->parse->parse_mount(ap, key, key_len,
 				       mapent, ctxt->parse->context);
 	if (ret) {
+		/* Don't update negative cache when re-connecting */
+		if (ap->flags & MOUNT_FLAG_REMOUNT)
+			return NSS_STATUS_TRYAGAIN;
 		cache_writelock(mc);
 		cache_update_negative(mc, source, key, ap->negative_timeout);
 		cache_unlock(mc);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index e99e3c0..4d1848e 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -662,7 +662,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 			return status;
 	}
 
-	cache_writelock(mc);
+	/*
+	 * We can't take the writelock for direct mounts. If we're
+	 * starting up or trying to re-connect to an existing direct
+	 * mount we could be iterating through the map entries with
+	 * the readlock held. But we don't need to update the cache
+	 * when we're starting up so just take the readlock in that
+	 * case.
+	 */
+	if (ap->flags & MOUNT_FLAG_REMOUNT)
+		cache_readlock(mc);
+	else
+		cache_writelock(mc);
 	me = cache_lookup(mc, key);
 	/* Stale mapent => check for entry in alternate source or wildcard */
 	if (me && !me->mapent) {
@@ -674,10 +685,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 	}
 	if (me && me->mapent) {
 		/*
-		 * Add wildcard match for later validation checks and
-		 * negative cache lookups.
+		 * If this is a lookup add wildcard match for later validation
+		 * checks and negative cache lookups.
 		 */
-		if (ap->type == LKP_INDIRECT && *me->key == '*') {
+		if (ap->type == LKP_INDIRECT && *me->key == '*' &&
+		   !(ap->flags & MOUNT_FLAG_REMOUNT)) {
 			ret = cache_update(mc, source, key, me->mapent, me->age);
 			if (!(ret & (CHE_OK | CHE_UPDATED)))
 				me = NULL;
@@ -698,6 +710,9 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 		ret = ctxt->parse->parse_mount(ap, key, key_len,
 					       mapent, ctxt->parse->context);
 		if (ret) {
+			/* Don't update negative cache when re-connecting */
+			if (ap->flags & MOUNT_FLAG_REMOUNT)
+				return NSS_STATUS_TRYAGAIN;
 			cache_writelock(mc);
 			cache_update_negative(mc, source, key, ap->negative_timeout);
 			cache_unlock(mc);


  parent reply	other threads:[~2013-08-19  1:14 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-19  1:11 [PATCH 00/25] Current autofs patch queue Ian Kent
2013-08-19  1:11 ` [PATCH 01/25] autofs-5.0.7 - don't override LDFLAGS in make rules Ian Kent
2013-08-19  1:12 ` [PATCH 02/25] autofs-5.0.7 - fix a couple of compiler warnings Ian Kent
2013-08-19  1:12 ` [PATCH 03/25] autofs-5.0.7 - add after sssd dependency to unit file Ian Kent
2013-08-19  1:12 ` [PATCH 04/25] autofs-5.0.7 - dont start readmap unless ready Ian Kent
2013-08-19  1:12 ` [PATCH 05/25] autofs-5.0.7 - fix crash due to thread unsafe use of libldap Ian Kent
2013-08-19  1:12 ` [PATCH 06/25] autofs-5.0.7 - fix compile error with heimdal support enabled Ian Kent
2013-08-20  3:36   ` Dennis Lan (dlan)
2013-08-20  7:34     ` Ian Kent
2013-08-19  1:12 ` [PATCH 07/25] autofs-5.0.7 - fix typo forced-shutdown should be force-shutdown Ian Kent
2013-08-19  1:12 ` [PATCH 08/25] autofs-5.0.7 - fix hesiod check error and use correct $(LIBS) setting Ian Kent
2013-08-19  1:12 ` [PATCH 09/25] autofs-5.0.7 - fix dead LDAP symbolic link when LDAP support is disabled Ian Kent
2013-08-19  1:13 ` [PATCH 10/25] autofs-5.0.7 - add missing libtirpc lib to mount_nfs.so when TIRPC enabled Ian Kent
2013-08-19  1:13 ` [PATCH 11/25] autofs-5.0.7 - use compiler determined by configure instead of hard-coded ones Ian Kent
2013-08-19  1:13 ` [PATCH 12/25] autofs-5.0.7 - remove hard-coded STRIP variable Ian Kent
2013-08-19  1:13 ` [PATCH 13/25] autofs-5.0.7 - use LIBS for link libraries Ian Kent
2013-08-19  1:13 ` [PATCH 14/25] autofs-5.0.7 - unbundle NOTSTRIP from DEBUG so they dont depend on each other Ian Kent
2013-08-19  1:13 ` [PATCH 15/25] autofs-5.0.7 - fix occasional build error when enable parallel compiling Ian Kent
2013-08-19  1:13 ` [PATCH 16/25] autofs-5.0.7 - fix compilation of lookup_ldap.c without sasl Ian Kent
2013-08-19  1:13 ` [PATCH 17/25] autofs-5.0.7 - fix dumpmaps multi output Ian Kent
2013-08-19  1:13 ` [PATCH 18/25] autofs-5.0.7 - try and cleanup after dumpmaps Ian Kent
2013-08-19  1:14 ` [PATCH 19/25] autofs-5.0.7 - teach dumpmaps to output simple key value pairs Ian Kent
2013-08-19  1:14 ` [PATCH 20/25] autofs-5.0.7 - fix syncronize handle_mounts() shutdown Ian Kent
2013-08-19  1:14 ` Ian Kent [this message]
2013-08-19  1:14 ` [PATCH 22/25] autofs-5.0.7 - improve timeout option description Ian Kent
2013-08-19  1:14 ` [PATCH 23/25] autofs-5.0.7 - only probe specific nfs version when requested Ian Kent
2013-08-19  1:14 ` [PATCH 24/25] autofs-5.0.7 - fix bad mkdir permission on create Ian Kent
2013-08-19  2:13   ` Ian Kent
2013-08-19  1:14 ` [PATCH 25/25] autofs-5.0.7 - setup program map env from macro table Ian Kent
2013-08-19  5:30 ` [PATCH 00/25] Current autofs patch queue Dennis Lan (dlan)
2013-08-20  2:55   ` Ian Kent
2013-08-20  4:52     ` Dennis Lan (dlan)
2013-09-02 10:34 ` Martin Wilck
2013-09-02 10:41   ` Gordon Lack
2013-09-02 11:04     ` Martin Wilck
2013-09-02 11:13       ` Gordon Lack
2013-09-02 12:17         ` Martin Wilck
2013-09-02 12:55           ` Gordon Lack
2013-09-02 13:15             ` Martin Wilck
2013-09-02 13:41               ` Gordon Lack
2013-09-02 14:11                 ` Martin Wilck
2013-09-02 14:20                   ` Gordon Lack
2013-09-02 14:49                     ` Martin Wilck
2013-09-02 15:08                       ` Gordon Lack
2013-09-02 15:23                         ` Martin Wilck
2013-09-02 15:36                           ` Gordon Lack
2013-09-06  8:11   ` Ian Kent

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130819011415.6472.48682.stgit@perseus.fritz.box \
    --to=raven@themaw.net \
    --cc=DuPol@gmx.de \
    --cc=autofs@vger.kernel.org \
    --cc=dennis.yxun@gmail.com \
    --cc=gordon.m.lack@gsk.com \
    --cc=leonardo.lists@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox