rpms/autofs/F-13 autofs-5.0.5-add-autofs_ldap_auth_conf-man-page.patch, NONE, 1.1 autofs-5.0.5-check-each-dc-server.patch, NONE, 1.1 autofs-5.0.5-dont-check-null-cache-on-expire.patch, NONE, 1.1 autofs-5.0.5-dont-hold-lock-for-simple-mounts.patch, NONE, 1.1 autofs-5.0.5-fix-cache_init-on-source-re-read.patch, NONE, 1.1 autofs-5.0.5-fix-master-map-source-server-unavialable-handling.patch, NONE, 1.1 autofs-5.0.5-fix-negative-cache-included-map-lookup.patch, NONE, 1.1 autofs-5.0.5-fix-null-cache-race.patch, NONE, 1.1 autofs-5.0.5-fix-parse_sun-module-init.patch, NONE, 1.1 autofs-5.0.5-fix-random-selection-for-host-on-different-network.patch, NONE, 1.1 autofs-5.0.5-fix-remount-locking.patch, NONE, 1.1 autofs-5.0.5-fix-wildcard-map-entry-match.patch, NONE, 1.1 autofs-5.0.5-make-redhat-init-script-more-lsb-compliant.patch, NONE, 1.1 autofs-5.0.5-mapent-becomes-negative-during-lookup.patch, NONE, 1.1 autofs-5.0.5-remove-state-machine-timed-wait.patch, NONE, 1.1 autofs.spec, 1.308, 1.309

Ian Kent iankent at fedoraproject.org
Fri Jun 11 02:44:48 UTC 2010


Author: iankent

Update of /cvs/pkgs/rpms/autofs/F-13
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv12789

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.5-add-autofs_ldap_auth_conf-man-page.patch 
	autofs-5.0.5-check-each-dc-server.patch 
	autofs-5.0.5-dont-check-null-cache-on-expire.patch 
	autofs-5.0.5-dont-hold-lock-for-simple-mounts.patch 
	autofs-5.0.5-fix-cache_init-on-source-re-read.patch 
	autofs-5.0.5-fix-master-map-source-server-unavialable-handling.patch 
	autofs-5.0.5-fix-negative-cache-included-map-lookup.patch 
	autofs-5.0.5-fix-null-cache-race.patch 
	autofs-5.0.5-fix-parse_sun-module-init.patch 
	autofs-5.0.5-fix-random-selection-for-host-on-different-network.patch 
	autofs-5.0.5-fix-remount-locking.patch 
	autofs-5.0.5-fix-wildcard-map-entry-match.patch 
	autofs-5.0.5-make-redhat-init-script-more-lsb-compliant.patch 
	autofs-5.0.5-mapent-becomes-negative-during-lookup.patch 
	autofs-5.0.5-remove-state-machine-timed-wait.patch 
Log Message:
* Fri Jun 11 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-26.fc13
- remove URL tag as there is not official autofs wiki (bz529804).
- fix master map source server unavailable handling.
- add autofs_ldap_auth.conf man page.
- fix random selection for host on different network.
- make redhat init script more lsb compliant.
- don't hold lock for simple mounts.
- fix remount locking.
- fix wildcard map entry match.
- fix parse_sun() module init.
- dont check null cache on expire.
- fix null cache race.
- fix cache_init() on source re-read.
- fix mapent becomes negative during lookup.
- check each dc server individually.
- fix negative cache included map lookup.
- remove state machine timed wait.


autofs-5.0.5-add-autofs_ldap_auth_conf-man-page.patch:
 CHANGELOG                                   |    1 
 autofs-5.0.5/man/autofs_ldap_auth.conf.5.in |   93 ++++++++++++++++++++++++++++
 man/auto.master.5.in                        |    3 
 man/autofs.5                                |    1 
 man/autofs.8.in                             |    1 
 man/automount.8                             |    1 
 samples/autofs_ldap_auth.conf               |   64 -------------------
 7 files changed, 101 insertions(+), 63 deletions(-)

--- NEW FILE autofs-5.0.5-add-autofs_ldap_auth_conf-man-page.patch ---
autofs-5.0.5 - add autofs_ldap_auth.conf man page

From: Ian Kent <raven at themaw.net>


---

 CHANGELOG                      |    1 
 man/auto.master.5.in           |    3 +
 man/autofs.5                   |    1 
 man/autofs.8.in                |    1 
 man/autofs_ldap_auth.conf.5.in |   93 +++++++++++++++++++++++++++++++++++++++++
 man/automount.8                |    1 
 samples/autofs_ldap_auth.conf  |   64 ----------------------------
 7 files changed, 101 insertions(+), 63 deletions(-)
 create mode 100644 man/autofs_ldap_auth.conf.5.in


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -30,6 +30,7 @@
 - add simple bind authentication.
 - fix included map read fail handling (again).
 - fix master map source server unavailable handling.
+- add autofs_ldap_auth.conf man page.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/man/auto.master.5.in
+++ autofs-5.0.5/man/auto.master.5.in
@@ -365,6 +365,8 @@ and set the location of the client certi
 in the per-user configuration. The location of these files and the configuration
 entry requirements is system dependent so the documentation for your
 installation will need to be consulted to get further information.
+.P
+See \fBautofs_ldap_auth.conf\fP(5) for more information.
 .SH EXAMPLE
 .sp
 .RS +.2i
@@ -399,6 +401,7 @@ configuration will be used to locate the
 .BR automount (8),
 .BR autofs (5),
 .BR autofs (8).
+.BR autofs_ldap_auth.conf (5)
 .SH AUTHOR
 This manual page was written by Christoph Lameter <chris at waterf.org>,
 for the Dean GNU/Linux system.  Edited by <hpa at transmeta.com> and
--- autofs-5.0.5.orig/man/autofs.5
+++ autofs-5.0.5/man/autofs.5
@@ -229,6 +229,7 @@ and LDAP only.
 .BR auto.master (5),
 .BR autofs (8),
 .BR mount (8).
+.BR autofs_ldap_auth.conf (5)
 .SH AUTHOR
 This manual page was written by Christoph Lameter <chris at waterf.org>,
 for the Debian GNU/Linux system.  Edited by H. Peter Avian
--- autofs-5.0.5.orig/man/autofs.8.in
+++ autofs-5.0.5/man/autofs.8.in
@@ -50,6 +50,7 @@ will display the status of,
 .BR automount (8),
 .BR autofs (5),
 .BR auto.master (5).
+.BR autofs_ldap_auth.conf (5)
 .SH AUTHOR
 This manual page was written by Christoph Lameter <chris at waterf.org>,
 for the Debi GNU/Linux system.  Edited by H. Peter Anvin
--- /dev/null
+++ autofs-5.0.5/man/autofs_ldap_auth.conf.5.in
@@ -0,0 +1,93 @@
+.\" t
+.TH AUTOFS_LDAP_AUTH.CONF 5 "19 Feb 2010"
+.SH NAME
+autofs_ldap_auth.conf \- autofs LDAP authentication configuration
+.SH "DESCRIPTION"
+LDAP authenticated binds, TLS encrypted connections and certification
+may be used by setting appropriate values in the autofs authentication
+configuration file and configuring the LDAP client with appropriate
+settings.  The default location of this file is
+.nh
+.BR @@autofsmapdir@@/autofs_ldap_auth.conf .
+.hy
+If this file exists it will be used to establish whether TLS or authentication
+should be used.
+.P
+An example of this file is:
+.sp
+.RS +.2i
+.ta 1.0i
+.nf
+<?xml version="1.0" ?>
+<autofs_ldap_sasl_conf
+        usetls="yes"
+        tlsrequired="no"
+        authrequired="no"
+        authtype="DIGEST-MD5"
+        user="xyz"
+        secret="abc"
+/>
+.fi
+.RE
+.sp
+If TLS encryption is to be used the location of the Certificate Authority
+certificate must be set within the LDAP client configuration in
+order to validate the server certificate. If, in addition, a certified
+connection is to be used then the client certificate and private key file
+locations must also be configured within the LDAP client.
+.SH "OPTIONS"
+This files contains a single XML element, as shown in the example above, with
+several attributes.
+.TP
+The possible attributes are:
+.TP
+\fBusetls="yes"|"no"\fP
+Determines whether an encrypted connection to the ldap server
+should be attempted.
+.TP
+\fBtlsrequired="yes"|"no"\fP
+This flag tells whether the ldap connection must be encrypted. If set to "yes",
+the automounter will fail to start if an encrypted connection cannot be
+established.
+.TP
+\fBauthrequired="yes"|"no"|"autodetect"|"simple"\fP
+This option tells whether an authenticated connection to the ldap server is
+required in order to perform ldap queries. If the flag is set to yes, only
+sasl authenticated connections will be allowed. If it is set to no then
+authentication is not needed for ldap server connections. If it is set to
+autodetect then the ldap server will be queried to establish a suitable sasl
+authentication  mechanism. If no suitable mechanism can be found, connections
+to the ldap server are made without authentication. Finally, if it is set to
+simple, then simple authentication will be used instead of SASL.
+.TP
+\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5"\fP
+This attribute can be used to specify a preferred authentication mechanism.
+ In normal operations, the automounter will attempt to authenticate to the
+ldap server using the list of supportedSASLmechanisms obtained from the
+directory server.  Explicitly setting the authtype will bypass this selection
+and only try the mechanism specified.
+.TP
+\fBuser="<username>"\fP
+This attribute holds the authentication identity used by authentication
+mechanisms that require it.  Legal values for this attribute include any
+printable characters that can be used by the selected authentication
+mechanism.
+.TP
+\fBsecret="<password>"\fP
+This attribute holds the secret used by authentication mechanisms that
+require it. Legal values for this attribute include any printable
+characters that can be used by the selected authentication mechanism.
+.TP
+\fBclientprinc="<GSSAPI client principal>"\fP
+When using GSSAPI authentication, this attribute is consulted to determine
+the principal name to use when authenticating to the directory server. By
+default, this will be set to "autofsclient/<fqdn>@<REALM>.
+.TP
+\fBcredentialcache="<external credential cache path>"\fP
+When using GSSAPI authentication, this attribute can be used to specify an
+externally configured credential cache that is used during authentication.
+By default, autofs will setup a memory based credential cache.
+.SH "SEE ALSO"
+.BR auto.master (5),
+.SH AUTHOR
+This manual page was written by Ian Kent <raven at themaw.net>.
--- autofs-5.0.5.orig/man/automount.8
+++ autofs-5.0.5/man/automount.8
@@ -152,6 +152,7 @@ constructed has been detached from the m
 .BR autofs (8),
 .BR auto.master (5),
 .BR mount (8).
