rpms/autofs/F-9 autofs-5.0.3-allow-dir-create-on-nfs-root.patch, NONE, 1.1 autofs-5.0.3-check-direct-path-len.patch, NONE, 1.1 autofs-5.0.3-dont-abuse-ap-ghost-field.patch, NONE, 1.1 autofs-5.0.3-fix-couple-of-memory-leaks.patch, NONE, 1.1 autofs-5.0.3-fix-get-user-info-check.patch, NONE, 1.1 autofs-5.0.3-lookup-next-soucre-stale-entry.patch, NONE, 1.1 autofs-5.0.3-mount-thread-create-cond-handling-fix.patch, NONE, 1.1 autofs-5.0.3-remove-redundant-dns-name-lookups.patch, NONE, 1.1 autofs.spec, 1.242, 1.243

Ian Kent (iankent) fedora-extras-commits at redhat.com
Mon Jun 30 05:38:57 UTC 2008


Author: iankent

Update of /cvs/pkgs/rpms/autofs/F-9
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv14031

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.3-allow-dir-create-on-nfs-root.patch 
	autofs-5.0.3-check-direct-path-len.patch 
	autofs-5.0.3-dont-abuse-ap-ghost-field.patch 
	autofs-5.0.3-fix-couple-of-memory-leaks.patch 
	autofs-5.0.3-fix-get-user-info-check.patch 
	autofs-5.0.3-lookup-next-soucre-stale-entry.patch 
	autofs-5.0.3-mount-thread-create-cond-handling-fix.patch 
	autofs-5.0.3-remove-redundant-dns-name-lookups.patch 
Log Message:
* Mon Jun 30 2008 Ian Kent <ikent at redhat.com> - 5.0.3-17
- mount thread create condition handling fix.
- allow directory create on NFS root.
- check direct mount path length.
- fix incorrect in check in get user info.
- fix a couple of memory leaks.


autofs-5.0.3-allow-dir-create-on-nfs-root.patch:

--- NEW FILE autofs-5.0.3-allow-dir-create-on-nfs-root.patch ---
autofs-5.0.3 - allow directory create on NFS root

From: Matthias Koenig <mkoenig at suse.de>

autofs will not create the autofs mountpoint path if the filesystem is
not a locally mounted filesystem (e.g. a NFS mounted filesystem).

contained_in_local_fs() returns false in this case. This is intentional
but breaks clients that have an NFS root filesystem. In this case we
shouldn't impose this restriction.
---

 CHANGELOG    |    1 +
 lib/mounts.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index f7aa839..2553f26 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@
 - check for map key in (possible) alternate map sources when doing lookup.
 - eliminate redundant DNS name lookups.
 - additional fix incorrect pthreads condition handling for mount requests.