+.BR autofs_ldap_auth.conf (5)
 .SH BUGS
 Don't know, I've fixed everything I know about.
 
--- autofs-5.0.5.orig/samples/autofs_ldap_auth.conf
+++ autofs-5.0.5/samples/autofs_ldap_auth.conf
@@ -1,69 +1,7 @@
 <?xml version="1.0" ?>
 <!--
 This files contains a single entry with multiple attributes tied to it.
-The attributes are:
-
-usetls  -  Determines whether an encrypted connection to the ldap server
-	   should be attempted.  Legal values for the entry are:
-	   "yes"
-	   "no"
-
-tlsrequired  -  This flag tells whether the ldap connection must be
-	   encrypted.  If set to "yes", the automounter will fail to start
-	   if an encrypted connection cannot be established.  Legal values
-	   for this option include:
-	   "yes"
-	   "no"
-
-authrequired  -  This option tells whether an authenticated connection to
-	    the ldap server is required in order to perform ldap queries.
-	    If the flag is set to yes, only sasl authenticated connections
-	    will be allowed. If it is set to no then authentication is not
-	    needed for ldap server connections. If it is set to autodetect
-	    then the ldap server will be queried to establish a suitable
-	    sasl authentication mechanism. If no suitable mechanism can be
-	    found, connections to the ldap server are made without
-	    authentication. Finally, if it is set to simple, then simple
-	    authentication will be used instead of SASL.
-
-	    Legal values for this option include:
-	    "yes"
-	    "no"
-	    "autodetect"
-	    "simple"
-
-authtype  -  This attribute can be used to specify a preferred
-	    authentication mechanism.  In normal operations, the
-	    automounter will attempt to authenticate to the ldap server
-	    using the list of supportedSASLmechanisms obtained from the
-	    directory server.  Explicitly setting the authtype will bypass
-	    this selection and only try the mechanism specified.  Legal
-	    values for this attribute include:
-	    "GSSAPI"
-	    "LOGIN"
-	    "PLAIN"
-	    "ANONYMOUS"
-	    "DIGEST-MD5"
-
-user  -  This attribute holds the authentication identity used by
-	    authentication mechanisms that require it.  Legal values for
-	    this attribute include any printable characters that can be
-	    used by the selected authentication mechanism.
-
-secret  -  This attribute holds the secret used by authentication
-	    mechanisms that require it.  Legal values for this attribute
-	    include any printable characters that can be used by the
-	    selected authentication mechanism.
-
-clientprinc  -  When using GSSAPI authentication, this attribute is
-	    consulted to determine the principal name to use when
-	    authenticating to the directory server.  By default, this will
-	    be set to "autofsclient/<fqdn>@<REALM>.
-
-credentialcache - When using GSSAPI authentication, this attribute
-	    can be used to specify an externally configured credential
-	    cache that is used during authentication. By default, autofs
-	    will setup a memory based credential cache.
+See autofs_ldap_auth.conf(5) for more information.
 -->
 
 <autofs_ldap_sasl_conf

autofs-5.0.5-check-each-dc-server.patch:
 CHANGELOG             |    1 
 modules/lookup_ldap.c |  103 +++++++++++++++++++++++++++++---------------------
 2 files changed, 62 insertions(+), 42 deletions(-)

--- NEW FILE autofs-5.0.5-check-each-dc-server.patch ---
autofs-5.0.5 - check each dc server

From: Ian Kent <raven at themaw.net>

We return a space separated list of dc servers from get_dc_list() but the
GSSAPI code needs an individual server in the uri to function correctly.

Change the logic in find_server() and do_reconnect() to attempt a connection
to each dc server individually.
---

 CHANGELOG             |    1 
 modules/lookup_ldap.c |  103 +++++++++++++++++++++++++++++---------------------
 2 files changed, 62 insertions(+), 42 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -41,6 +41,7 @@
 - fix null cache race.
 - fix cache_init() on source re-read.
 - fix mapent becomes negative during lookup.
+- check each dc server individually.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/modules/lookup_ldap.c
+++ autofs-5.0.5/modules/lookup_ldap.c
@@ -615,23 +615,43 @@ static LDAP *connect_to_server(unsigned 
 	return ldap;
 }
 