+- allow mount point directory creation for clients with an NFS root.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/lib/mounts.c b/lib/mounts.c
index 425a65a..b987fbb 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -363,7 +363,13 @@ int contained_in_local_fs(const char *path)
 		if (!strncmp(path, this->path, len)) {
 			if (len > 1 && pathlen > len && path[len] != '/')
 				continue;
-			else if (this->fs_name[0] == '/') {
+			else if (len == 1 && this->path[0] == '/') {
+				/*
+				 * always return true on rootfs, we don't
+				 * want to break diskless clients.
+				 */
+				ret = 1;
+			} else if (this->fs_name[0] == '/') {
 				if (strlen(this->fs_name) > 1) {
 					if (this->fs_name[1] != '/')
 						ret = 1;

autofs-5.0.3-check-direct-path-len.patch:

--- NEW FILE autofs-5.0.3-check-direct-path-len.patch ---
autofs-5.0.3 - check direct mount path length

From: Ian Kent <raven at themaw.net>

The length of the path corresponding to a direct mount can't be
checked in the kernel so we need to check it will fit into the
request structire before going ahead with the mount. The name
field of the request structure is also to short and so is increased
to PATH_MAX.
---

 CHANGELOG           |    1 +
 daemon/direct.c     |   15 +++++++++++++--
 include/automount.h |    2 +-
 3 files changed, 15 insertions(+), 3 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 2553f26..82b080c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
 - eliminate redundant DNS name lookups.
 - additional fix incorrect pthreads condition handling for mount requests.
 - allow mount point directory creation for clients with an NFS root.
+- fix direct mount path length not being checked.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 768fbf9..98590ec 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1411,7 +1411,7 @@ static void *do_mount_direct(void *arg)
 	}
 
 cont:
-	status = lookup_nss_mount(ap, NULL, mt.name, strlen(mt.name));
+	status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
 	/*
 	 * Direct mounts are always a single mount. If it fails there's
 	 * nothing to undo so just complain
@@ -1454,7 +1454,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 	struct pending_args *mt;
 	char buf[MAX_ERR_BUF];
 	int status = 0;
-	int ioctlfd, cl_flags, state;
+	int ioctlfd, len, cl_flags, state;
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
 
@@ -1525,6 +1525,16 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		return 1;
 	}
 
+	len = strlen(me->key);
+	if (len >= PATH_MAX) {
+		error(ap->logopt, "direct mount path too long %s", me->key);
+		send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
+		close(ioctlfd);
+		cache_unlock(mc);
+		pthread_setcancelstate(state, NULL);
+		return 1;
+	}
+
 	mt = malloc(sizeof(struct pending_args));
 	if (!mt) {
 		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
@@ -1553,6 +1563,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 	mt->ioctlfd = ioctlfd;
 	mt->mc = mc;
 	strcpy(mt->name, me->key);
+	mt->len = len;
 	mt->dev = me->dev;
 	mt->type = NFY_MOUNT;
 	mt->uid = pkt->uid;
diff --git a/include/automount.h b/include/automount.h
index d59be77..72e2457 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -409,7 +409,7 @@ struct pending_args {
 	int type;			/* Type of packet */
 	int ioctlfd;			/* Mount ioctl fd */
 	struct mapent_cache *mc;	/* Cache Containing entry */
-	char name[KEY_MAX_LEN];		/* Name field of the request */
+	char name[PATH_MAX];		/* Name field of the request */
 	dev_t dev;			/* device number of mount */
 	unsigned int len;		/* Name field len */
 	uid_t uid;			/* uid of requestor */

autofs-5.0.3-dont-abuse-ap-ghost-field.patch:

--- NEW FILE autofs-5.0.3-dont-abuse-ap-ghost-field.patch ---
autofs-5.0.3 - don't abuse the ap->ghost field on NFS mount

From: Ian Kent <raven at themaw.net>

Using the ap->ghost field in the autofs mount point struct, to prevent
the mount point directory from being removed, when attempting a bind
mount when an NFS mount is local may lead to incorrectly reading and
ghosting the map. This can happen if a mount request comes in during
a map re-read when the autofs map doesn't have the browse option set.
This patch corrects that by using the existence check in the bind mount
module instead of the hack of changing the struct field.
---

 modules/mount_bind.c |    2 +-
 modules/mount_nfs.c  |   11 -----------
 2 files changed, 1 insertions(+), 12 deletions(-)


diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index ef973e1..e4a04d0 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -144,7 +144,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 			if (ap->type != LKP_INDIRECT)
 				return 1;
 
-			if ((!ap->ghost && name_len) || !existed)
+			if ((!ap->ghost && name_len) && !existed)
 				rmdir_path(ap, fullpath, ap->dev);
 
 			return err;
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index 1855ea9..d7f42a7 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -62,7 +62,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 {
 	char *fullpath, buf[MAX_ERR_BUF];
 	struct host *this, *hosts = NULL;
-	unsigned int save_ghost = ap->ghost;
 	unsigned int vers;
 	char *nfsoptions = NULL;
 	int len, rlen, status, err, existed = 1;
@@ -186,13 +185,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 	if (!status)
 		existed = 0;
 
-	/*
-	 * We need to stop the bind mount module from removing the
-	 * mount point directory if a bind attempt fails so abuse
-	 * the ap->ghost field for this.
-	 */
-	ap->ghost = 1;
-
 	this = hosts;
 	while (this) {
 		char *loc, *port_opt = NULL;
@@ -229,7 +221,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 			/* Success - we're done */
 			if (!err) {
 				free_host_list(&hosts);
-				ap->ghost = save_ghost;
 				return 0;
 			}
 
@@ -271,7 +262,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 			info(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath);
 			free(loc);
 			free_host_list(&hosts);
-			ap->ghost = save_ghost;
 			return 0;
 		}
 
@@ -281,7 +271,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
 
 forced_fail:
 	free_host_list(&hosts);
-	ap->ghost = save_ghost;
 
 	/* If we get here we've failed to complete the mount */
 

autofs-5.0.3-fix-couple-of-memory-leaks.patch:

--- NEW FILE autofs-5.0.3-fix-couple-of-memory-leaks.patch ---
autofs-5.0.3 - fix a couple of memory leaks

From: Ian Kent <raven at themaw.net>


---

 CHANGELOG           |    2 ++
 daemon/lookup.c     |    5 ++++-
 modules/parse_sun.c |   14 ++++++++++----
 3 files changed, 16 insertions(+), 5 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 82b080c..5901c75 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,8 @@
 - additional fix incorrect pthreads condition handling for mount requests.
 - allow mount point directory creation for clients with an NFS root.
 - fix direct mount path length not being checked.
+- fix incorrect if check in get user info.
+- fix couple of memory leaks.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/daemon/lookup.c b/daemon/lookup.c
index eac6053..29a1491 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -996,8 +996,11 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
 
 			key = strdup(me->key);
 			me = cache_enumerate(mc, me);
-			if (!key || *key == '*')
+			if (!key || *key == '*') {
+				if (key)
+					free(key);
 				continue;
+			}
 
 			path = make_fullpath(ap->path, key);
 			if (!path) {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 4241f16..d839694 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -462,11 +462,17 @@ static char *concat_options(char *left, char *right)
 	char buf[MAX_ERR_BUF];
 	char *ret;
 
-	if (left == NULL || *left == '\0')
-		return strdup(right);
+	if (left == NULL || *left == '\0') {
+		ret = strdup(right);
+		free(right);
+		return ret;
+	}
 
-	if (right == NULL || *right == '\0')
-		return strdup(left);
+	if (right == NULL || *right == '\0') {
+		ret = strdup(left);
+		free(left);
+		return ret;
+	}
 
 	ret = malloc(strlen(left) + strlen(right) + 2);
 

autofs-5.0.3-fix-get-user-info-check.patch:

--- NEW FILE autofs-5.0.3-fix-get-user-info-check.patch ---
autofs-5.0.3 - fix incorrect if check in get user info

From: Ian Kent <raven at themaw.net>

Fix an if statement checking the wrong value in the get user info code.
---

 daemon/direct.c   |    2 +-
 daemon/indirect.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/daemon/direct.c b/daemon/direct.c
index 98590ec..072ef97 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -1337,7 +1337,7 @@ static void *do_mount_direct(void *arg)
 	}
 
 	tsv->home = strdup(pw.pw_dir);
-	if (!tsv->user) {
+	if (!tsv->home) {
 		error(ap->logopt, "failed to malloc buffer for home");
 		free(pw_tmp);
 		free(tsv->user);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 9f22ec9..ccdd8bf 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -768,7 +768,7 @@ static void *do_mount_indirect(void *arg)
 	}
 
 	tsv->home = strdup(pw.pw_dir);
-	if (!tsv->user) {
+	if (!tsv->home) {
 		error(ap->logopt, "failed to malloc buffer for home");
 		free(pw_tmp);
 		free(tsv->user);

autofs-5.0.3-lookup-next-soucre-stale-entry.patch:

--- NEW FILE autofs-5.0.3-lookup-next-soucre-stale-entry.patch ---
autofs-5.0.3 - multi-map doesn't pickup NIS updates automatically

From: Ian Kent <raven at themaw.net>

In a multi-map configuration, autofs doesn't pick up NIS updates
automatically. This is caused by the lookup not checking alternate
sources for the given key (or wildcard) when doing a key lookup.
---

 CHANGELOG                |    1 +
 lib/cache.c              |    2 ++
 modules/lookup_file.c    |   11 ++++++++---
 modules/lookup_ldap.c    |   11 ++++++++---
 modules/lookup_nisplus.c |   11 ++++++++---
 modules/lookup_yp.c      |   11 ++++++++---
 6 files changed, 35 insertions(+), 12 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 268fca6..3ed84d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
 - fix incorrect pthreads condition handling for mount requests.
 - add check for exports automatically mounted by NFS kernel client.
 - update nsswitch parser to ignore nsswitch sources that aren't supported.
+- check for map key in (possible) alternate map sources when doing lookup.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/lib/cache.c b/lib/cache.c
index 55586a3..d5abab0 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -700,6 +700,8 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
 	int ret = CHE_OK;
 
 	me = cache_lookup(mc, key);
+	while (me && me->source != ms)
+		me = cache_lookup_key_next(me);
 	if (!me || (*me->key == '*' && *key != '*')) {
 		ret = cache_add(mc, ms, key, mapent, age);
 		if (!ret) {
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 466690a..894f6fd 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1116,9 +1116,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		mapent_len = strlen(me->mapent);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index ded26f7..5cc2148 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2596,9 +2596,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 628ffcf..3c19fd3 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -530,9 +530,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 0fc84f8..14f981c 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -636,9 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);

autofs-5.0.3-mount-thread-create-cond-handling-fix.patch:

--- NEW FILE autofs-5.0.3-mount-thread-create-cond-handling-fix.patch ---
autofs-5.0.3 - mount thread create condition handling fix

From: Ian Kent <raven at themaw.net>

Make the mount thread creation condition mutex specific to the
thread being created.
---

 CHANGELOG         |    1 +
 daemon/direct.c   |   31 +++++++++++++++++++++++--------
 daemon/indirect.c |   31 +++++++++++++++++++++++--------
 3 files changed, 47 insertions(+), 16 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 995daea..f7aa839 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
 - update nsswitch parser to ignore nsswitch sources that aren't supported.
 - check for map key in (possible) alternate map sources when doing lookup.
 - eliminate redundant DNS name lookups.
+- additional fix incorrect pthreads condition handling for mount requests.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/daemon/direct.c b/daemon/direct.c
index 86c817c..768fbf9 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -50,7 +50,6 @@ pthread_key_t key_mnt_direct_params;
 pthread_key_t key_mnt_offset_params;
 pthread_once_t key_mnt_params_once = PTHREAD_ONCE_INIT;
 
-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void key_mnt_params_destroy(void *arg)
@@ -1218,9 +1217,18 @@ static void mount_send_fail(void *arg)
 	close(mt->ioctlfd);
 }
 
+static void pending_mutex_destroy(void *arg)
+{
+	struct pending_args *mt = (struct pending_args *) arg;
+	int status = pthread_mutex_destroy(&mt->mutex);
+	if (status)
+		fatal(status);
+}
+
 static void mount_mutex_unlock(void *arg)
 {
-	int status = pthread_mutex_unlock(&ma_mutex);
+	struct pending_args *mt = (struct pending_args *) arg;
+	int status = pthread_mutex_unlock(&mt->mutex);
 	if (status)
 		fatal(status);
 }
@@ -1243,7 +1251,7 @@ static void *do_mount_direct(void *arg)
 
 	args = (struct pending_args *) arg;
 
-	status = pthread_mutex_lock(&ma_mutex);
+	status = pthread_mutex_lock(&args->mutex);
 	if (status)
 		fatal(status);
 
@@ -1256,7 +1264,7 @@ static void *do_mount_direct(void *arg)
 	if (status)
 		fatal(status);
 
-	mount_mutex_unlock(NULL);
+	mount_mutex_unlock(args);
 
 	pthread_cleanup_push(mount_send_fail, &mt);
 
@@ -1533,7 +1541,11 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&ma_mutex);
+	status = pthread_mutex_init(&mt->mutex, NULL);
+	if (status)
+		fatal(status);
+
+	status = pthread_mutex_lock(&mt->mutex);
 	if (status)
 		fatal(status);
 
@@ -1553,8 +1565,9 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 		send_fail(ap->logopt, ioctlfd, pkt->wait_queue_token);
 		close(ioctlfd);
 		cache_unlock(mc);
-		mount_mutex_unlock(NULL);
+		mount_mutex_unlock(mt);
 		pending_cond_destroy(mt);
+		pending_mutex_destroy(mt);
 		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
@@ -1562,13 +1575,14 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 
 	cache_unlock(mc);
 	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_mutex_destroy, mt);
 	pthread_cleanup_push(pending_cond_destroy, mt);
-	pthread_cleanup_push(mount_mutex_unlock, NULL);
+	pthread_cleanup_push(mount_mutex_unlock, mt);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &ma_mutex);
+		status = pthread_cond_wait(&mt->cond, &mt->mutex);
 		if (status)
 			fatal(status);
 	}
@@ -1576,6 +1590,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
 	pthread_cleanup_pop(1);
 	pthread_cleanup_pop(1);
 	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
 
 	return 0;
 }
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 11865b3..9f22ec9 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -40,7 +40,6 @@
 
 extern pthread_attr_t thread_attr;
 
-static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static int unlink_mount_tree(struct autofs_point *ap, struct mnt_list *mnts)
@@ -651,9 +650,18 @@ static void mount_send_fail(void *arg)
 	send_fail(mt->ap->logopt, mt->ap->ioctlfd, mt->wait_queue_token);
 }
 
+static void pending_mutex_destroy(void *arg)
+{
+	struct pending_args *mt = (struct pending_args *) arg;
+	int status = pthread_mutex_destroy(&mt->mutex);
+	if (status)
+		fatal(status);
+}
+
 static void mount_mutex_unlock(void *arg)
 {
-	int status = pthread_mutex_unlock(&ma_mutex);
+	struct pending_args *mt = (struct pending_args *) arg;
+	int status = pthread_mutex_unlock(&mt->mutex);
 	if (status)
 		fatal(status);
 }
@@ -676,7 +684,7 @@ static void *do_mount_indirect(void *arg)
 
 	args = (struct pending_args *) arg;
 
-	status = pthread_mutex_lock(&ma_mutex);
+	status = pthread_mutex_lock(&args->mutex);
 	if (status)
 		fatal(status);
 
@@ -689,7 +697,7 @@ static void *do_mount_indirect(void *arg)
 	if (status)
 		fatal(status);
 
-	mount_mutex_unlock(NULL);
+	mount_mutex_unlock(args);
 
 	pthread_cleanup_push(mount_send_fail, &mt);
 
@@ -884,7 +892,11 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 	if (status)
 		fatal(status);
 
-	status = pthread_mutex_lock(&ma_mutex);
+	status = pthread_mutex_init(&mt->mutex, NULL);
+	if (status)
+		fatal(status);
+
+	status = pthread_mutex_lock(&mt->mutex);
 	if (status)
 		fatal(status);
 
@@ -901,21 +913,23 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 	if (status) {
 		error(ap->logopt, "expire thread create failed");
 		send_fail(ap->logopt, ap->ioctlfd, pkt->wait_queue_token);
-		mount_mutex_unlock(NULL);
+		mount_mutex_unlock(mt);
 		pending_cond_destroy(mt);
+		pending_mutex_destroy(mt);
 		free_pending_args(mt);
 		pthread_setcancelstate(state, NULL);
 		return 1;
 	}
 
 	pthread_cleanup_push(free_pending_args, mt);
+	pthread_cleanup_push(pending_mutex_destroy, mt);
 	pthread_cleanup_push(pending_cond_destroy, mt);
-	pthread_cleanup_push(mount_mutex_unlock, NULL);
+	pthread_cleanup_push(mount_mutex_unlock, mt);
 	pthread_setcancelstate(state, NULL);
 
 	mt->signaled = 0;
 	while (!mt->signaled) {
-		status = pthread_cond_wait(&mt->cond, &ma_mutex);
+		status = pthread_cond_wait(&mt->cond, &mt->mutex);
 		if (status)
 			fatal(status);
 	}
@@ -923,6 +937,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
 	pthread_cleanup_pop(1);
 	pthread_cleanup_pop(1);
 	pthread_cleanup_pop(1);
+	pthread_cleanup_pop(1);
 
 	return 0;
 }

autofs-5.0.3-remove-redundant-dns-name-lookups.patch:

--- NEW FILE autofs-5.0.3-remove-redundant-dns-name-lookups.patch ---
autofs-5.0.3 - eliminate redundant DNS name lookups

From: Ian Kent <raven at themaw.net>

When autofs tries to lookup a DNS host name where one or more DNS
servers aren't available the mount can take a long time. This is
caused by autofs doing the name lookups more often than it needs
to. This patch removes a number of these redundant name lookups.
---

 CHANGELOG            |    1 +
 include/replicated.h |    1 +
 include/rpc_subs.h   |    4 +++-
 lib/rpc_subs.c       |   22 ++++++++++++++++++++--
 modules/replicated.c |   25 +++++++++++++++++++------
 5 files changed, 44 insertions(+), 9 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 3ed84d3..995daea 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@
 - add check for exports automatically mounted by NFS kernel client.
 - update nsswitch parser to ignore nsswitch sources that aren't supported.
 - check for map key in (possible) alternate map sources when doing lookup.
+- eliminate redundant DNS name lookups.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/include/replicated.h b/include/replicated.h
index 672f853..88cd08a 100644
--- a/include/replicated.h
+++ b/include/replicated.h
@@ -52,6 +52,7 @@
 struct host {
 	char *name;
 	char *addr;
+	size_t addr_len;
 	char *path;
 	unsigned int version;
 	unsigned int proximity;
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index 3292e01..e20a89d 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -46,6 +46,8 @@
 
 struct conn_info {
 	const char *host;
+	const char *addr;
+	size_t addr_len;
 	unsigned short port;
 	unsigned long program;
 	unsigned long version;
@@ -61,7 +63,7 @@ int rpc_udp_getclient(struct conn_info *, unsigned int, unsigned int);
 void rpc_destroy_udp_client(struct conn_info *);
 int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int);
 void rpc_destroy_tcp_client(struct conn_info *);
-int rpc_portmap_getclient(struct conn_info *, const char *, const char *, unsigned int);
+int rpc_portmap_getclient(struct conn_info *, const char *, const char *, size_t, const char *, unsigned int);
 unsigned short rpc_portmap_getport(struct conn_info *, struct pmap *);
 int rpc_ping_proto(struct conn_info *);
 int rpc_ping(const char *, long, long, unsigned int);
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 5797639..6be86c6 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -86,6 +86,11 @@ static CLIENT *create_udp_client(struct conn_info *info)
 	memset(&raddr, 0, sizeof(raddr));
 
 	raddr.sin_family = AF_INET;
+	if (info->addr) {
+		memcpy(&raddr.sin_addr.s_addr, info->addr, info->addr_len);
+		goto got_addr;
+	}
+
 	if (inet_aton(info->host, &raddr.sin_addr))
 		goto got_addr;
 
@@ -295,6 +300,11 @@ static CLIENT *create_tcp_client(struct conn_info *info)
 	memset(&addr, 0, sizeof(addr));
 
 	addr.sin_family = AF_INET;
+	if (info->addr) {
+		memcpy(&addr.sin_addr.s_addr, info->addr, info->addr_len);
+		goto got_addr;
+	}
+
 	if (inet_aton(info->host, &addr.sin_addr))
 		goto got_addr;
 
@@ -407,8 +417,8 @@ void rpc_destroy_tcp_client(struct conn_info *info)
 }
 
 int rpc_portmap_getclient(struct conn_info *info,
-			  const char *host, const char *proto,
-			  unsigned int option)
+			  const char *host, const char *addr, size_t addr_len,
+			  const char *proto, unsigned int option)
 {
 	struct protoent *pe_proto;
 	CLIENT *client;
@@ -418,6 +428,8 @@ int rpc_portmap_getclient(struct conn_info *info,
 		return 0;
 
 	info->host = host;
+	info->addr = addr;
+	info->addr_len = addr_len;
 	info->program = PMAPPROG;
 	info->port = PMAPPORT;
 	info->version = PMAPVERS;
@@ -462,6 +474,8 @@ unsigned short rpc_portmap_getport(struct conn_info *info, struct pmap *parms)
 		client = info->client;
 	else {
 		pmap_info.host = info->host;
+		pmap_info.addr = info->addr;
+		pmap_info.addr_len = info->addr_len;
 		pmap_info.port = PMAPPORT;
 		pmap_info.program = PMAPPROG;
 		pmap_info.version = PMAPVERS;
@@ -589,6 +603,8 @@ static unsigned int __rpc_ping(const char *host,
 	struct pmap parms;
 
 	info.host = host;
+	info.addr = NULL;
+	info.addr_len = 0;
 	info.program = NFS_PROGRAM;
 	info.version = version;
 	info.send_sz = 0;
@@ -769,6 +785,8 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in
 	int status;
 
 	info.host = host;
+	info.addr = NULL;
+	info.addr_len = 0;
 	info.program = MOUNTPROG;
 	info.version = MOUNTVERS;
 	info.send_sz = 0;
diff --git a/modules/replicated.c b/modules/replicated.c
index 90b2925..efbe6b4 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -225,7 +225,9 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
 	return PROXIMITY_OTHER;
 }
 
-static struct host *new_host(const char *name, const char *addr, unsigned int proximity, unsigned int weight)
+static struct host *new_host(const char *name,
+			     const char *addr, size_t addr_len,
+			     unsigned int proximity, unsigned int weight)
 {
 	struct host *new;
 	char *tmp1, *tmp2;
@@ -237,11 +239,12 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr
 	if (!tmp1)
 		return NULL;
 
-	tmp2 = strdup(addr);
+	tmp2 = malloc(addr_len);
 	if (!tmp2) {
 		free(tmp1);
 		return NULL;
 	}
+	memcpy(tmp2, addr, addr_len);
 
 	new = malloc(sizeof(struct host));
 	if (!new) {
@@ -253,6 +256,7 @@ static struct host *new_host(const char *name, const char *addr, unsigned int pr
 	memset(new, 0, sizeof(struct host));
 
 	new->name = tmp1;
+	new->addr_len = addr_len;
 	new->addr = tmp2;
 	new->proximity = proximity;
 	new->weight = weight;
@@ -437,7 +441,8 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host,
 v3_ver:
 	if (!have_port_opt) {
 		status = rpc_portmap_getclient(pm_info,
-				 host->name, proto, RPC_CLOSE_DEFAULT);
+				host->name, host->addr, host->addr_len,
+				proto, RPC_CLOSE_DEFAULT);
 		if (!status)
 			goto done_ver;
 	}
@@ -551,6 +556,8 @@ static int get_vers_and_cost(unsigned logopt, struct host *host,
 		timeout = RPC_TIMEOUT * 8;
 
 	rpc_info.host = host->name;
+	rpc_info.addr = host->addr;
+	rpc_info.addr_len = host->addr_len;
 	rpc_info.program = NFS_PROGRAM;
 	rpc_info.timeout.tv_sec = timeout;
 	rpc_info.close_option = RPC_CLOSE_DEFAULT;
@@ -606,6 +613,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
 		timeout = RPC_TIMEOUT * 8;
 
 	rpc_info.host = host->name;
+	rpc_info.addr = host->addr;
+	rpc_info.addr_len = host->addr_len;
 	rpc_info.program = NFS_PROGRAM;
 	rpc_info.timeout.tv_sec = timeout;
 	rpc_info.close_option = RPC_CLOSE_DEFAULT;
@@ -652,7 +661,8 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host,
 			return 0;
 	} else {
 		int ret = rpc_portmap_getclient(&pm_info,
-				 host->name, proto, RPC_CLOSE_DEFAULT);
+				host->name, host->addr, host->addr_len,
+				proto, RPC_CLOSE_DEFAULT);
 		if (!ret)
 			return 0;
 
@@ -868,7 +878,7 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei
 		if (prx == PROXIMITY_ERROR)
 			return 0;
 
-		if (!(new = new_host(host, thost, prx, weight)))
+		if (!(new = new_host(host, thost, sizeof(saddr.sin_addr), prx, weight)))
 			return 0;
 
 		if (!add_host(list, new))
@@ -891,11 +901,14 @@ static int add_host_addrs(struct host **list, const char *host, unsigned int wei
 	}
 
 	for (haddr = phe->h_addr_list; *haddr; haddr++) {
+		struct in_addr tt;
+
 		prx = get_proximity(*haddr, phe->h_length);
 		if (prx == PROXIMITY_ERROR)
 			return 0;
 
-		if (!(new = new_host(host, *haddr, prx, weight)))
+		memcpy(&tt, *haddr, sizeof(struct in_addr));
+		if (!(new = new_host(host, *haddr, phe->h_length, prx, weight)))
 			return 0;
 
 		if (!add_host(list, new)) {


Index: autofs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/autofs/F-9/autofs.spec,v
retrieving revision 1.242
retrieving revision 1.243
diff -u -r1.242 -r1.243
--- autofs.spec	23 May 2008 03:17:29 -0000	1.242
+++ autofs.spec	30 Jun 2008 05:38:14 -0000	1.243
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 Version: 5.0.3
-Release: 15
+Release: 17
 Epoch: 1
 License: GPL
 Group: System Environment/Daemons
@@ -24,6 +24,11 @@
 Patch12: autofs-5.0.3-mount-thread-create-cond-handling.patch
 Patch13: autofs-5.0.3-check-for-kernel-automount.patch
 Patch14: autofs-5.0.3-nss-source-any.patch
+Patch15: autofs-5.0.3-mount-thread-create-cond-handling-fix.patch
+Patch16: autofs-5.0.3-allow-dir-create-on-nfs-root.patch
+Patch17: autofs-5.0.3-check-direct-path-len.patch
+Patch18: autofs-5.0.3-fix-get-user-info-check.patch
+Patch19: autofs-5.0.3-fix-couple-of-memory-leaks.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
 Conflicts: kernel < 2.6.17
@@ -79,6 +84,11 @@
 %patch12 -p1
 %patch13 -p1
 %patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -131,6 +141,13 @@
 %{_libdir}/autofs/
 
 %changelog
+* Mon Jun 30 2008 Ian Kent <ikent at redhat.com> - 5.0.3-17
+- mount thread create condition handling fix.
+- allow directory create on NFS root.
+- check direct mount path length.
+- fix incorrect in check in get user info.
+- fix a couple of memory leaks.
+
 * Fri May 23 2008 Ian Kent <ikent at redhat.com> - 5.0.3-15
 - check for nohide mounts (bz 442618).
 - ignore nsswitch sources that aren't supported (bz 445880).




More information about the fedora-extras-commits mailing list