+static LDAP *find_dc_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
+{
+	char *str, *tok, *ptr = NULL;
+	LDAP *ldap = NULL;
+
+	str = strdup(uri);
+	if (!str)
+		return NULL;
+
+	tok = strtok_r(str, " ", &ptr);
+	while (tok) {
+		const char *this = (const char *) tok;
+		debug(logopt, "trying server uri %s", this);
+		ldap = connect_to_server(logopt, this, ctxt);
+		if (ldap) {
+			info(logopt, "connected to uri %s", this);
+			free(str);
+			return ldap;
+		}
+		tok = strtok_r(NULL, " ", &ptr);
+	}
+
+	free(str);
+
+	return NULL;
+}
+
 static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
 {
 	LDAP *ldap = NULL;
 	struct ldap_uri *this;
 	struct list_head *p, *first;
-	struct dclist *dclist = NULL;
+	struct dclist *dclist;
 	char *uri = NULL;
 
 	uris_mutex_lock(ctxt);
-	if (ctxt->dclist) {
-		dclist = ctxt->dclist;
-		if (ctxt->dclist->expire < time(NULL)) {
-			free_dclist(ctxt->dclist);
-			ctxt->dclist = NULL;
-			dclist = NULL;
-		}
-	}
+	dclist = ctxt->dclist;
 	if (!ctxt->uri)
 		first = ctxt->uris;
 	else
@@ -648,9 +668,16 @@ static LDAP *find_server(unsigned logopt
 			continue;
 		}
 		this = list_entry(p, struct ldap_uri, list);
-		if (!strstr(this->uri, ":///"))
+		if (!strstr(this->uri, ":///")) {
 			uri = strdup(this->uri);
-		else {
+			debug(logopt, "trying server uri %s", uri);
+			ldap = connect_to_server(logopt, uri, ctxt);
+			if (ldap) {
+				info(logopt, "connected to uri %s", uri);
+				free(uri);
+				break;
+			}
+		} else {
 			if (dclist)
 				uri = strdup(dclist->uri);
 			else {
@@ -663,21 +690,11 @@ static LDAP *find_server(unsigned logopt
 				dclist = tmp;
 				uri = strdup(dclist->uri);
 			}
-		}
-		if (!uri) {
-			if (dclist) {
-				free_dclist(dclist);
-				dclist = NULL;
+			ldap = find_dc_server(logopt, uri, ctxt);
+			if (ldap) {
+				free(uri);
+				break;
 			}
-			p = p->next;
-			continue;
-		}
-		debug(logopt, "trying server uri %s", uri);
-		ldap = connect_to_server(logopt, uri, ctxt);
-		if (ldap) {
-			info(logopt, "connected to uri %s", uri);
-			free(uri);
-			break;
 		}
 		free(uri);
 		uri = NULL;
@@ -708,7 +725,7 @@ static LDAP *find_server(unsigned logopt
 
 static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
 {
-	LDAP *ldap;
+	LDAP *ldap = NULL;
 	char *uri;
 
 	if (ctxt->server || !ctxt->uris) {
@@ -723,25 +740,29 @@ static LDAP *do_reconnect(unsigned logop
 		return ldap;
 	}
 
+	if (ctxt->dclist) {
+		ldap = find_dc_server(logopt, ctxt->dclist->uri, ctxt);
+		if (ldap)
+			return ldap;
+	}
+
 	uris_mutex_lock(ctxt);
-	if (ctxt->dclist)
-		uri = strdup(ctxt->dclist->uri);
-	else if (ctxt->uri)
-		uri = strdup(ctxt->uri->uri);
-	else {
+	if (ctxt->dclist) {
+		if (!ldap || ctxt->dclist->expire < time(NULL)) {
+			free_dclist(ctxt->dclist);
+			ctxt->dclist = NULL;
+		}
+		/* Make sure we don't skip the domain spec */
+		ctxt->uri = NULL;
 		uris_mutex_unlock(ctxt);
 		goto find_server;
 	}
 	uris_mutex_unlock(ctxt);
 
-	if (!uri) {
-		char buf[MAX_ERR_BUF];
-		char *estr = strerror_r(errno, buf, sizeof(buf));
-		crit(logopt, MODPREFIX "strdup: %s", estr);
-		return NULL;
-	}
+	if (!ctxt->uri)
+		goto find_server;
 
-	ldap = do_connect(logopt, uri, ctxt);
+	ldap = do_connect(logopt, ctxt->uri->uri, ctxt);
 #ifdef WITH_SASL
 	/*
 	 * Dispose of the sasl authentication connection and try the
@@ -752,19 +773,17 @@ static LDAP *do_reconnect(unsigned logop
 		ldap = connect_to_server(logopt, uri, ctxt);
 	}
 #endif
-	free(uri);
-
 	if (ldap)
 		return ldap;
 
 	/* Failed to connect, try to find a new server */
 
+find_server:
 #ifdef WITH_SASL
 	autofs_sasl_dispose(ctxt);
 #endif
 
-find_server:
-	/* Current server failed connect, try the rest */
+	/* Current server failed, try the rest or dc connection */
 	ldap = find_server(logopt, ctxt);
 	if (!ldap)
 		error(logopt, MODPREFIX "failed to find available server");

autofs-5.0.5-dont-check-null-cache-on-expire.patch:
 CHANGELOG          |    1 +
 daemon/automount.c |    9 ---------
 2 files changed, 1 insertion(+), 9 deletions(-)

--- NEW FILE autofs-5.0.5-dont-check-null-cache-on-expire.patch ---
autofs-5.0.5 - dont check null cache on expire

From: Ian Kent <raven at themaw.net>

When expiring an entry there is no need to check the null map
entry cache. If we have a mount then it must have been done at
some point when the entry was not a nulled so it still needs
to be expired. Remove this check.
---

 CHANGELOG          |    1 +
 daemon/automount.c |    9 ---------
 2 files changed, 1 insertion(+), 9 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -37,6 +37,7 @@
 - fix remount locking.
 - fix wildcard map entry match.
 - fix parse_sun() module init.
+- dont check null cache on expire.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/automount.c
+++ autofs-5.0.5/daemon/automount.c
@@ -526,20 +526,11 @@ static int umount_subtree_mounts(struct 
    it also tries to umount path itself */
 int umount_multi(struct autofs_point *ap, const char *path, int incl)
 {
-	struct mapent_cache *nc;
 	int is_autofs_fs;
 	int left;
 
 	debug(ap->logopt, "path %s incl %d", path, incl);
 
-	nc = ap->entry->master->nc;
-	cache_readlock(nc);
-	if (cache_lookup_distinct(nc, path)) {
-		cache_unlock(nc);
-		return 0;
-	}
-	cache_unlock(nc);
-
 	is_autofs_fs = 0;
 	if (master_find_submount(ap, path))
 		is_autofs_fs = 1;

autofs-5.0.5-dont-hold-lock-for-simple-mounts.patch:
 CHANGELOG           |    1 +
 modules/parse_sun.c |   41 +++++++++++++++++------------------------
 2 files changed, 18 insertions(+), 24 deletions(-)

--- NEW FILE autofs-5.0.5-dont-hold-lock-for-simple-mounts.patch ---
autofs-5.0.5 - don't hold lock for simple mounts

From: Ian Kent <raven at themaw.net>

A map entry that depends on another map entry in the "same" map cannot
be allowed in all cases. In particular, multi-mount entries must not
change during mount operations so the internal map entry cache must
remain locked during the mount. This is because, during the mount, we
must consult the map and possibly update the internal cache entry to
ensure we are using the most up to date mount information.

This isn't the case for non multi-mount map entries but autofs didn't
allow for this, which is the issue this patch addresses.
---

 CHANGELOG           |    1 +
 modules/parse_sun.c |   41 +++++++++++++++++------------------------
 2 files changed, 18 insertions(+), 24 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -33,6 +33,7 @@
 - add autofs_ldap_auth.conf man page.
 - fix random selection for host on different network.
 - make redhat init script more lsb compliant.
+- don't hold lock for simple mounts.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/modules/parse_sun.c
+++ autofs-5.0.5/modules/parse_sun.c
@@ -1136,19 +1136,6 @@ static int mount_subtree(struct autofs_p
 
 	rv = 0;
 
-	if (!me || !me->multi) {
-		int loclen = strlen(loc);
-		int namelen = strlen(name);
-		const char *root = ap->path;
-
-		if (!strcmp(ap->path, "/-"))
-			root = name;
-
-		rv = sun_mount(ap, root, name, namelen, loc, loclen, options, ctxt);
-
-		goto done;
-	}
-
 	mm = me->multi;
 	mm_key = mm->key;
 	move = MOUNT_MOVE_NONE;
@@ -1294,7 +1281,6 @@ static int mount_subtree(struct autofs_p
 	if (rv > 0)
 		return rv;
 
-done:
 	/*
 	 * Convert fail on nonstrict, non-empty multi-mount
 	 * to success
@@ -1622,17 +1608,25 @@ int parse_mount(struct autofs_point *ap,
 		 * it's already been parsed (above) and any option string
 		 * has already been stripped so just use the remainder.
 		 */
+		cache_readlock(mc);
 		if (*name == '/' &&
 		   (me = cache_lookup_distinct(mc, name)) && me->multi) {
 			loc = strdup(p);
 			if (!loc) {
 				free(options);
+				cache_unlock(mc);
 				warn(ap->logopt, MODPREFIX "out of memory");
 				return 1;
 			}
-			loclen = strlen(p);
-			goto mount_it;
+			cache_multi_writelock(me);
+			rv = mount_subtree(ap, me, name, loc, options, ctxt);
+			cache_multi_unlock(me);
+			cache_unlock(mc);
+			free(loc);
+			free(options);
+			return rv;
 		}
+		cache_unlock(mc);
 
 		l = chunklen(p, check_colon(p));
 		loc = dequote(p, l, ap->logopt);
@@ -1716,21 +1710,20 @@ int parse_mount(struct autofs_point *ap,
 			      MODPREFIX "entry %s is empty!", name);
 			return 1;
 		}
-mount_it:
+
 		debug(ap->logopt,
 		      MODPREFIX "core of entry: options=%s, loc=%.*s",
 		      options, loclen, loc);
 
-		cache_readlock(mc);
-		cache_multi_writelock(me);
-
-		rv = mount_subtree(ap, me, name, loc, options, ctxt);
+		if (!strcmp(ap->path, "/-"))
+			rv = sun_mount(ap, name, name, name_len,
+				       loc, loclen, options, ctxt);
+		else
+			rv = sun_mount(ap, ap->path, name, name_len,
+				       loc, loclen, options, ctxt);
 
 		free(loc);
 		free(options);
-
-		cache_multi_unlock(me);
-		cache_unlock(mc);
 		pthread_setcancelstate(cur_state, NULL);
 	}
 	return rv;

autofs-5.0.5-fix-cache_init-on-source-re-read.patch:
 CHANGELOG              |    1 +
 lib/master.c           |    6 ++++++
 lib/master_parse.y     |   10 ----------
 modules/mount_autofs.c |    8 --------
 4 files changed, 7 insertions(+), 18 deletions(-)

--- NEW FILE autofs-5.0.5-fix-cache_init-on-source-re-read.patch ---
autofs-5.0.5 - fix cache_init() on source re-read

From: Ian Kent <raven at themaw.net>

The master map entry cache is released and re-allocated for each
map source upon master map re-read. This is done without holding
the master map entry write lock and, when there are many master
map entries, could lead to a race because other activities can be
underway concurrently. In this case then we must either use
additional expensive exclusive locking or not do the cache
re-recreate.

So the question really becomes what do we have to gain by releasing
and re-creating the cache since we spend a fairly significant amount
of effort on pruning stale entries during ongoing operation already.

This patch moves the allocation of the map entry cache (belonging to
the map source) into the function used to add the map source to the
master map entry and does not release and re-create the cache if the
source already exists for the given master map entry.
---

 CHANGELOG              |    1 +
 lib/master.c           |    6 ++++++
 lib/master_parse.y     |   10 ----------
 modules/mount_autofs.c |    8 --------
 4 files changed, 7 insertions(+), 18 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -39,6 +39,7 @@
 - fix parse_sun() module init.
 - dont check null cache on expire.
 - fix null cache race.
+- fix cache_init() on source re-read.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/lib/master.c
+++ autofs-5.0.5/lib/master.c
@@ -188,6 +188,12 @@ master_add_map_source(struct master_mape
 	source->argc = argc;
 	source->argv = tmpargv;
 
+	source->mc = cache_init(entry->ap, source);
+	if (!source->mc) {
+		master_free_map_source(source, 0);
+		return NULL;
+	}
+
 	master_source_writelock(entry);
 
 	if (!entry->maps) {
--- autofs-5.0.5.orig/lib/master_parse.y
+++ autofs-5.0.5/lib/master_parse.y
@@ -830,16 +830,6 @@ int master_parse_entry(const char *buffe
 		return 0;
 	}
 
-	if (!source->mc) {
-		source->mc = cache_init(entry->ap, source);
-		if (!source->mc) {
-			error(m_logopt, "failed to init source cache");
-			if (new)
-				master_free_mapent(new);
-			local_free_vars();
-			return 0;
-		}
-	}
 	source->master_line = lineno;
 
 	entry->age = age;
--- autofs-5.0.5.orig/modules/mount_autofs.c
+++ autofs-5.0.5/modules/mount_autofs.c
@@ -200,14 +200,6 @@ int mount_mount(struct autofs_point *ap,
 	}
 	free_map_type_info(info);
 
-	source->mc = cache_init(entry->ap, source);
-	if (!source->mc) {
-		error(ap->logopt, MODPREFIX "failed to init source cache");
-		master_free_map_source(source, 0);
-		master_free_mapent(entry);
-		return 1;
-	}
-
 	mounts_mutex_lock(ap);
 
 	if (handle_mounts_startup_cond_init(&suc)) {

autofs-5.0.5-fix-master-map-source-server-unavialable-handling.patch:
 CHANGELOG          |    1 +
 daemon/automount.c |    5 +++--
 daemon/lookup.c    |    9 +++++++++
 include/master.h   |    1 +
 lib/master.c       |    9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)

--- NEW FILE autofs-5.0.5-fix-master-map-source-server-unavialable-handling.patch ---
autofs-5.0.5 - fix master map source server unavailable handling

From: Ian Kent <raven at themaw.net>

If we get an NSS_STATUS_UNAVAIL from any server when trying to read
the master map we have no choice but to not update mounted automounts
because we can't know what entries may have come from the server that
isn't avialable. So we leave everything the way it is and wait until
the next re-read to update our mounts.
---

 CHANGELOG          |    1 +
 daemon/automount.c |    5 +++--
 daemon/lookup.c    |    9 +++++++++
 include/master.h   |    1 +
 lib/master.c       |    9 ++++++++-
 5 files changed, 22 insertions(+), 3 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -29,6 +29,7 @@
 - add locality as valid ldap master map attribute fix.
 - add simple bind authentication.
 - fix included map read fail handling (again).
+- fix master map source server unavailable handling.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/automount.c
+++ autofs-5.0.5/daemon/automount.c
@@ -1478,7 +1478,6 @@ static void handle_mounts_cleanup(void *
 		master_free_mapent_sources(ap->entry, 1);
 		master_free_mapent(ap->entry);
 	}
-	master_mutex_unlock();
 
 	if (clean) {
 		if (rmdir(path) == -1) {
@@ -1497,7 +1496,9 @@ static void handle_mounts_cleanup(void *
 	 */
 	if (!submount)
 		pthread_kill(state_mach_thid, SIGTERM);
-	
+
+	master_mutex_unlock();
+
 	return;
 }
 
--- autofs-5.0.5.orig/daemon/lookup.c
+++ autofs-5.0.5/daemon/lookup.c
@@ -157,6 +157,9 @@ int lookup_nss_read_master(struct master
 			result = do_read_master(master, "file", age);
 		}
 
+		if (result == NSS_STATUS_UNAVAIL)
+			master->read_fail = 1;
+
 		return !result;
 	} else {
 		char *name = master->name;
@@ -194,6 +197,9 @@ int lookup_nss_read_master(struct master
 				result = do_read_master(master, source, age);
 				master->name = name;
 
+				if (result == NSS_STATUS_UNAVAIL)
+					master->read_fail = 1;
+
 				return !result;
 			}
 		}
@@ -248,6 +254,9 @@ int lookup_nss_read_master(struct master
 			continue;
 		}
 
+		if (result == NSS_STATUS_UNAVAIL)
+			master->read_fail = 1;
+
 		status = check_nss_result(this, result);
 		if (status >= 0) {
 			free_sources(&nsslist);
--- autofs-5.0.5.orig/include/master.h
+++ autofs-5.0.5/include/master.h
@@ -56,6 +56,7 @@ struct master {
 	unsigned int recurse;
 	unsigned int depth;
 	unsigned int reading;
+	unsigned int read_fail;
 	unsigned int default_ghost;
 	unsigned int default_logging;
 	unsigned int default_timeout;
--- autofs-5.0.5.orig/lib/master.c
+++ autofs-5.0.5/lib/master.c
@@ -794,6 +794,7 @@ struct master *master_new(const char *na
 	master->recurse = 0;
 	master->depth = 0;
 	master->reading = 0;
+	master->read_fail = 0;
 	master->default_ghost = ghost;
 	master->default_timeout = timeout;
 	master->default_logging = defaults_get_logging();
@@ -821,7 +822,13 @@ int master_read_master(struct master *ma
 	master_init_scan();
 
 	lookup_nss_read_master(master, age);
-	master_mount_mounts(master, age, readall);
+	if (!master->read_fail)
+		master_mount_mounts(master, age, readall);
+	else {
+		master->read_fail = 0;
+		if (!readall)
+			master_mount_mounts(master, age, readall);
+	}
 
 	master_mutex_lock();
 

autofs-5.0.5-fix-negative-cache-included-map-lookup.patch:
 CHANGELOG       |    1 +
 daemon/lookup.c |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

--- NEW FILE autofs-5.0.5-fix-negative-cache-included-map-lookup.patch ---
autofs-5.0.5 - fix negative cache included map lookup

From: Ian Kent <raven at themaw.net>

If we are looking up a mount from multiple included map sources we
can't update the negative cache until we have looked at all sources.
If we don't postpone the negative cache update we will get a false
negative on a subsequent lookups.

Also clean up "not found" message.
---

 CHANGELOG       |    1 +
 daemon/lookup.c |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -42,6 +42,7 @@
 - fix cache_init() on source re-read.
 - fix mapent becomes negative during lookup.
 - check each dc server individually.
+- fix negative cache included map lookup.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/lookup.c
+++ autofs-5.0.5/daemon/lookup.c
@@ -813,6 +813,10 @@ static void update_negative_cache(struct
 	struct map_source *map;
 	struct mapent *me;
 
+	/* Don't update negative cache for included maps */
+	if (source && source->depth)
+		return;
+
 	/* Have we recorded the lookup fail for negative caching? */
 	me = lookup_source_mapent(ap, name, LKP_DISTINCT);
 	if (me)
@@ -823,7 +827,7 @@ static void update_negative_cache(struct
 		cache_unlock(me->mc);
 	else {
 		/* Notify only once after fail */
-		error(ap->logopt, "key \"%s\" not found in map.", name);
+		logmsg("key \"%s\" not found in map source(s).", name);
 
 		/* Doesn't exist in any source, just add it somewhere */
 		if (source)

autofs-5.0.5-fix-null-cache-race.patch:
 CHANGELOG           |    1 +
 daemon/automount.c  |    4 +++-
 include/automount.h |    1 +
 lib/cache.c         |   33 ++++++++++++++++++++++++++-------
 lib/master.c        |   27 ++++++++++++++++++++-------
 lib/master_parse.y  |    5 -----
 6 files changed, 51 insertions(+), 20 deletions(-)

--- NEW FILE autofs-5.0.5-fix-null-cache-race.patch ---
autofs-5.0.5 - fix null cache race

From: Ian Kent <raven at themaw.net>

The null map entry cache scope is across the entire master map but
it is used by individual master map entries during master map re-read
and subsequest updates resulting form it. The current null cache locking
doesn't properly account for this.

To resolve this, when we re-read the master, map we need to block
access to the null cache until the master map has been read and the
null cache updated.
---

 CHANGELOG           |    1 +
 daemon/automount.c  |    4 +++-
 include/automount.h |    1 +
 lib/cache.c         |   33 ++++++++++++++++++++++++++-------
 lib/master.c        |   27 ++++++++++++++++++++-------
 lib/master_parse.y  |    5 -----
 6 files changed, 51 insertions(+), 20 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -38,6 +38,7 @@
 - fix wildcard map entry match.
 - fix parse_sun() module init.
 - dont check null cache on expire.
+- fix null cache race.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/automount.c
+++ autofs-5.0.5/daemon/automount.c
@@ -1273,14 +1273,16 @@ static int do_hup_signal(struct master *
 	if (status)
 		fatal(status);
 
+	master_mutex_lock();
 	if (master->reading) {
 		status = pthread_mutex_unlock(&mrc.mutex);
 		if (status)
 			fatal(status);
+		master_mutex_unlock();
 		return 1;
 	}
-
 	master->reading = 1;
+	master_mutex_unlock();
 
 	status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL);
 	if (status) {
--- autofs-5.0.5.orig/include/automount.h
+++ autofs-5.0.5/include/automount.h
@@ -194,6 +194,7 @@ void cache_multi_writelock(struct mapent
 void cache_multi_unlock(struct mapent *me);
 int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
 void cache_release(struct map_source *map);
+void cache_clean_null_cache(struct mapent_cache *mc);
 void cache_release_null_cache(struct master *master);
 struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me);
 char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos);
--- autofs-5.0.5.orig/lib/cache.c
+++ autofs-5.0.5/lib/cache.c
@@ -228,15 +228,38 @@ struct mapent_cache *cache_init(struct a
 	return mc;
 }
 
+void cache_clean_null_cache(struct mapent_cache *mc)
+{
+	struct mapent *me, *next;
+	int i;
+
+	for (i = 0; i < mc->size; i++) {
+		me = mc->hash[i];
+		if (me == NULL)
+			continue;
+		next = me->next;
+		free(me->key);
+		if (me->mapent)
+			free(me->mapent);
+		free(me);
+
+		while (next != NULL) {
+			me = next;
+			next = me->next;
+			free(me->key);
+			free(me);
+		}
+	}
+
+	return;
+}
+
 struct mapent_cache *cache_init_null_cache(struct master *master)
 {
 	struct mapent_cache *mc;
 	unsigned int i;
 	int status;
 
-	if (master->nc)
-		cache_release_null_cache(master);
-
 	mc = malloc(sizeof(struct mapent_cache));
 	if (!mc)
 		return NULL;
@@ -264,8 +287,6 @@ struct mapent_cache *cache_init_null_cac
 	if (status)
 		fatal(status);
 
-	cache_writelock(mc);
-
 	for (i = 0; i < mc->size; i++) {
 		mc->hash[i] = NULL;
 		INIT_LIST_HEAD(&mc->ino_index[i]);
@@ -274,8 +295,6 @@ struct mapent_cache *cache_init_null_cac
 	mc->ap = NULL;
 	mc->map = NULL;
 
-	cache_unlock(mc);
-
 	return mc;
 }
 
--- autofs-5.0.5.orig/lib/master.c
+++ autofs-5.0.5/lib/master.c
@@ -811,15 +811,28 @@ int master_read_master(struct master *ma
 	unsigned int logopt = master->logopt;
 	struct mapent_cache *nc;
 
-	nc = cache_init_null_cache(master);
-	if (!nc) {
-		error(logopt,
-		      "failed to init null map cache for %s", master->name);
-		return 0;
+	/*
+	 * We need to clear and re-populate the null map entry cache
+	 * before alowing anyone else to use it.
+	 */
+	if (master->nc) {
+		cache_writelock(master->nc);
+		nc = master->nc;
+		cache_clean_null_cache(nc);
+	} else {
+		nc = cache_init_null_cache(master);
+		if (!nc) {
+			error(logopt,
+			      "failed to init null map cache for %s",
+			      master->name);
+			return 0;
+		}
+		cache_writelock(nc);
+		master->nc = nc;
 	}
-	master->nc = nc;
-
 	master_init_scan();
+	lookup_nss_read_master(master, age);
+	cache_unlock(nc);
 
 	lookup_nss_read_master(master, age);
 	if (!master->read_fail)
--- autofs-5.0.5.orig/lib/master_parse.y
+++ autofs-5.0.5/lib/master_parse.y
@@ -741,21 +741,16 @@ int master_parse_entry(const char *buffe
 
 	/* Add null map entries to the null map cache */
 	if (type && !strcmp(type, "null")) {
-		cache_writelock(nc);
 		cache_update(nc, NULL, path, NULL, lineno);
-		cache_unlock(nc);
 		local_free_vars();
 		return 1;
 	}
 
 	/* Ignore all subsequent matching nulled entries */
-	cache_readlock(nc);
 	if (cache_lookup_distinct(nc, path)) {
-		cache_unlock(nc);
 		local_free_vars();
 		return 1;
 	}
-	cache_unlock(nc);
 
 	if (debug || verbose) {
 		logopt = (debug ? LOGOPT_DEBUG : 0);

autofs-5.0.5-fix-parse_sun-module-init.patch:
 CHANGELOG           |    1 +
 modules/parse_sun.c |   37 ++++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

--- NEW FILE autofs-5.0.5-fix-parse_sun-module-init.patch ---
autofs-5.0.5 - fix parse_sun() module init

From: Ian Kent <raven at themaw.net>

In the parse sun module we pre-open the NFS mount module and cache
the library handle because it is used so often. Since this is shared
amonst all the master map entries multiple threads can race when
accessing the instance counter, especially when there are many
master map entries, leading to a double close on the mount library
handle.
---

 CHANGELOG           |    1 +
 modules/parse_sun.c |   37 ++++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -36,6 +36,7 @@
 - don't hold lock for simple mounts.
 - fix remount locking.
 - fix wildcard map entry match.
+- fix parse_sun() module init.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/modules/parse_sun.c
+++ autofs-5.0.5/modules/parse_sun.c
@@ -45,6 +45,22 @@ int parse_version = AUTOFS_PARSE_VERSION
 
 static struct mount_mod *mount_nfs = NULL;
 static int init_ctr = 0;
+static int macro_init_done = 0;
+static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void instance_mutex_lock(void)
+{
+	int status = pthread_mutex_lock(&instance_mutex);
+	if (status)
+		fatal(status);
+}
+
+static void instance_mutex_unlock(void)
+{
+	int status = pthread_mutex_unlock(&instance_mutex);
+	if (status)
+		fatal(status);
+}
 
 extern const char *global_options;
 
@@ -276,9 +292,12 @@ int parse_init(int argc, const char *con
 	unsigned int append_options;
 
 	/* Get processor information for predefined escapes */
-
-	if (!init_ctr)
+	macro_lock();
+	if (!macro_init_done) {
+		macro_init_done = 1;
 		macro_init();
+	}
+	macro_unlock();
 
 	/* Set up context and escape chain */
 
@@ -434,19 +453,21 @@ options_done:
 
 	/* We only need this once.  NFS mounts are so common that we cache
 	   this module. */
-	if (!mount_nfs) {
+	instance_mutex_lock();
+	if (mount_nfs)
+		init_ctr++;
+	else {
 		if ((mount_nfs = open_mount("nfs", MODPREFIX))) {
 			init_ctr++;
-			return 0;
 		} else {
 			kill_context(ctxt);
 			*context = NULL;
+			instance_mutex_unlock();
 			return 1;
 		}
-	} else {
-		init_ctr++;
-		return 0;
 	}
+	instance_mutex_unlock();
+	return 0;
 }
 
 static const char *parse_options(const char *str, char **ret, unsigned int logopt)
@@ -1734,10 +1755,12 @@ int parse_done(void *context)
 	int rv = 0;
 	struct parse_context *ctxt = (struct parse_context *) context;
 
+	instance_mutex_lock();
 	if (--init_ctr == 0) {
 		rv = close_mount(mount_nfs);
 		mount_nfs = NULL;
 	}
+	instance_mutex_unlock();
 	if (ctxt)
 		kill_context(ctxt);
 

autofs-5.0.5-fix-random-selection-for-host-on-different-network.patch:
 CHANGELOG            |    1 +
 include/replicated.h |    2 +-
 modules/mount_nfs.c  |    2 +-
 modules/replicated.c |   28 ++++++++++++++++++++--------
 4 files changed, 23 insertions(+), 10 deletions(-)

--- NEW FILE autofs-5.0.5-fix-random-selection-for-host-on-different-network.patch ---
autofs-5.0.5 - fix random selection for host on different network

From: Ian Kent <raven at themaw.net>

When we select from a list of hosts from which we can mount the list
is ordered by response time within proximity.

This is intended for normal selection but when using random selection
if any hosts are on another network (and so considered further away)
they will never be at the head of the list and so are unlikely to be
used. This leads to a limited set of hosts being used for mounts which
usually isn't what's required when the random selection option is used.
---

 CHANGELOG            |    1 +
 include/replicated.h |    2 +-
 modules/mount_nfs.c  |    2 +-
 modules/replicated.c |   28 ++++++++++++++++++++--------
 4 files changed, 23 insertions(+), 10 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -31,6 +31,7 @@
 - fix included map read fail handling (again).
 - fix master map source server unavailable handling.
 - add autofs_ldap_auth.conf man page.
+- fix random selection for host on different network.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/include/replicated.h
+++ autofs-5.0.5/include/replicated.h
@@ -64,7 +64,7 @@ struct host {
 
 void seed_random(void);
 void free_host_list(struct host **);
-int parse_location(unsigned, struct host **, const char *);
+int parse_location(unsigned, struct host **, const char *, unsigned int);
 int prune_host_list(unsigned, struct host **, unsigned int, const char *, unsigned int);
 void dump_host_list(struct host *);
 
--- autofs-5.0.5.orig/modules/mount_nfs.c
+++ autofs-5.0.5/modules/mount_nfs.c
@@ -137,7 +137,7 @@ int mount_mount(struct autofs_point *ap,
 	else if (mount_default_proto == 4)
 		vers = vers | NFS4_VERS_MASK;
 
-	if (!parse_location(ap->logopt, &hosts, what)) {
+	if (!parse_location(ap->logopt, &hosts, what, random_selection)) {
 		info(ap->logopt, MODPREFIX "no hosts available");
 		return 1;
 	}
--- autofs-5.0.5.orig/modules/replicated.c
+++ autofs-5.0.5/modules/replicated.c
@@ -1041,13 +1041,23 @@ int prune_host_list(unsigned logopt, str
 
 static int add_new_host(struct host **list,
 			const char *host, unsigned int weight,
-			struct addrinfo *host_addr)
+			struct addrinfo *host_addr,
+			unsigned int random_selection)
 {
 	struct host *new;
 	unsigned int prx;
 	int addr_len;
 
-	prx = get_proximity(host_addr->ai_addr);
+	/*
+	 * If we are using random selection we pretend all hosts are at
+	 * the same proximity so hosts further away don't get excluded.
+	 * We can't use PROXIMITY_LOCAL or we won't perform an RPC ping
+	 * to remove hosts that may be down.
+	 */
+	if (random_selection)
+		prx = PROXIMITY_SUBNET;
+	else
+		prx = get_proximity(host_addr->ai_addr);
 	/*
 	 * If we tried to add an IPv6 address and we don't have IPv6
 	 * support return success in the hope of getting an IPv4
@@ -1071,7 +1081,8 @@ static int add_new_host(struct host **li
 	return 1;
 }
 
-static int add_host_addrs(struct host **list, const char *host, unsigned int weight)
+static int add_host_addrs(struct host **list, const char *host,
+			  unsigned int weight, unsigned int random_selection)
 {
 	struct addrinfo hints, *ni, *this;
 	int ret;
@@ -1087,7 +1098,7 @@ static int add_host_addrs(struct host **
 
 	this = ni;
 	while (this) {
-		ret = add_new_host(list, host, weight, this);
+		ret = add_new_host(list, host, weight, this, random_selection);
 		if (!ret)
 			break;
 		this = this->ai_next;
@@ -1110,7 +1121,7 @@ try_name:
 
 	this = ni;
 	while (this) {
-		ret = add_new_host(list, host, weight, this);
+		ret = add_new_host(list, host, weight, this, random_selection);
 		if (!ret)
 			break;
 		this = this->ai_next;
@@ -1197,7 +1208,8 @@ static char *seek_delim(const char *s)
 	return NULL;
 }
 
-int parse_location(unsigned logopt, struct host **hosts, const char *list)
+int parse_location(unsigned logopt, struct host **hosts,
+		   const char *list, unsigned int random_selection)
 {
 	char *str, *p, *delim;
 	unsigned int empty = 1;
@@ -1252,7 +1264,7 @@ int parse_location(unsigned logopt, stru
 				}
 
 				if (p != delim) {
-					if (!add_host_addrs(hosts, p, weight)) {
+					if (!add_host_addrs(hosts, p, weight, random_selection)) {
 						if (empty) {
 							p = next;
 							continue;
@@ -1274,7 +1286,7 @@ int parse_location(unsigned logopt, stru
 				*delim = '\0';
 				next = delim + 1;
 
-				if (!add_host_addrs(hosts, p, weight)) {
+				if (!add_host_addrs(hosts, p, weight, random_selection)) {
 					p = next;
 					continue;
 				}

autofs-5.0.5-fix-remount-locking.patch:
 CHANGELOG                |    1 +
 modules/lookup_file.c    |   27 +++++++++++++++++----------
 modules/lookup_hosts.c   |   24 +++++++++++++++---------
 modules/lookup_ldap.c    |   24 ++++++++++++++++--------
 modules/lookup_nisplus.c |   29 ++++++++++++++++++-----------
 modules/lookup_program.c |   29 +++++++++++++++++++++--------
 modules/lookup_yp.c      |   27 +++++++++++++++++----------
 7 files changed, 105 insertions(+), 56 deletions(-)

--- NEW FILE autofs-5.0.5-fix-remount-locking.patch ---
autofs-5.0.5 - fix remount locking

From: Ian Kent <raven at themaw.net>

When autofs is restarted with active mounts it is possible, due
to possible recursion when mounting multi-mount map entries, that
a lookup module will take a write lock on the map entry cache
when a read lock is alreay held.

Since, during the re-mount, we are still essentially running
single threaded we need only take care to ensure we don't take
the write lock.
---

 CHANGELOG                |    1 +
 modules/lookup_file.c    |   27 +++++++++++++++++----------
 modules/lookup_hosts.c   |   24 +++++++++++++++---------
 modules/lookup_ldap.c    |   24 ++++++++++++++++--------
 modules/lookup_nisplus.c |   29 ++++++++++++++++++-----------
 modules/lookup_program.c |   29 +++++++++++++++++++++--------
 modules/lookup_yp.c      |   27 +++++++++++++++++----------
 7 files changed, 105 insertions(+), 56 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -34,6 +34,7 @@
 - fix random selection for host on different network.
 - make redhat init script more lsb compliant.
 - don't hold lock for simple mounts.
+- fix remount locking.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/modules/lookup_file.c
+++ autofs-5.0.5/modules/lookup_file.c
@@ -871,7 +871,6 @@ static int check_map_indirect(struct aut
 	if (ret == CHE_FAIL)
 		return NSS_STATUS_NOTFOUND;
 
-	pthread_cleanup_push(cache_lock_cleanup, mc);
 	cache_writelock(mc);
 	exists = cache_lookup_distinct(mc, key);
 	/* Not found in the map but found in the cache */
@@ -882,7 +881,7 @@ static int check_map_indirect(struct aut
 			exists->status = 0;
 		}
 	}
-	pthread_cleanup_pop(1);
+	cache_unlock(mc);
 
 	if (ret == CHE_MISSING) {
 		struct mapent *we;
@@ -896,7 +895,6 @@ static int check_map_indirect(struct aut
 		 * Check for map change and update as needed for
 		 * following cache lookup.
 		 */
-		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
 		we = cache_lookup_distinct(mc, "*");
 		if (we) {
@@ -904,7 +902,7 @@ static int check_map_indirect(struct aut
 			if (we->source == source && (wild & CHE_MISSING))
 				cache_delete(mc, "*");
 		}
-		pthread_cleanup_pop(1);
+		cache_unlock(mc);
 
 		if (wild & (CHE_OK | CHE_UPDATED))
 			return NSS_STATUS_SUCCESS;
@@ -957,13 +955,22 @@ int lookup_mount(struct autofs_point *ap
 		if (me->status >= time(NULL)) {
 			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
+
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, key);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, key);
+				cache_unlock(smc);
+			}
 		}
-
-		/* Negative timeout expired for non-existent entry. */
-		if (!me->mapent)
-			cache_delete(me->mc, key);
-
-		cache_unlock(me->mc);
 	}
 
 	/*
--- autofs-5.0.5.orig/modules/lookup_hosts.c
+++ autofs-5.0.5/modules/lookup_hosts.c
@@ -146,19 +146,25 @@ int lookup_mount(struct autofs_point *ap
 	/* Check if we recorded a mount fail for this key anywhere */
 	me = lookup_source_mapent(ap, name, LKP_DISTINCT);
 	if (me) {
-		struct mapent_cache *fmc = me->mc;
-
 		if (me->status >= time(NULL)) {
-			cache_unlock(fmc);
+			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
-		}
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
 
-		if (!me->mapent) {
-			cache_delete(fmc, name);
-			me = NULL;
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, name);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, name);
+				cache_unlock(smc);
+			}
 		}
-
-		cache_unlock(fmc);
 	}
 
 	cache_readlock(mc);
--- autofs-5.0.5.orig/modules/lookup_ldap.c
+++ autofs-5.0.5/modules/lookup_ldap.c
@@ -2681,7 +2681,6 @@ next:
 	unbind_ldap_connection(ap->logopt, ldap, ctxt);
 
 	/* Failed to find wild entry, update cache if needed */
-	pthread_cleanup_push(cache_lock_cleanup, mc);
 	cache_writelock(mc);
 	we = cache_lookup_distinct(mc, "*");
 	if (we) {
@@ -2707,7 +2706,7 @@ next:
 			}
 		}
 	}
-	pthread_cleanup_pop(1);
+	cache_unlock(mc);
 	free(query);
 
 	return ret;
@@ -2817,13 +2816,22 @@ int lookup_mount(struct autofs_point *ap
 		if (me->status >= time(NULL)) {
 			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
+
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, key);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, key);
+				cache_unlock(smc);
+			}
 		}
-
-		/* Negative timeout expired for non-existent entry. */
-		if (!me->mapent)
-			cache_delete(me->mc, key);
-
-		cache_unlock(me->mc);
 	}
 
         /*
--- autofs-5.0.5.orig/modules/lookup_nisplus.c
+++ autofs-5.0.5/modules/lookup_nisplus.c
@@ -421,7 +421,6 @@ static int check_map_indirect(struct aut
 		return NSS_STATUS_UNAVAIL;
 	}
 
-	pthread_cleanup_push(cache_lock_cleanup, mc);
 	cache_writelock(mc);
 	t_last_read = ap->exp_runfreq + 1;
 	me = cache_lookup_first(mc);
@@ -442,8 +441,8 @@ static int check_map_indirect(struct aut
 			exists->status = 0;
 		}
 	}
-	pthread_cleanup_pop(1);
-	
+	cache_unlock(mc);
+
 	if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
 		source->stale = 1;
 
@@ -459,7 +458,6 @@ static int check_map_indirect(struct aut
 		 * Check for map change and update as needed for
 		 * following cache lookup.
 		*/
-		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
 		we = cache_lookup_distinct(mc, "*");
 		if (we) {
@@ -473,7 +471,7 @@ static int check_map_indirect(struct aut
 			if (wild & (CHE_OK | CHE_UPDATED))
 				source->stale = 1;
 		}
-		pthread_cleanup_pop(1);
+		cache_unlock(mc);
 
 		if (wild & (CHE_UPDATED | CHE_OK))
 			return NSS_STATUS_SUCCESS;
@@ -516,13 +514,22 @@ int lookup_mount(struct autofs_point *ap
 		if (me->status >= time(NULL)) {
 			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
-		}
-
-		/* Negative timeout expired for non-existent entry. */
-		if (!me->mapent)
-			cache_delete(me->mc, key);
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
 
-		cache_unlock(me->mc);
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, key);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, key);
+				cache_unlock(smc);
+			}
+		}
 	}
 
 	/*
--- autofs-5.0.5.orig/modules/lookup_program.c
+++ autofs-5.0.5/modules/lookup_program.c
@@ -135,17 +135,26 @@ int lookup_mount(struct autofs_point *ap
 		if (me->status >= time(NULL)) {
 			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
-		}
-
-		/* Negative timeout expired for non-existent entry. */
-		if (!me->mapent)
-			cache_delete(me->mc, name);
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
 
-		cache_unlock(me->mc);
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, name);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, name);
+				cache_unlock(smc);
+			}
+		}
 	}
 
 	/* Catch installed direct offset triggers */
-	cache_writelock(mc);
+	cache_readlock(mc);
 	me = cache_lookup_distinct(mc, name);
 	if (!me) {
 		cache_unlock(mc);
@@ -191,7 +200,11 @@ int lookup_mount(struct autofs_point *ap
 				     " key %s, returning fail", name);
 				return NSS_STATUS_UNAVAIL;
 			}
-			cache_delete(mc, name);
+			cache_unlock(mc);
+			cache_writelock(mc);
+			me = cache_lookup_distinct(mc, name);
+			if (me)
+				cache_delete(mc, name);
 			cache_unlock(mc);
 		}
 	}
--- autofs-5.0.5.orig/modules/lookup_yp.c
+++ autofs-5.0.5/modules/lookup_yp.c
@@ -533,7 +533,6 @@ static int check_map_indirect(struct aut
 		source->stale = 1;
 	}
 
-	pthread_cleanup_push(cache_lock_cleanup, mc);
 	cache_writelock(mc);
 	exists = cache_lookup_distinct(mc, key);
 	/* Not found in the map but found in the cache */
@@ -545,7 +544,7 @@ static int check_map_indirect(struct aut
 			exists->status = 0;
 		}
 	}
-	pthread_cleanup_pop(1);
+	cache_unlock(mc);
 
 	if (ret == CHE_MISSING) {
 		struct mapent *we;
@@ -559,7 +558,6 @@ static int check_map_indirect(struct aut
 		 * Check for map change and update as needed for
 		 * following cache lookup.
 		 */
-		pthread_cleanup_push(cache_lock_cleanup, mc);
 		cache_writelock(mc);
 		we = cache_lookup_distinct(mc, "*");
 		if (we) {
@@ -573,7 +571,7 @@ static int check_map_indirect(struct aut
 			if (wild & (CHE_OK | CHE_UPDATED))
 				source->stale = 1;
 		}
-		pthread_cleanup_pop(1);
+		cache_unlock(mc);
 
 		if (wild & (CHE_OK | CHE_UPDATED))
 			return NSS_STATUS_SUCCESS;
@@ -616,13 +614,22 @@ int lookup_mount(struct autofs_point *ap
 		if (me->status >= time(NULL)) {
 			cache_unlock(me->mc);
 			return NSS_STATUS_NOTFOUND;
-		}
-
-		/* Negative timeout expired for non-existent entry. */
-		if (!me->mapent)
-			cache_delete(me->mc, key);
+		} else {
+			struct mapent_cache *smc = me->mc;
+			struct mapent *sme;
 
-		cache_unlock(me->mc);
+			if (me->mapent)
+				cache_unlock(smc);
+			else {
+				cache_unlock(smc);
+				cache_writelock(smc);
+				sme = cache_lookup_distinct(smc, key);
+				/* Negative timeout expired for non-existent entry. */
+				if (sme && !sme->mapent)
+					cache_delete(smc, key);
+				cache_unlock(smc);
+			}
+		}
 	}
 
 	 /*

autofs-5.0.5-fix-wildcard-map-entry-match.patch:
 CHANGELOG       |    1 +
 daemon/lookup.c |    4 ++--
 lib/cache.c     |    2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

--- NEW FILE autofs-5.0.5-fix-wildcard-map-entry-match.patch ---
autofs-5.0.5 - fix wildcard map entry match

From: Ian Kent <raven at themaw.net>

In some cases we can get a key string that includes a '*' at the start.
This causes an incorrect comparison in the cache library routines and can
lead to a segmentation fault.

This patch enures that the key length is also considered when checking the
wildcard key entry.
---

 CHANGELOG       |    1 +
 daemon/lookup.c |    4 ++--
 lib/cache.c     |    2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -35,6 +35,7 @@
 - make redhat init script more lsb compliant.
 - don't hold lock for simple mounts.
 - fix remount locking.
+- fix wildcard map entry match.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/lookup.c
+++ autofs-5.0.5/daemon/lookup.c
@@ -600,7 +600,7 @@ int lookup_ghost(struct autofs_point *ap
 		cache_readlock(mc);
 		me = cache_enumerate(mc, NULL);
 		while (me) {
-			if (*me->key == '*')
+			if (!strcmp(me->key, "*"))
 				goto next;
 
 			if (*me->key == '/') {
@@ -1035,7 +1035,7 @@ void lookup_prune_one_cache(struct autof
 
 		key = strdup(me->key);
 		me = cache_enumerate(mc, me);
-		if (!key || *key == '*') {
+		if (!key || !strcmp(key, "*")) {
 			if (key)
 				free(key);
 			continue;
--- autofs-5.0.5.orig/lib/cache.c
+++ autofs-5.0.5/lib/cache.c
@@ -719,7 +719,7 @@ int cache_update(struct mapent_cache *mc
 	me = cache_lookup(mc, key);
 	while (me && me->source != ms)
 		me = cache_lookup_key_next(me);
-	if (!me || (*me->key == '*' && *key != '*')) {
+	if (!me || (!strcmp(me->key, "*") && strcmp(key, "*"))) {
 		ret = cache_add(mc, ms, key, mapent, age);
 		if (!ret) {
 			debug(logopt, "failed for %s", key);

autofs-5.0.5-make-redhat-init-script-more-lsb-compliant.patch:
 CHANGELOG             |    1 +
 redhat/autofs.init.in |   39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)

--- NEW FILE autofs-5.0.5-make-redhat-init-script-more-lsb-compliant.patch ---
autofs-5.0.5 - make redhat init script more lsb compliant

From: Ian Kent <raven at themaw.net>


---

 CHANGELOG             |    1 +
 redhat/autofs.init.in |   39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -32,6 +32,7 @@
 - fix master map source server unavailable handling.
 - add autofs_ldap_auth.conf man page.
 - fix random selection for host on different network.
+- make redhat init script more lsb compliant.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/redhat/autofs.init.in
+++ autofs-5.0.5/redhat/autofs.init.in
@@ -86,14 +86,18 @@ function start() {
 	fi
 
 	echo -n $"Starting $prog: "
-	$prog $OPTIONS 
+	$prog $OPTIONS --pid-file /var/run/autofs.pid
 	RETVAL=$?
 	if [ $RETVAL -eq 0 ] ; then
 		success "$prog startup"
 	else
 		failure "$prog startup"
 	fi
-	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/autofs
+	if [ $RETVAL -eq 0 ]; then
+		touch /var/lock/subsys/autofs
+	else
+		RETVAL=1
+	fi
 	echo
 	return $RETVAL
 }
@@ -107,7 +111,11 @@ function stop() {
 		[ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 3
 		count=`expr $count + 1`
 	done
-	[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/autofs
+	if [ $RETVAL -eq 0 ]; then
+		rm -f /var/lock/subsys/autofs
+	else
+		RETVAL=1
+	fi
 	if [ -n "`pidof $prog`" ] ; then
 		failure "$prog shutdown"
 	else
@@ -118,7 +126,10 @@ function stop() {
 }
 
 function restart() {
-	stop
+	status > /dev/null 2>&1
+	if [ $? -eq 0 ]; then
+		stop
+	fi
 	start
 }
 
@@ -142,6 +153,12 @@ function reload() {
 
 RETVAL=0
 
+# Only the root user may change the service status
+if [ `id -u` -ne 0 ]; then
+	echo "insufficient privilege to change service status"
+	exit 4
+fi
+
 case "$1" in
 	start)
 		start
@@ -154,7 +171,7 @@ case "$1" in
 		stop
 		;;
 	status)
-		status $prog
+		status -p /var/run/autofs.pid -l autofs $prog
 		;;
 	restart)
 		restart
@@ -171,9 +188,17 @@ case "$1" in
 			restart
 		fi
 		;;
-	*)
+	usage)
 		echo $"Usage: $0 {start|forcestart|stop|status|restart|forcerestart|reload|condrestart}"
-		exit 1;
+		exit 0
+		;;
+	try-restart|force-reload)
+		echo "$1 service action not supported"
+		exit 3
+		;;
+	*)
+		echo "unknown, invalid or excess argument(s)"
+		exit 2
 		;;
 esac
 

autofs-5.0.5-mapent-becomes-negative-during-lookup.patch:
 CHANGELOG                |    1 +
 modules/lookup_file.c    |    2 +-
 modules/lookup_ldap.c    |    2 +-
 modules/lookup_nisplus.c |    2 +-
 modules/lookup_yp.c      |    2 +-
 5 files changed, 5 insertions(+), 4 deletions(-)

--- NEW FILE autofs-5.0.5-mapent-becomes-negative-during-lookup.patch ---
autofs-5.0.5 - mapent becomes negative during lookup

From: Ian Kent <raven at themaw.net>

During a mount request it is possible for a mapent to become negative
between the time it is checked on entry and when we fetch the mount
location information. This is because we drop the cache lock after
the initial check and take it back again before getting the location
information.
---

 CHANGELOG                |    1 +
 modules/lookup_file.c    |    2 +-
 modules/lookup_ldap.c    |    2 +-
 modules/lookup_nisplus.c |    2 +-
 modules/lookup_yp.c      |    2 +-
 5 files changed, 5 insertions(+), 4 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -40,6 +40,7 @@
 - dont check null cache on expire.
 - fix null cache race.
 - fix cache_init() on source re-read.
+- fix mapent becomes negative during lookup.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/modules/lookup_file.c
+++ autofs-5.0.5/modules/lookup_file.c
@@ -1047,7 +1047,7 @@ do_cache_lookup:
 		if (!me)
 			me = cache_lookup_distinct(mc, "*");
 	}
-	if (me && (me->source == source || *me->key == '/')) {
+	if (me && me->mapent && (me->source == source || *me->key == '/')) {
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		strcpy(mapent_buf, me->mapent);
 		mapent = mapent_buf;
--- autofs-5.0.5.orig/modules/lookup_ldap.c
+++ autofs-5.0.5/modules/lookup_ldap.c
@@ -2872,7 +2872,7 @@ int lookup_mount(struct autofs_point *ap
 		if (!me)
 			me = cache_lookup_distinct(mc, "*");
 	}
-	if (me && (me->source == source || *me->key == '/')) {
+	if (me && me->mapent && (me->source == source || *me->key == '/')) {
 		strcpy(mapent_buf, me->mapent);
 		mapent = mapent_buf;
 	}
--- autofs-5.0.5.orig/modules/lookup_nisplus.c
+++ autofs-5.0.5/modules/lookup_nisplus.c
@@ -569,7 +569,7 @@ int lookup_mount(struct autofs_point *ap
 		if (!me)
 			me = cache_lookup_distinct(mc, "*");
 	}
-	if (me && (me->source == source || *me->key == '/')) {
+	if (me && me->mapent && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = malloc(mapent_len + 1);
 		strcpy(mapent, me->mapent);
--- autofs-5.0.5.orig/modules/lookup_yp.c
+++ autofs-5.0.5/modules/lookup_yp.c
@@ -670,7 +670,7 @@ int lookup_mount(struct autofs_point *ap
 		if (!me)
 			me = cache_lookup_distinct(mc, "*");
 	}
-	if (me && (me->source == source || *me->key == '/')) {
+	if (me && me->mapent && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
 		strcpy(mapent, me->mapent);

autofs-5.0.5-remove-state-machine-timed-wait.patch:
 CHANGELOG      |    1 +
 daemon/state.c |   30 +++++++-----------------------
 2 files changed, 8 insertions(+), 23 deletions(-)

--- NEW FILE autofs-5.0.5-remove-state-machine-timed-wait.patch ---
autofs-5.0.5 - remove state machine timed wait

From: Ian Kent <raven at themaw.net>

We are seeing a problem using timed waits when running under KVM.

Using timed condition waits in the state machine (and in some other
places) has been used because of observed task throughput problems
in the past. Also, we've seen condition waits not reacting to signals
occassionaly.

But now we are seeing problems with the setup of the wait time within
KVM VMs causing the condition wait to go into a tight loop using
excessive CPU.

Changing the state queue handler to not use timed waits appears to
not have the previously observed throughput problems, hopefully we
won't see lost signals either.
---

 CHANGELOG      |    1 +
 daemon/state.c |   30 +++++++-----------------------
 2 files changed, 8 insertions(+), 23 deletions(-)


--- autofs-5.0.5.orig/CHANGELOG
+++ autofs-5.0.5/CHANGELOG
@@ -43,6 +43,7 @@
 - fix mapent becomes negative during lookup.
 - check each dc server individually.
 - fix negative cache included map lookup.
+- remove state machine timed wait.
 
 03/09/2009 autofs-5.0.5
 -----------------------
--- autofs-5.0.5.orig/daemon/state.c
+++ autofs-5.0.5/daemon/state.c
@@ -197,11 +197,11 @@ void expire_cleanup(void *arg)
 		}
 	}
 
+	st_set_done(ap);
+
 	if (next != ST_INVAL)
 		__st_add_task(ap, next);
 
-	st_set_done(ap);
-
 	st_mutex_unlock();
 
 	return;
@@ -332,11 +332,10 @@ static void do_readmap_cleanup(void *arg
 	st_mutex_lock();
 
 	ap->readmap_thread = 0;
-	st_ready(ap);
 	st_set_done(ap);
-
 	if (!ap->submount)
 		alarm_add(ap, ap->exp_runfreq);
+	st_ready(ap);
 
 	st_mutex_unlock();
 
@@ -1060,8 +1059,6 @@ static void *st_queue_handler(void *arg)
 {
 	struct list_head *head;
 	struct list_head *p;
-	struct timespec wait;
-	struct timeval now;
 	int status, ret;
 
 	st_mutex_lock();
@@ -1072,17 +1069,11 @@ static void *st_queue_handler(void *arg)
 		 * entry is added.
 		 */
 		head = &state_queue;
-		gettimeofday(&now, NULL);
-		wait.tv_sec = now.tv_sec + 1;
-		wait.tv_nsec = now.tv_usec * 1000;
 
 		while (list_empty(head)) {
-			status = pthread_cond_timedwait(&cond, &mutex, &wait);
-			if (status) {
-				if (status == ETIMEDOUT)
-					break;
+			status = pthread_cond_wait(&cond, &mutex);
+			if (status)
 				fatal(status);
-			}
 		}
 
 		p = head->next;
@@ -1108,18 +1099,11 @@ static void *st_queue_handler(void *arg)
 		}
 
 		while (1) {
-			gettimeofday(&now, NULL);
-			wait.tv_sec = now.tv_sec + 1;
-			wait.tv_nsec = now.tv_usec * 1000;
-
 			signaled = 0;
 			while (!signaled) {
-				status = pthread_cond_timedwait(&cond, &mutex, &wait);
-				if (status) {
-					if (status == ETIMEDOUT)
-						break;
+				status = pthread_cond_wait(&cond, &mutex);
+				if (status)
 					fatal(status);
-				}
 			}
 
 			head = &state_queue;


Index: autofs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-13/autofs.spec,v
retrieving revision 1.308
retrieving revision 1.309
diff -u -p -r1.308 -r1.309
--- autofs.spec	3 May 2010 05:53:04 -0000	1.308
+++ autofs.spec	11 Jun 2010 02:44:47 -0000	1.309
@@ -4,11 +4,10 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 Version: 5.0.5
-Release: 25%{?dist}
+Release: 26%{?dist}
 Epoch: 1
 License: GPLv2+
 Group: System Environment/Daemons
-URL: http://wiki.autofs.net/
 Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2
 Patch1: autofs-5.0.5-fix-included-map-read-fail-handling.patch
 Patch2: autofs-5.0.5-refactor-ldap-sasl-bind.patch
@@ -40,6 +39,21 @@ Patch27: autofs-5.0.5-add-locality-as-va
 Patch28: autofs-5.0.5-make-nfs4-default-for-redhat-replicated-selection.patch
 Patch29: autofs-5.0.5-add-simple-bind-auth.patch
 Patch30: autofs-5.0.5-fix-included-map-read-fail-handling-2.patch
+Patch31: autofs-5.0.5-fix-master-map-source-server-unavialable-handling.patch
+Patch32: autofs-5.0.5-add-autofs_ldap_auth_conf-man-page.patch
+Patch33: autofs-5.0.5-fix-random-selection-for-host-on-different-network.patch
+Patch34: autofs-5.0.5-make-redhat-init-script-more-lsb-compliant.patch
+Patch35: autofs-5.0.5-dont-hold-lock-for-simple-mounts.patch
+Patch36: autofs-5.0.5-fix-remount-locking.patch
+Patch37: autofs-5.0.5-fix-wildcard-map-entry-match.patch
+Patch38: autofs-5.0.5-fix-parse_sun-module-init.patch
+Patch39: autofs-5.0.5-dont-check-null-cache-on-expire.patch
+Patch40: autofs-5.0.5-fix-null-cache-race.patch
+Patch41: autofs-5.0.5-fix-cache_init-on-source-re-read.patch
+Patch42: autofs-5.0.5-mapent-becomes-negative-during-lookup.patch
+Patch43: autofs-5.0.5-check-each-dc-server.patch
+Patch44: autofs-5.0.5-fix-negative-cache-included-map-lookup.patch
+Patch45: autofs-5.0.5-remove-state-machine-timed-wait.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel
 Conflicts: cyrus-sasl-lib < 2.1.23-8
@@ -112,6 +126,21 @@ echo %{version}-%{release} > .version
 %patch28 -p1
 %patch29 -p1
 %patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
+%patch40 -p1
+%patch41 -p1
+%patch42 -p1
+%patch43 -p1
+%patch44 -p1
+%patch45 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -164,6 +193,24 @@ fi
 %{_libdir}/autofs/
 
 %changelog
+* Fri Jun 11 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-26.fc13
+- remove URL tag as there is not official autofs wiki (bz529804).
+- fix master map source server unavailable handling.
+- add autofs_ldap_auth.conf man page.
+- fix random selection for host on different network.
+- make redhat init script more lsb compliant.
+- don't hold lock for simple mounts.
+- fix remount locking.
+- fix wildcard map entry match.
+- fix parse_sun() module init.
+- dont check null cache on expire.
+- fix null cache race.
+- fix cache_init() on source re-read.
+- fix mapent becomes negative during lookup.
+- check each dc server individually.
+- fix negative cache included map lookup.
+- remove state machine timed wait.
+
 * Mon May 3 2010 Ian Kent <ikent at redhat.com> - 1:5.0.5-25.fc13
 - fix included map read fail handling again (bz540594).
 



More information about the scm-commits mailing list