[autofs] - sync up with upstream patches.

Ian Kent iankent at fedoraproject.org
Tue Jul 3 03:52:17 UTC 2012


commit cc58c12fcac0c08bb1183d20587ce08af8d76a2d
Author: Ian Kent <ikent at redhat.com>
Date:   Tue Jul 3 11:51:28 2012 +0800

    - sync up with upstream patches.

 ...add-function-to-delete-offset-cache-entry.patch |   84 +++
 ....0.6-add-hup-signal-handling-to-hosts-map.patch |  498 ++++++++++++++++++
 ...llow-update-of-multi-mount-offset-entries.patch |  104 ++++
 ...eck-if-mtab-is-a-link-to-proc-self-mounts.patch |   70 +++
 ...6-dont-retry-ldap-connect-if-not-required.patch |   65 +++
 ...uplicate-parent-options-for-included-maps.patch |  158 ++++++
 ...s-5.0.6-fix-device-ioctl-alloc-path-check.patch |   37 ++
 ...-fix-fix-LDAP-result-leaks-on-error-paths.patch |   33 ++
 ...kernel-verion-check-of-version-components.patch |   94 ++++
 autofs-5.0.6-fix-nfs4-contacts-portmap.patch       |   52 ++
 ...-fix-offset-mount-point-directory-removal.patch |  167 ++++++
 autofs-5.0.6-fix-remount-deadlock.patch            |  136 +++++
 autofs-5.0.6-fix-remount-of-multi-mount.patch      |   49 ++
 autofs-5.0.6-fix-sss-map-age.patch                 |   34 ++
 ...-fix-umount-recovery-of-busy-direct-mount.patch |   66 +++
 ....0.6-make-autofs-wait-longer-for-shutdown.patch |   78 +++
 autofs-5.0.6-move-timeout-to-map_source.patch      |  529 ++++++++++++++++++++
 autofs-5.0.6-refactor-lookup-hosts-module.patch    |  248 +++++++++
 ....0.6-remove-cache-update-from-parse_mount.patch |   47 ++
 ...move-move-mount-code-and-configure-option.patch |  421 ++++++++++++++++
 ....6-report-map-not-read-when-debug-logging.patch |   99 ++++
 ...te-timeout-function-to-not-return-timeout.patch |  171 +++++++
 22 files changed, 3240 insertions(+), 0 deletions(-)
---
diff --git a/autofs-5.0.6-add-function-to-delete-offset-cache-entry.patch b/autofs-5.0.6-add-function-to-delete-offset-cache-entry.patch
new file mode 100644
index 0000000..977bb11
--- /dev/null
+++ b/autofs-5.0.6-add-function-to-delete-offset-cache-entry.patch
@@ -0,0 +1,84 @@
+autofs-5.0.6 - add function to delete offset cache entry
+
+From: Ian Kent <ikent at redhat.com>
+
+Currently only the entire expanded list of offset cache entries may be
+removed from the cache. In order to be able to update already expanded
+multi map offset entries we need to be able to delete them.
+---
+
+ include/automount.h |    1 +
+ lib/cache.c         |   47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+), 0 deletions(-)
+
+
+diff --git a/include/automount.h b/include/automount.h
+index e1246e3..40c1975 100644
+--- a/include/automount.h
++++ b/include/automount.h
+@@ -192,6 +192,7 @@ int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key,
+ int cache_set_parents(struct mapent *mm);
+ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
+ int cache_delete(struct mapent_cache *mc, const char *key);
++int cache_delete_offset(struct mapent_cache *mc, const char *key);
+ void cache_multi_readlock(struct mapent *me);
+ void cache_multi_writelock(struct mapent *me);
+ void cache_multi_unlock(struct mapent *me);
+diff --git a/lib/cache.c b/lib/cache.c
+index 3464e7d..1489273 100644
+--- a/lib/cache.c
++++ b/lib/cache.c
+@@ -771,6 +771,53 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
+ 	return ret;
+ }
+ 
++/* cache_multi_lock of the multi mount owner must be held by caller */
++int cache_delete_offset(struct mapent_cache *mc, const char *key)
++{
++	u_int32_t hashval = hash(key, mc->size);
++	struct mapent *me = NULL, *pred;
++	int status;
++
++	me = mc->hash[hashval];
++	if (!me)
++		return CHE_FAIL;
++
++	if (strcmp(key, me->key) == 0) {
++		if (me->multi && me->multi == me)
++			return CHE_FAIL;
++		mc->hash[hashval] = me->next;
++		goto delete;
++	}
++
++	while (me->next != NULL) {
++		pred = me;
++		me = me->next;
++		if (strcmp(key, me->key) == 0) {
++			if (me->multi && me->multi == me)
++				return CHE_FAIL;
++			pred->next = me->next;
++			goto delete;
++		}
++	}
++
++	return CHE_FAIL;
++
++delete:
++	status = pthread_rwlock_destroy(&me->multi_rwlock);
++	if (status)
++		fatal(status);
++	list_del(&me->multi_list);
++	ino_index_lock(mc);
++	list_del(&me->ino_index);
++	ino_index_unlock(mc);
++	free(me->key);
++	if (me->mapent)
++		free(me->mapent);
++	free(me);
++
++	return CHE_OK;
++}
++
+ /* cache must be write locked by caller */
+ int cache_delete(struct mapent_cache *mc, const char *key)
+ {
diff --git a/autofs-5.0.6-add-hup-signal-handling-to-hosts-map.patch b/autofs-5.0.6-add-hup-signal-handling-to-hosts-map.patch
new file mode 100644
index 0000000..491612c
--- /dev/null
+++ b/autofs-5.0.6-add-hup-signal-handling-to-hosts-map.patch
@@ -0,0 +1,498 @@
+autofs-5.0.6 - add hup signal handling to hosts map
+
+From: Ian Kent <ikent at redhat.com>
+
+Add HUP signal handling to the internal hosts lookup module.
+---
+
+ CHANGELOG              |    1 
+ daemon/direct.c        |    4 -
+ include/mounts.h       |    1 
+ lib/mounts.c           |  162 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ man/auto.master.5.in   |    5 +
+ man/autofs.5           |    8 +-
+ modules/lookup_hosts.c |   97 ++++++++++++++++++++++++-----
+ modules/parse_sun.c    |    9 ++
+ 8 files changed, 262 insertions(+), 25 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -57,6 +57,7 @@
+ - fix offset mount point directory removal.
+ - fix remount of multi mount.
+ - fix devce ioctl alloc path check.
++- add hup signal handling to hosts map.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/direct.c
++++ autofs-5.0.6/daemon/direct.c
+@@ -654,7 +654,9 @@ int mount_autofs_offset(struct autofs_po
+ 		ret = try_remount(ap, me, t_offset);
+ 		if (ret == 1)
+ 			return MOUNT_OFFSET_OK;
+-		return MOUNT_OFFSET_FAIL;
++		/* Offset mount not found, fall thru and try to mount it */
++		if (!(ret == -1 && errno == ENOENT))
++			return MOUNT_OFFSET_FAIL;
+ 	} else {
+ /*
+ 		if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) {
+--- autofs-5.0.6.orig/include/mounts.h
++++ autofs-5.0.6/include/mounts.h
+@@ -112,5 +112,6 @@ int try_remount(struct autofs_point *, s
+ int umount_ent(struct autofs_point *, const char *);
+ int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
+ int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
++int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
+ 
+ #endif
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -1436,6 +1436,7 @@ static int remount_active_mount(struct a
+ 
+ 	/* Re-reading the map, set timeout and return */
+ 	if (ap->state == ST_READMAP) {
++		debug(ap->logopt, "already mounted, update timeout");
+ 		ops->timeout(ap->logopt, fd, timeout);
+ 		ops->close(ap->logopt, fd);
+ 		return REMOUNT_READ_MAP;
+@@ -1550,7 +1551,9 @@ int try_remount(struct autofs_point *ap,
+ 	 * record that in the mount point struct. Otherwise we're
+ 	 * re-reading the map.
+ 	*/
+-	if (ret == REMOUNT_SUCCESS || ret == REMOUNT_READ_MAP) {
++	if (ret == REMOUNT_READ_MAP)
++		return 1;
++	else if (ret == REMOUNT_SUCCESS) {
+ 		if (fd != -1) {
+ 			if (type == t_indirect)
+ 				ap->ioctlfd = fd;
+@@ -1781,5 +1784,162 @@ int umount_multi_triggers(struct autofs_
+ 	}
+ 
+ 	return left;
++}
++
++int clean_stale_multi_triggers(struct autofs_point *ap,
++			       struct mapent *me, char *top, const char *base)
++{
++	char *root;
++	char mm_top[PATH_MAX + 1];
++	char path[PATH_MAX + 1];
++	char buf[MAX_ERR_BUF];
++	char *offset;
++	struct mapent *oe;
++	struct list_head *mm_root, *pos;
++	const char o_root[] = "/";
++	const char *mm_base;
++	int left, start;
++	time_t age;
++
++	if (top)
++		root = top;
++	else {
++		if (!strchr(me->multi->key, '/'))
++			/* Indirect multi-mount root */
++			/* sprintf okay - if it's mounted, it's
++			 * PATH_MAX or less bytes */
++			sprintf(mm_top, "%s/%s", ap->path, me->multi->key);
++		else
++			strcpy(mm_top, me->multi->key);
++		root = mm_top;
++	}
++
++	left = 0;
++	start = strlen(root);
++
++	mm_root = &me->multi->multi_list;
++
++	if (!base)
++		mm_base = o_root;
++	else
++		mm_base = base;
++
++	pos = NULL;
++	offset = path;
++	age = me->multi->age;
++
++	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
++		char *oe_base;
++		char *key;
++		int ret;
++
++		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
++		/* root offset is a special case */
++		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
++			continue;
++
++		/* Check for and umount stale subtree offsets */
++		oe_base = oe->key + strlen(root);
++		ret = clean_stale_multi_triggers(ap, oe, root, oe_base);
++		left =+ ret;
++		if (ret)
++			continue;
++
++		if (oe->age == age)
++			continue;
++
++		/*
++		 * If an offset that has an active mount has been removed
++		 * from the multi-mount we don't want to attempt to trigger
++		 * mounts for it. Obviously this is because it has been
++		 * removed, but less obvious is the potential strange
++		 * behaviour that can result if we do try and mount it
++		 * again after it's been expired. For example, if an NFS
++		 * file system is no longer exported and is later umounted
++		 * it can be mounted again without any error message but
++		 * shows as an empty directory. That's going to confuse
++		 * people for sure.
++		 *
++		 * If the mount cannot be umounted (the process is now
++		 * using a stale mount) the offset needs to be invalidated
++		 * so no further mounts will be attempted but the offset
++		 * cache entry must remain so expires can continue to
++		 * attempt to umount it. If the mount can be umounted and
++		 * the offset is removed, at least for NFS we will get
++		 * ESTALE errors when attempting list the directory.
++		 */
++		if (oe->ioctlfd != -1 ||
++		    is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
++			if (umount_ent(ap, oe->key)) {
++				debug(ap->logopt,
++				      "offset %s has active mount, invalidate",
++				      oe->key);
++				if (oe->mapent) {
++					free(oe->mapent);
++					oe->mapent = NULL;
++				}
++				left++;
++				continue;
++			}
++		}
++
++		key = strdup(oe->key);
++		if (!key) {
++	                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
++        	        error(ap->logopt, "malloc: %s", estr);
++			left++;
++			continue;
++		}
++
++		debug(ap->logopt, "umount offset %s", oe->key);
++
++		if (umount_autofs_offset(ap, oe)) {
++			warn(ap->logopt, "failed to umount offset %s", key);
++			left++;
++		} else {
++			struct stat st;
++
++			/* Mount point not ours to delete ? */
++			if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) {
++				debug(ap->logopt, "delete offset key %s", key);
++				if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
++					error(ap->logopt,
++					     "failed to delete offset key %s", key);
++				free(key);
++				continue;
++			}
++
++			/*
++			 * An error due to partial directory removal is
++			 * ok so only try and remount the offset if the
++			 * actual mount point still exists.
++			 */
++			ret = rmdir_path(ap, oe->key, ap->dev);
++			if (ret == -1 && !stat(oe->key, &st)) {
++				ret = do_mount_autofs_offset(ap, oe, root, offset);
++				if (ret) {
++					left++;
++					free(key);
++					continue;
++				}
++				/*
++				 * Fall through if the trigger can't be mounted
++				 * again, since there is no offset there can't
++				 * be any mount requests so remove the map
++				 * entry from the cache. There's now a dead
++				 * offset mount, but what else can we do ....
++				 */
++			}
++
++			debug(ap->logopt, "delete offset key %s", key);
++
++			if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
++				error(ap->logopt,
++				     "failed to delete offset key %s", key);
++		}
++		free(key);
++	}
++
++	return left;
+ }
+ 
+--- autofs-5.0.6.orig/man/auto.master.5.in
++++ autofs-5.0.6/man/auto.master.5.in
+@@ -220,7 +220,10 @@ set default log level "none", "verbose"
+ .SH BUILTIN MAP -hosts
+ If "-hosts" is given as the map then accessing a key under the mount point
+ which corresponds to a hostname will allow access to the exports of that
+-host.
++host. The hosts map cannot be dynamically updated and requires a HUP signal
++to be sent to the daemon for it to check hosts for an update. Due to possible
++hierarchic dependencies within a mount tree, it might not be completely
++updated during the HUP signal processing.
+ .P
+ For example, with an entry in the master map of
+ .nh
+--- autofs-5.0.6.orig/man/autofs.5
++++ autofs-5.0.6/man/autofs.5
+@@ -13,10 +13,10 @@ These maps describe how file systems bel
+ map format; if another map format is specified (e.g. \fBhesiod\fP),
+ this documentation does not apply.
+ 
+-Indirect maps can be changed on the fly and the automouter will recognize
+-those changes on the next operation it performs on that map. Direct maps
+-require a HUP signal be sent to the daemon to refresh their contents as does
+-the master map.
++Indirect maps, except for the internal hosts map, can be changed on the fly
++and the automouter will recognize those changes on the next operation it
++performs on that map. Direct maps require a HUP signal be sent to the
++daemon to refresh their contents as does the master map.
+ .SH "FORMAT"
+ This is a description of the text file format.  Other methods of specifying
+ these files may exist.  All empty lines or lines beginning with # are
+--- autofs-5.0.6.orig/modules/lookup_hosts.c
++++ autofs-5.0.6/modules/lookup_hosts.c
+@@ -80,10 +80,11 @@ int lookup_read_master(struct master *ma
+ 
+ static char *get_exports(struct autofs_point *ap, const char *host)
+ {
+-	char *mapent = NULL;
++	char buf[MAX_ERR_BUF];
++	char *mapent;
+ 	exports exp;
+ 
+-	debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
++	debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
+ 
+ 	exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
+ 
+@@ -92,20 +93,20 @@ static char *get_exports(struct autofs_p
+ 		if (mapent) {
+ 			int len = strlen(mapent) + 1;
+ 
+-			len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
++			len += strlen(host) + 2*(strlen(exp->ex_dir) + 2) + 3;
+ 			mapent = realloc(mapent, len);
+ 			if (!mapent) {
+ 				char *estr;
+ 				estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ 				error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ 				rpc_exports_free(exp);
+-				return NSS_STATUS_UNAVAIL;
++				return NULL;
+ 			}
+ 			strcat(mapent, " \"");
+ 			strcat(mapent, exp->ex_dir);
+ 			strcat(mapent, "\"");
+ 		} else {
+-			int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
++			int len = 2*(strlen(exp->ex_dir) + 2) + strlen(host) + 3;
+ 
+ 			mapent = malloc(len);
+ 			if (!mapent) {
+@@ -113,14 +114,14 @@ static char *get_exports(struct autofs_p
+ 				estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ 				error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ 				rpc_exports_free(exp);
+-				return NSS_STATUS_UNAVAIL;
++				return NULL;
+ 			}
+ 			strcpy(mapent, "\"");
+ 			strcat(mapent, exp->ex_dir);
+ 			strcat(mapent, "\"");
+ 		}
+ 		strcat(mapent, " \"");
+-		strcat(mapent, name);
++		strcat(mapent, host);
+ 		strcat(mapent, ":");
+ 		strcat(mapent, exp->ex_dir);
+ 		strcat(mapent, "\"");
+@@ -130,14 +131,14 @@ static char *get_exports(struct autofs_p
+ 	rpc_exports_free(exp);
+ 
+ 	if (!mapent)
+-		error(ap->logopt, "exports lookup failed for %s", name);
++		error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
+ 
+ 	return mapent;
+ }
+ 
+-static int do_parse_mount(struct autofs_point *ap,
++static int do_parse_mount(struct autofs_point *ap, struct map_source *source,
+ 			  const char *name, int name_len, char *mapent,
+-			  void *context)
++			  struct lookup_context *ctxt)
+ {
+ 	int ret;
+ 
+@@ -166,8 +167,68 @@ static int do_parse_mount(struct autofs_
+ 	return NSS_STATUS_SUCCESS;
+ }
+ 
++static int update_hosts_mounts(struct autofs_point *ap,
++			       struct map_source *source, time_t age,
++			       struct lookup_context *ctxt)
++{
++	struct mapent_cache *mc;
++	struct mapent *me;
++	char *mapent;
++	int ret;
++
++	mc = source->mc;
++
++	pthread_cleanup_push(cache_lock_cleanup, mc);
++	cache_writelock(mc);
++	me = cache_lookup_first(mc);
++	while (me) {
++		/* Hosts map entry not yet expanded or already expired */
++		if (!me->multi)
++			goto next;
++
++		debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key);
++
++		mapent = get_exports(ap, me->key);
++		if (mapent) {
++			cache_update(mc, source, me->key, mapent, age);
++			free(mapent);
++		}
++next:
++		me = cache_lookup_next(mc, me);
++	}
++	pthread_cleanup_pop(1);
++
++	pthread_cleanup_push(cache_lock_cleanup, mc);
++	cache_readlock(mc);
++	me = cache_lookup_first(mc);
++	while (me) {
++		/*
++		 * Hosts map entry not yet expanded, already expired
++		 * or not the base of the tree
++		 */
++		if (!me->multi || me->multi != me)
++			goto cont;
++
++		debug(ap->logopt, MODPREFIX
++		      "attempt to update exports for exports for %s", me->key);
++
++		master_source_current_wait(ap->entry);
++		ap->entry->current = source;
++		ap->flags |= MOUNT_FLAG_REMOUNT;
++		ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
++					       me->mapent, ctxt->parse->context);
++		ap->flags &= ~MOUNT_FLAG_REMOUNT;
++cont:
++		me = cache_lookup_next(mc, me);
++	}
++	pthread_cleanup_pop(1);
++
++	return NSS_STATUS_SUCCESS;
++}
++
+ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
+ {
++	struct lookup_context *ctxt = (struct lookup_context *) context;
+ 	struct map_source *source;
+ 	struct mapent_cache *mc;
+ 	struct hostent *host;
+@@ -177,18 +238,23 @@ int lookup_read_map(struct autofs_point
+ 	ap->entry->current = NULL;
+ 	master_source_current_signal(ap->entry);
+ 
++	mc = source->mc;
++
++	debug(ap->logopt, MODPREFIX "read hosts map");
++
+ 	/*
+ 	 * If we don't need to create directories then there's no use
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+ 	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
+-		debug(ap->logopt, "map read not needed, so not done");
++		debug(ap->logopt, MODPREFIX
++		      "map not browsable, update existing host entries only");
++		update_hosts_mounts(ap, source, age, ctxt);
++		source->age = age;
+ 		return NSS_STATUS_SUCCESS;
+ 	}
+ 
+-	mc = source->mc;
+-
+ 	status = pthread_mutex_lock(&hostent_mutex);
+ 	if (status) {
+ 		error(ap->logopt, MODPREFIX "failed to lock hostent mutex");
+@@ -209,6 +275,7 @@ int lookup_read_map(struct autofs_point
+ 	if (status)
+ 		error(ap->logopt, MODPREFIX "failed to unlock hostent mutex");
+ 
++	update_hosts_mounts(ap, source, age, ctxt);
+ 	source->age = age;
+ 
+ 	return NSS_STATUS_SUCCESS;
+@@ -220,11 +287,9 @@ int lookup_mount(struct autofs_point *ap
+ 	struct map_source *source;
+ 	struct mapent_cache *mc;
+ 	struct mapent *me;
+-	char buf[MAX_ERR_BUF];
+ 	char *mapent = NULL;
+ 	int mapent_len;
+ 	time_t now = time(NULL);
+-	exports exp;
+ 	int ret;
+ 
+ 	source = ap->entry->current;
+@@ -320,7 +385,7 @@ done:
+ 		cache_unlock(mc);
+ 	}
+ 
+-	ret = do_parse_mount(ap, name, name_len, mapent, ctxt->parse->context);
++	ret = do_parse_mount(ap, source, name, name_len, mapent, ctxt);
+ 
+ 	free(mapent);
+ 
+--- autofs-5.0.6.orig/modules/parse_sun.c
++++ autofs-5.0.6/modules/parse_sun.c
+@@ -1355,7 +1355,7 @@ int parse_mount(struct autofs_point *ap,
+ 	if (check_is_multi(p)) {
+ 		char *m_root = NULL;
+ 		int m_root_len;
+-		time_t age = time(NULL);
++		time_t age;
+ 		int l;
+ 
+ 		/* If name starts with "/" it's a direct mount */
+@@ -1399,6 +1399,8 @@ int parse_mount(struct autofs_point *ap,
+ 			return 1;
+ 		}
+ 
++		age = me->age;
++
+ 		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
+ 		cache_multi_writelock(me);
+ 		/* It's a multi-mount; deal with it */
+@@ -1472,8 +1474,11 @@ int parse_mount(struct autofs_point *ap,
+ 
+ 		/*
+ 		 * We've got the ordered list of multi-mount entries so go
+-		 * through and set the parent entry of each
++		 * through and remove any stale entries if this is the top
++		 * of the multi-mount and set the parent entry of each.
+ 		 */
++		if (me == me->multi)
++			clean_stale_multi_triggers(ap, me, NULL, NULL);
+ 		cache_set_parents(me);
+ 
+ 		rv = mount_subtree(ap, me, name, NULL, options, ctxt);
diff --git a/autofs-5.0.6-allow-update-of-multi-mount-offset-entries.patch b/autofs-5.0.6-allow-update-of-multi-mount-offset-entries.patch
new file mode 100644
index 0000000..99841a1
--- /dev/null
+++ b/autofs-5.0.6-allow-update-of-multi-mount-offset-entries.patch
@@ -0,0 +1,104 @@
+autofs-5.0.6 - allow update of multi mount offset entries
+
+From: Ian Kent <ikent at redhat.com>
+
+Currently multi mount offsets can only be added or all offsets owned by
+an entry deleted at once. In order to be able to update multi mount map
+entries we need to be able to update offset entries of an already expanded
+multi map cache entry.
+---
+
+ include/automount.h |    2 +-
+ lib/cache.c         |    4 ++--
+ modules/parse_sun.c |   20 ++++++++++----------
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+
+diff --git a/include/automount.h b/include/automount.h
+index 40c1975..561fcc2 100644
+--- a/include/automount.h
++++ b/include/automount.h
+@@ -188,7 +188,7 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key);
+ struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head);
+ struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix);
+ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
+-int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
++int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
+ int cache_set_parents(struct mapent *mm);
+ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
+ int cache_delete(struct mapent_cache *mc, const char *key);
+diff --git a/lib/cache.c b/lib/cache.c
+index 1489273..9179ad5 100644
+--- a/lib/cache.c
++++ b/lib/cache.c
+@@ -647,7 +647,7 @@ static void cache_add_ordered_offset(struct mapent *me, struct list_head *head)
+ }
+ 
+ /* cache must be write locked by caller */
+-int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
++int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
+ {
+ 	unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
+ 	struct mapent *me, *owner;
+@@ -659,7 +659,7 @@ int cache_add_offset(struct mapent_cache *mc, const char *mkey, const char *key,
+ 
+ 	me = cache_lookup_distinct(mc, key);
+ 	if (me && me->age == age) {
+-		if (me != owner)
++		if (me->multi != owner)
+ 			return CHE_DUPLICATE;
+ 	}
+ 
+diff --git a/modules/parse_sun.c b/modules/parse_sun.c
+index c4decbc..5be7345 100644
+--- a/modules/parse_sun.c
++++ b/modules/parse_sun.c
+@@ -781,10 +781,10 @@ static int check_is_multi(const char *mapent)
+ }
+ 
+ static int
+-add_offset_entry(struct autofs_point *ap, const char *name,
+-		 const char *m_root, int m_root_len,
+-		 const char *path, const char *myoptions, const char *loc,
+-		 time_t age)
++update_offset_entry(struct autofs_point *ap, const char *name,
++		    const char *m_root, int m_root_len,
++		    const char *path, const char *myoptions, const char *loc,
++		    time_t age)
+ {
+ 	struct map_source *source;
+ 	struct mapent_cache *mc;
+@@ -838,17 +838,17 @@ add_offset_entry(struct autofs_point *ap, const char *name,
+ 	} else
+ 		strcpy(m_mapent, loc);
+ 
+-	ret = cache_add_offset(mc, name, m_key, m_mapent, age);
++	ret = cache_update_offset(mc, name, m_key, m_mapent, age);
+ 	if (ret == CHE_DUPLICATE)
+ 		warn(ap->logopt, MODPREFIX
+ 		     "syntax error or duplicate offset %s -> %s", path, loc);
+ 	else if (ret == CHE_FAIL)
+ 		debug(ap->logopt, MODPREFIX
+-		      "failed to add multi-mount offset %s -> %s", path, m_mapent);
++		      "failed to update multi-mount offset %s -> %s", path, m_mapent);
+ 	else {
+ 		ret = CHE_OK;
+ 		debug(ap->logopt, MODPREFIX
+-		      "added multi-mount offset %s -> %s", path, m_mapent);
++		      "updated multi-mount offset %s -> %s", path, m_mapent);
+ 	}
+ 
+ 	return ret;
+@@ -1448,9 +1448,9 @@ int parse_mount(struct autofs_point *ap, const char *name,
+ 			master_source_current_wait(ap->entry);
+ 			ap->entry->current = source;
+ 
+-			status = add_offset_entry(ap, name,
+-						m_root, m_root_len,
+-						path, myoptions, loc, age);
++			status = update_offset_entry(ap, name,
++						     m_root, m_root_len,
++						     path, myoptions, loc, age);
+ 
+ 			if (status != CHE_OK) {
+ 				warn(ap->logopt, MODPREFIX "error adding multi-mount");
diff --git a/autofs-5.0.6-check-if-mtab-is-a-link-to-proc-self-mounts.patch b/autofs-5.0.6-check-if-mtab-is-a-link-to-proc-self-mounts.patch
new file mode 100644
index 0000000..a8bef3b
--- /dev/null
+++ b/autofs-5.0.6-check-if-mtab-is-a-link-to-proc-self-mounts.patch
@@ -0,0 +1,70 @@
+autofs-5.0.6 - check if /etc/mtab is a link to /proc/self/mounts
+
+From: Leonardo Chiquitto <leonardo.lists at gmail.com>
+
+Check if /etc/mtab is a link to /proc/self/mounts
+
+Some distributions link /etc/mtab to /proc/self/mounts instead
+of /proc/mounts.
+---
+
+ CHANGELOG           |    1 +
+ daemon/spawn.c      |    9 ++++++---
+ include/automount.h |    3 ++-
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -48,6 +48,7 @@
+ - move timeout to map_source (allow per direct map timeout).
+ - fix kernel verion check of version components.
+ - dont retry ldap connect if not required.
++- check if /etc/mtab is a link to /proc/self/mounts.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/spawn.c
++++ autofs-5.0.6/daemon/spawn.c
+@@ -336,7 +336,8 @@ int spawn_mount(unsigned logopt, ...)
+ 	ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ 	if (ret != -1) {
+ 		buf[ret] = '\0';
+-		if (!strcmp(buf, _PROC_MOUNTS)) {
++		if (!strcmp(buf, _PROC_MOUNTS) ||
++		    !strcmp(buf, _PROC_SELF_MOUNTS)) {
+ 			debug(logopt,
+ 			      "mtab link detected, passing -n to mount");
+ 			argc++;
+@@ -467,7 +468,8 @@ int spawn_bind_mount(unsigned logopt, ..
+ 	ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ 	if (ret != -1) {
+ 		buf[ret] = '\0';
+-		if (!strcmp(buf, _PROC_MOUNTS)) {
++		if (!strcmp(buf, _PROC_MOUNTS) ||
++		    !strcmp(buf, _PROC_SELF_MOUNTS)) {
+ 			debug(logopt,
+ 			      "mtab link detected, passing -n to mount");
+ 			argc++;
+@@ -569,7 +571,8 @@ int spawn_umount(unsigned logopt, ...)
+ 	ret = readlink(_PATH_MOUNTED, buf, PATH_MAX);
+ 	if (ret != -1) {
+ 		buf[ret] = '\0';
+-		if (!strcmp(buf, _PROC_MOUNTS)) {
++		if (!strcmp(buf, _PROC_MOUNTS) ||
++		    !strcmp(buf, _PROC_SELF_MOUNTS)) {
+ 			debug(logopt,
+ 			      "mtab link detected, passing -n to mount");
+ 			argc++;
+--- autofs-5.0.6.orig/include/automount.h
++++ autofs-5.0.6/include/automount.h
+@@ -84,7 +84,8 @@ int load_autofs4_module(void);
+ #define MTAB_NOTUPDATED 0x1000			/* mtab succeded but not updated */
+ #define NOT_MOUNTED     0x0100			/* path notmounted */
+ #define MNT_FORCE_FAIL	-1
+-#define _PROC_MOUNTS	"/proc/mounts"
++#define _PROC_MOUNTS		"/proc/mounts"
++#define _PROC_SELF_MOUNTS	"/proc/self/mounts"
+ 
+ /* Constants for lookup modules */
+ 
diff --git a/autofs-5.0.6-dont-retry-ldap-connect-if-not-required.patch b/autofs-5.0.6-dont-retry-ldap-connect-if-not-required.patch
new file mode 100644
index 0000000..a611b83
--- /dev/null
+++ b/autofs-5.0.6-dont-retry-ldap-connect-if-not-required.patch
@@ -0,0 +1,65 @@
+autofs-5.0.6 - dont retry ldap connect if not required
+
+From: Ian Kent <ikent at redhat.com>
+
+When using LDAP and the server is not available autofs retries the
+connection when  it fails in case the SASL credentail has expired.
+But this is done even when not using SASL, so change it check if
+SASL authentication is required.
+---
+
+ CHANGELOG             |    1 +
+ include/lookup_ldap.h |    1 +
+ modules/lookup_ldap.c |    6 +++---
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -47,6 +47,7 @@
+ - update ->timeout() function to not return timeout.
+ - move timeout to map_source (allow per direct map timeout).
+ - fix kernel verion check of version components.
++- dont retry ldap connect if not required.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/include/lookup_ldap.h
++++ autofs-5.0.6/include/lookup_ldap.h
+@@ -104,6 +104,7 @@ struct lookup_context {
+ #define LDAP_AUTH_NOTREQUIRED	0x0001
+ #define LDAP_AUTH_REQUIRED	0x0002
+ #define LDAP_AUTH_AUTODETECT	0x0004
++#define LDAP_NEED_AUTH		(LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)
+ #endif
+ 
+ #define LDAP_AUTH_USESIMPLE	0x0008
+--- autofs-5.0.6.orig/modules/lookup_ldap.c
++++ autofs-5.0.6/modules/lookup_ldap.c
+@@ -511,7 +511,7 @@ static int do_bind(unsigned logopt, LDAP
+ 	debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s",
+ 	      ctxt->auth_required, ctxt->sasl_mech);
+ 
+-	if (ctxt->auth_required & (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT)) {
++	if (ctxt->auth_required & LDAP_NEED_AUTH) {
+ 		rv = autofs_sasl_bind(logopt, ldap, ctxt);
+ 		debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
+ 	} else {
+@@ -731,7 +731,7 @@ static LDAP *do_reconnect(unsigned logop
+ 		ldap = do_connect(logopt, ctxt->server, ctxt);
+ #ifdef WITH_SASL
+ 		/* Dispose of the sasl authentication connection and try again. */
+-		if (!ldap) {
++		if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
+ 			autofs_sasl_dispose(ctxt);
+ 			ldap = connect_to_server(logopt, ctxt->server, ctxt);
+ 		}
+@@ -767,7 +767,7 @@ static LDAP *do_reconnect(unsigned logop
+ 	 * Dispose of the sasl authentication connection and try the
+ 	 * current server again before trying other servers in the list.
+ 	 */
+-	if (!ldap) {
++	if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) {
+ 		autofs_sasl_dispose(ctxt);
+ 		ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt);
+ 	}
diff --git a/autofs-5.0.6-duplicate-parent-options-for-included-maps.patch b/autofs-5.0.6-duplicate-parent-options-for-included-maps.patch
new file mode 100644
index 0000000..a38c509
--- /dev/null
+++ b/autofs-5.0.6-duplicate-parent-options-for-included-maps.patch
@@ -0,0 +1,158 @@
+autofs-5.0.6 - duplicate parent options for included maps
+
+From: Ian Kent <ikent at redhat.com>
+
+Included maps should inherite mount options from their parent mount.
+---
+
+ CHANGELOG             |    1 
+ modules/lookup_file.c |   61 +++++++++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 54 insertions(+), 8 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -43,6 +43,7 @@
+ - fix initialization in rpc create_client().
+ - fix libtirpc name clash.
+ - report map not read when debug logging.
++- duplicate parent options for included maps.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/modules/lookup_file.c
++++ autofs-5.0.6/modules/lookup_file.c
+@@ -41,9 +41,10 @@ typedef enum {
+ typedef enum { got_nothing, got_star, got_real, got_plus } FOUND_STATE;
+ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
+ 
+-
+ struct lookup_context {
+ 	const char *mapname;
++	int opts_argc;
++	const char **opts_argv;
+ 	struct parse_mod *parse;
+ };
+ 
+@@ -88,8 +89,20 @@ int lookup_init(const char *mapfmt, int
+ 	if (!mapfmt)
+ 		mapfmt = MAPFMT_DEFAULT;
+ 
+-	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
++	argc--;
++	argv++;
++
++	ctxt->opts_argv = copy_argv(argc, (const char **) argv);
++	if (ctxt->opts_argv == NULL) {
++		free(ctxt);
++		warn(LOGOPT_NONE, MODPREFIX "failed to duplicate options");
++		return 1;
++	}
++	ctxt->opts_argc = argc;
++
++	ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv);
+ 	if (!ctxt->parse) {
++		free_argv(ctxt->opts_argc, ctxt->opts_argv);
+ 		free(ctxt);
+ 		logmsg(MODPREFIX "failed to open parse context");
+ 		return 1;
+@@ -512,12 +525,15 @@ static int check_self_include(const char
+ }
+ 
+ static struct map_source *
+-prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned int inc)
++prepare_plus_include(struct autofs_point *ap,
++		     time_t age, char *key, unsigned int inc,
++		     struct lookup_context *ctxt)
+ {
+ 	struct map_source *current;
+ 	struct map_source *source;
+ 	struct map_type_info *info;
+ 	const char *argv[2];
++	char **tmp_argv, **tmp_opts;
+ 	int argc;
+ 	char *buf;
+ 
+@@ -551,9 +567,35 @@ prepare_plus_include(struct autofs_point
+ 	argv[0] = info->map;
+ 	argv[1] = NULL;
+ 
++	tmp_argv = (char **) copy_argv(argc, argv);
++	if (!tmp_argv) {
++		error(ap->logopt, MODPREFIX "failed to allocate args vector");
++		free_map_type_info(info);
++		free(buf);
++		return NULL;
++	}
++
++	tmp_opts = (char **) copy_argv(ctxt->opts_argc, ctxt->opts_argv);
++	if (!tmp_opts) {
++		error(ap->logopt, MODPREFIX "failed to allocate options args vector");
++		free_argv(argc, (const char **) tmp_argv);
++		free_map_type_info(info);
++		free(buf);
++		return NULL;
++	}
++
++	tmp_argv = append_argv(argc, tmp_argv, ctxt->opts_argc, tmp_opts);
++	if (!tmp_argv) {
++		error(ap->logopt, MODPREFIX "failed to append options vector");
++		free_map_type_info(info);
++		free(buf);
++		return NULL;
++	}
++	argc += ctxt->opts_argc;
++
+ 	source = master_find_source_instance(current,
+ 					     info->type, info->format,
+-					     argc, argv);
++					     argc, (const char **) tmp_argv);
+ 	if (source) {
+ 		/*
+ 		 * Make sure included map age is in sync with its owner
+@@ -563,15 +605,17 @@ prepare_plus_include(struct autofs_point
+ 		source->stale = 1;
+ 	} else {
+ 		source = master_add_source_instance(current,
+-						    info->type, info->format,
+-						    age, argc, argv);
++						    info->type, info->format, age,
++						    argc, (const char **) tmp_argv);
+ 		if (!source) {
++			free_argv(argc, (const char **) tmp_argv);
+ 			free_map_type_info(info);
+ 			free(buf);
+ 			error(ap->logopt, "failed to add included map instance");
+ 			return NULL;
+ 		}
+ 	}
++	free_argv(argc, (const char **) tmp_argv);
+ 
+ 	source->depth = current->depth + 1;
+ 	if (inc)
+@@ -645,7 +689,7 @@ int lookup_read_map(struct autofs_point
+ 			master_source_current_wait(ap->entry);
+ 			ap->entry->current = source;
+ 
+-			inc_source = prepare_plus_include(ap, age, key, inc);
++			inc_source = prepare_plus_include(ap, age, key, inc, ctxt);
+ 			if (!inc_source) {
+ 				debug(ap->logopt,
+ 				      "failed to select included map %s", key);
+@@ -729,7 +773,7 @@ static int lookup_one(struct autofs_poin
+ 				master_source_current_wait(ap->entry);
+ 				ap->entry->current = source;
+ 
+-				inc_source = prepare_plus_include(ap, age, mkey, inc);
++				inc_source = prepare_plus_include(ap, age, mkey, inc, ctxt);
+ 				if (!inc_source) {
+ 					debug(ap->logopt,
+ 					      MODPREFIX
+@@ -1096,6 +1140,7 @@ int lookup_done(void *context)
+ {
+ 	struct lookup_context *ctxt = (struct lookup_context *) context;
+ 	int rv = close_parse(ctxt->parse);
++	free_argv(ctxt->opts_argc, ctxt->opts_argv);
+ 	free(ctxt);
+ 	return rv;
+ }
diff --git a/autofs-5.0.6-fix-device-ioctl-alloc-path-check.patch b/autofs-5.0.6-fix-device-ioctl-alloc-path-check.patch
new file mode 100644
index 0000000..42e70de
--- /dev/null
+++ b/autofs-5.0.6-fix-device-ioctl-alloc-path-check.patch
@@ -0,0 +1,37 @@
+autofs-5.0.6 - fix devce ioctl alloc path check
+
+From: Ian Kent <ikent at redhat.com>
+
+The errno error should be set in alloc_dev_ioctl_path() if the passed
+in path in NULL.
+---
+
+ CHANGELOG           |    1 +
+ lib/dev-ioctl-lib.c |    4 +++-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -56,6 +56,7 @@
+ - fix umount recovery of busy direct mount.
+ - fix offset mount point directory removal.
+ - fix remount of multi mount.
++- fix devce ioctl alloc path check.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/lib/dev-ioctl-lib.c
++++ autofs-5.0.6/lib/dev-ioctl-lib.c
+@@ -270,8 +270,10 @@ static struct autofs_dev_ioctl *alloc_de
+ 	struct autofs_dev_ioctl *ioctl;
+ 	size_t size, p_len;
+ 
+-	if (!path)
++	if (!path) {
++		errno = EINVAL;
+ 		return NULL;
++	}
+ 
+ 	p_len = strlen(path);
+ 	size = sizeof(struct autofs_dev_ioctl) + p_len + 1;
diff --git a/autofs-5.0.6-fix-fix-LDAP-result-leaks-on-error-paths.patch b/autofs-5.0.6-fix-fix-LDAP-result-leaks-on-error-paths.patch
new file mode 100644
index 0000000..cf0b069
--- /dev/null
+++ b/autofs-5.0.6-fix-fix-LDAP-result-leaks-on-error-paths.patch
@@ -0,0 +1,33 @@
+autofs-5.0.6 - fix fix LDAP result leaks on error paths
+
+From: Ian Kent <raven at themaw.net>
+
+The previous patch with which ensured that the result struture returned
+from ldap_search_s(3) was freed could sometimes lead to a segmentation
+fault because the local variable used was not initialized before use.
+---
+
+ modules/lookup_ldap.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+
+--- autofs-5.0.6.orig/modules/lookup_ldap.c
++++ autofs-5.0.6/modules/lookup_ldap.c
+@@ -1521,7 +1521,7 @@ int lookup_read_master(struct master *ma
+ 	char buf[MAX_ERR_BUF];
+ 	char parse_buf[PARSE_MAX_BUF];
+ 	char *query;
+-	LDAPMessage *result, *e;
++	LDAPMessage *result = NULL, *e;
+ 	char *class, *info, *entry;
+ 	char **keyValue = NULL;
+ 	char **values = NULL;
+@@ -2467,7 +2467,7 @@ static int lookup_one(struct autofs_poin
+ 	char buf[MAX_ERR_BUF];
+ 	time_t age = time(NULL);
+ 	char *query;
+-	LDAPMessage *result, *e;
++	LDAPMessage *result = NULL, *e;
+ 	char *class, *info, *entry;
+ 	char *enc_key1, *enc_key2;
+ 	int enc_len1 = 0, enc_len2 = 0;
diff --git a/autofs-5.0.6-fix-kernel-verion-check-of-version-components.patch b/autofs-5.0.6-fix-kernel-verion-check-of-version-components.patch
new file mode 100644
index 0000000..cc7ad24
--- /dev/null
+++ b/autofs-5.0.6-fix-kernel-verion-check-of-version-components.patch
@@ -0,0 +1,94 @@
+autofs-5.0.6 - fix kernel verion check of version components
+
+From: Ian Kent <ikent at redhat.com>
+
+Oops, not following the ball.
+
+The kernel may have (or will have at times) a two digit version number.
+Fix the version check function to allow for this.
+---
+
+ CHANGELOG        |    1 +
+ include/mounts.h |   15 +--------------
+ lib/mounts.c     |   29 +++++++++++++++++++++++++++++
+ 3 files changed, 31 insertions(+), 14 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -46,6 +46,7 @@
+ - duplicate parent options for included maps.
+ - update ->timeout() function to not return timeout.
+ - move timeout to map_source (allow per direct map timeout).
++- fix kernel verion check of version components.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/include/mounts.h
++++ autofs-5.0.6/include/mounts.h
+@@ -75,26 +75,13 @@ struct mnt_list {
+ 	struct list_head ordered;
+ };
+ 
+-static inline unsigned int linux_version_code(void)
+-{
+-	struct utsname my_utsname;
+-	unsigned int p, q, r;
+-	char *save;
+-
+-	if (uname(&my_utsname))
+-		return 0;
+-
+-	p = (unsigned int) atoi(strtok_r(my_utsname.release, ".", &save));
+-	q = (unsigned int) atoi(strtok_r(NULL, ".", &save));
+-	r = (unsigned int) atoi(strtok_r(NULL, ".", &save));
+-	return KERNEL_VERSION(p, q, r);
+-}
+ 
+ struct nfs_mount_vers {
+ 	unsigned int major;
+ 	unsigned int minor;
+ 	unsigned int fix;
+ };
++unsigned int linux_version_code(void);
+ int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
+ extern unsigned int nfs_mount_uses_string_options;
+ 
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -46,6 +46,35 @@ static const char mnt_name_template[]
+ static struct kernel_mod_version kver = {0, 0};
+ static const char kver_options_template[]  = "fd=%d,pgrp=%u,minproto=3,maxproto=5";
+ 
++unsigned int linux_version_code(void)
++{
++	struct utsname my_utsname;
++	unsigned int p, q, r;
++	char *tmp, *save;
++
++	if (uname(&my_utsname))
++		return 0;
++
++	p = q = r = 0;
++
++	tmp = strtok_r(my_utsname.release, ".", &save);
++	if (!tmp)
++		return 0;
++	p = (unsigned int ) atoi(tmp);
++
++	tmp = strtok_r(NULL, ".", &save);
++	if (!tmp)
++		return KERNEL_VERSION(p, 0, 0);
++	q = (unsigned int) atoi(tmp);
++
++	tmp = strtok_r(NULL, ".", &save);
++	if (!tmp)
++		return KERNEL_VERSION(p, q, 0);
++	r = (unsigned int) atoi(tmp);
++
++	return KERNEL_VERSION(p, q, r);
++}
++
+ unsigned int query_kproto_ver(void)
+ {
+ 	struct ioctl_ops *ops = get_ioctl_ops();
diff --git a/autofs-5.0.6-fix-nfs4-contacts-portmap.patch b/autofs-5.0.6-fix-nfs4-contacts-portmap.patch
new file mode 100644
index 0000000..57b1ae7
--- /dev/null
+++ b/autofs-5.0.6-fix-nfs4-contacts-portmap.patch
@@ -0,0 +1,52 @@
+autofs-5.0.6 - fix nfs4 contacts portmap
+
+From: Ian Kent <ikent at redhat.com>
+
+When an fstype of nfs4 is specified probing the server for availability
+should not need to contact the portmapper, it should use either the port
+specified by the port= option or use port 2049.
+
+However, in function modules/replicated.c:get_nfs_info() a check for the
+port= option, and subsequent portmap lookup when not it's not present, is
+done before the check for whether nfsv3 is to be checked at all.
+
+Oops!
+---
+
+ CHANGELOG            |    1 +
+ modules/replicated.c |    6 +++---
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -49,6 +49,7 @@
+ - fix kernel verion check of version components.
+ - dont retry ldap connect if not required.
+ - check if /etc/mtab is a link to /proc/self/mounts.
++- fix nfs4 contacts portmap.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/modules/replicated.c
++++ autofs-5.0.6/modules/replicated.c
+@@ -589,6 +589,9 @@ static unsigned int get_nfs_info(unsigne
+ 	}
+ 
+ v3_ver:
++	if (!(version & NFS3_REQUESTED))
++		goto v2_ver;
++
+ 	if (!have_port_opt) {
+ 		status = rpc_portmap_getclient(pm_info,
+ 				host->name, host->addr, host->addr_len,
+@@ -600,9 +603,6 @@ v3_ver:
+ 			goto done_ver;
+ 	}
+ 
+-	if (!(version & NFS3_REQUESTED))
+-		goto v2_ver;
+-
+ 	if (have_port_opt) {
+ 		if (!(rpc_info->port = get_port_option(options)))
+ 			goto done_ver;
diff --git a/autofs-5.0.6-fix-offset-mount-point-directory-removal.patch b/autofs-5.0.6-fix-offset-mount-point-directory-removal.patch
new file mode 100644
index 0000000..0bf8c92
--- /dev/null
+++ b/autofs-5.0.6-fix-offset-mount-point-directory-removal.patch
@@ -0,0 +1,167 @@
+autofs-5.0.6 - fix offset mount point directory removal
+
+From: Ian Kent <ikent at redhat.com>
+
+Attempting to remove the last component of a multi-mount offset mount
+point is incorrect. The removal and attempted recovery is better
+handled in the calling function.
+---
+
+ CHANGELOG       |    1 
+ daemon/direct.c |    7 ----
+ lib/mounts.c    |   82 ++++++++++++++++++++++++++++++++------------------------
+ 3 files changed, 49 insertions(+), 41 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -54,6 +54,7 @@
+ - fix sss map age not updated.
+ - fix remount deadlock.
+ - fix umount recovery of busy direct mount.
++- fix offset mount point directory removal.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/direct.c
++++ autofs-5.0.6/daemon/direct.c
+@@ -633,13 +633,6 @@ force_umount:
+ 	} else
+ 		info(ap->logopt, "umounted offset mount %s", me->key);
+ 
+-	if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
+-		if  (rmdir(me->key) == -1) {
+-			char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-			warn(ap->logopt, "failed to remove dir %s: %s",
+-			     me->key, estr);
+-		}
+-	}
+ 	return rv;
+ }
+ 
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -1605,6 +1605,33 @@ int umount_ent(struct autofs_point *ap,
+ 	return rv;
+ }
+ 
++static int do_mount_autofs_offset(struct autofs_point *ap,
++				  struct mapent *oe, const char *root,
++				  char *offset)
++
++{
++	int mounted = 0;
++	int ret;
++
++	debug(ap->logopt, "mount offset %s at %s", oe->key, root);
++
++	ret = mount_autofs_offset(ap, oe, root, offset);
++	if (ret >= MOUNT_OFFSET_OK)
++		mounted++;
++	else {
++		if (ret != MOUNT_OFFSET_IGNORE)
++			warn(ap->logopt, "failed to mount offset");
++		else {
++			debug(ap->logopt, "ignoring \"nohide\" trigger %s",
++			      oe->key);
++			free(oe->mapent);
++			oe->mapent = NULL;
++		}
++	}
++
++	return mounted;
++}
++
+ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
+ 			 const char *root, unsigned int start, const char *base)
+ {
+@@ -1613,8 +1640,7 @@ int mount_multi_triggers(struct autofs_p
+ 	struct mapent *oe;
+ 	struct list_head *pos = NULL;
+ 	unsigned int fs_path_len;
+-	unsigned int mounted;
+-	int ret;
++	int mounted;
+ 
+ 	fs_path_len = start + strlen(base);
+ 	if (fs_path_len > PATH_MAX)
+@@ -1634,22 +1660,7 @@ int mount_multi_triggers(struct autofs_p
+ 		if (!oe || !oe->mapent)
+ 			goto cont;
+ 
+-		debug(ap->logopt, "mount offset %s at %s", oe->key, root);
+-
+-		ret = mount_autofs_offset(ap, oe, root, offset);
+-		if (ret >= MOUNT_OFFSET_OK)
+-			mounted++;
+-		else {
+-			if (ret != MOUNT_OFFSET_IGNORE)
+-				warn(ap->logopt, "failed to mount offset");
+-			else {
+-				debug(ap->logopt,
+-				      "ignoring \"nohide\" trigger %s",
+-				      oe->key);
+-				free(oe->mapent);
+-				oe->mapent = NULL;
+-			}
+-		}
++		mounted += do_mount_autofs_offset(ap, oe, root, offset);
+ cont:
+ 		offset = cache_get_offset(base,
+ 				offset, start, &me->multi_list, &pos);
+@@ -1681,7 +1692,6 @@ int umount_multi_triggers(struct autofs_
+ 	pos = NULL;
+ 	offset = path;
+ 
+-	/* Make sure "none" of the offsets have an active mount. */
+ 	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+ 		char *oe_base;
+ 
+@@ -1700,28 +1710,32 @@ int umount_multi_triggers(struct autofs_
+ 		if (oe->ioctlfd != -1 ||
+ 		    is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
+ 			left++;
+-			break;
+-		}
+-	}
+-
+-	if (left)
+-		return left;
+-
+-	pos = NULL;
+-	offset = path;
+-
+-	/* Make sure "none" of the offsets have an active mount. */
+-	while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+-		oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+-		/* root offset is a special case */
+-		if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
+ 			continue;
++		}
+ 
+ 		debug(ap->logopt, "umount offset %s", oe->key);
+ 
+ 		if (umount_autofs_offset(ap, oe)) {
+ 			warn(ap->logopt, "failed to umount offset");
+ 			left++;
++		} else {
++			struct stat st;
++			int ret;
++
++			if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
++				continue;
++
++			/*
++			 * An error due to partial directory removal is
++			 * ok so only try and remount the offset if the
++			 * actual mount point still exists.
++			 */
++			ret = rmdir_path(ap, oe->key, ap->dev);
++			if (ret == -1 && !stat(oe->key, &st)) {
++				ret = do_mount_autofs_offset(ap, oe, root, offset);
++				if (ret)
++					left++;
++			}
+ 		}
+ 	}
+ 
diff --git a/autofs-5.0.6-fix-remount-deadlock.patch b/autofs-5.0.6-fix-remount-deadlock.patch
new file mode 100644
index 0000000..31a92ed
--- /dev/null
+++ b/autofs-5.0.6-fix-remount-deadlock.patch
@@ -0,0 +1,136 @@
+autofs-5.0.6 - fix remount deadlock
+
+From: Ian Kent <raven at themaw.net>
+
+When reconstructing the mount tree upon restart a writelock to the map
+entry cache cannot be taken when parsing a direct map entry because a
+readlock is already held higher up in the call tree.
+
+In the place this is done it isn't be necessary to alter the direct map
+entries in the cache. Also, it shouldn't be necessary to delete existing
+multi-mount cache entries to avoid a duplicate multi-mount entry error
+return. The check for a duplicate can be done in the cache handling
+functions.
+---
+
+ CHANGELOG           |    1 
+ lib/cache.c         |    8 ++++--
+ modules/parse_sun.c |   60 ++++++++++++++++++++++++++--------------------------
+ 3 files changed, 36 insertions(+), 33 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -52,6 +52,7 @@
+ - fix nfs4 contacts portmap.
+ - make autofs wait longer for shutdown completion.
+ - fix sss map age not updated.
++- fix remount deadlock.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/lib/cache.c
++++ autofs-5.0.6/lib/cache.c
+@@ -658,10 +658,12 @@ int cache_add_offset(struct mapent_cache
+ 		return CHE_FAIL;
+ 
+ 	me = cache_lookup_distinct(mc, key);
+-	if (me && me != owner)
+-		return CHE_DUPLICATE;
++	if (me && me->age == age) {
++		if (me != owner)
++			return CHE_DUPLICATE;
++	}
+ 
+-	ret = cache_add(mc, owner->source, key, mapent, age);
++	ret = cache_update(mc, owner->source, key, mapent, age);
+ 	if (ret == CHE_FAIL) {
+ 		warn(logopt, "failed to add key %s to cache", key);
+ 		return CHE_FAIL;
+--- autofs-5.0.6.orig/modules/parse_sun.c
++++ autofs-5.0.6/modules/parse_sun.c
+@@ -843,12 +843,17 @@ add_offset_entry(struct autofs_point *ap
+ 		strcpy(m_mapent, loc);
+ 
+ 	ret = cache_add_offset(mc, name, m_key, m_mapent, age);
+-	if (ret == CHE_OK)
++	if (ret == CHE_DUPLICATE)
++		warn(ap->logopt, MODPREFIX
++		     "syntax error or duplicate offset %s -> %s", path, loc);
++	else if (ret == CHE_FAIL)
++		debug(ap->logopt, MODPREFIX
++		      "failed to add multi-mount offset %s -> %s", path, m_mapent);
++	else {
++		ret = CHE_OK;
+ 		debug(ap->logopt, MODPREFIX
+ 		      "added multi-mount offset %s -> %s", path, m_mapent);
+-	else
+-		warn(ap->logopt, MODPREFIX
+-		      "syntax error or duplicate offset %s -> %s", path, loc);
++	}
+ 
+ 	return ret;
+ }
+@@ -1410,7 +1415,7 @@ int parse_mount(struct autofs_point *ap,
+ 	char buf[MAX_ERR_BUF];
+ 	struct map_source *source;
+ 	struct mapent_cache *mc;
+-	struct mapent *me = NULL;
++	struct mapent *me;
+ 	char *pmapent, *options;
+ 	const char *p;
+ 	int mapent_len, rv = 0;
+@@ -1561,33 +1566,28 @@ int parse_mount(struct autofs_point *ap,
+ 			strcat(m_root, name);
+ 		}
+ 
+-		cache_writelock(mc);
+-		me = cache_lookup_distinct(mc, name);
+-		if (!me) {
+-			int ret;
+-			/*
+-			 * Not in the cache, perhaps it's a program map
+-			 * or one that doesn't support enumeration
+-			 */
+-			ret = cache_add(mc, source, name, mapent, time(NULL));
+-			if (ret == CHE_FAIL) {
+-				cache_unlock(mc);
+-				free(options);
+-				return 1;
++		/*
++		 * Can't take the write lock for direct mount entries here
++		 * but they should always be present in the map entry cache.
++		 */
++		if (ap->type == LKP_INDIRECT) {
++			cache_writelock(mc);
++			me = cache_lookup_distinct(mc, name);
++			if (!me) {
++				int ret;
++				/*
++				 * Not in the cache, perhaps it's a program map
++				 * or one that doesn't support enumeration.
++				 */
++				ret = cache_add(mc, source, name, mapent, age);
++				if (ret == CHE_FAIL) {
++					cache_unlock(mc);
++					free(options);
++					return 1;
++				}
+ 			}
+-		} else {
+-			/*
+-			 * If the entry exists it must not have any existing
+-			 * multi-mount subordinate entries since we are
+-			 * mounting this afresh. We need to do this to allow
+-			 * us to fail on the check for duplicate offsets in
+-			 * we don't know when submounts go away.
+-			 */
+-			cache_multi_writelock(me);
+-			cache_delete_offset_list(mc, name);
+-			cache_multi_unlock(me);
++			cache_unlock(mc);
+ 		}
+-		cache_unlock(mc);
+ 
+ 		cache_readlock(mc);
+ 		me = cache_lookup_distinct(mc, name);
diff --git a/autofs-5.0.6-fix-remount-of-multi-mount.patch b/autofs-5.0.6-fix-remount-of-multi-mount.patch
new file mode 100644
index 0000000..59dd7f7
--- /dev/null
+++ b/autofs-5.0.6-fix-remount-of-multi-mount.patch
@@ -0,0 +1,49 @@
+autofs-5.0.6 - fix remount of multi mount
+
+From: Ian Kent <ikent at redhat.com>
+
+Went accessing a multi-mount only the the offsets that need to be mounted
+are mounted. But when re-mounting multi-mounts during a restart we need to
+also traverse into existing mounts and re-connect to triggers mounted within
+them.
+---
+
+ CHANGELOG    |    1 +
+ lib/mounts.c |   15 +++++++++++++++
+ 2 files changed, 16 insertions(+)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -55,6 +55,7 @@
+ - fix remount deadlock.
+ - fix umount recovery of busy direct mount.
+ - fix offset mount point directory removal.
++- fix remount of multi mount.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -1661,6 +1661,21 @@ int mount_multi_triggers(struct autofs_p
+ 			goto cont;
+ 
+ 		mounted += do_mount_autofs_offset(ap, oe, root, offset);
++
++		/*
++		 * If re-constructing a multi-mount it's necessary to walk
++		 * into nested mounts, unlike the usual "mount only what's
++		 * needed as you go" behavior.
++		 */
++		if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
++			if (oe->ioctlfd != -1 ||
++			    is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) {
++				char oe_root[PATH_MAX + 1];
++				strcpy(oe_root, root);
++				strcat(oe_root, offset); 
++				mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base);
++			}
++		}
+ cont:
+ 		offset = cache_get_offset(base,
+ 				offset, start, &me->multi_list, &pos);
diff --git a/autofs-5.0.6-fix-sss-map-age.patch b/autofs-5.0.6-fix-sss-map-age.patch
new file mode 100644
index 0000000..f30aa1b
--- /dev/null
+++ b/autofs-5.0.6-fix-sss-map-age.patch
@@ -0,0 +1,34 @@
+autofs-5.0.6 - fix sss map age not updated
+
+From: Ian Kent <ikent at redhat.com>
+
+The map source age field should be updated when the map is read for
+map entry cache cleanup.
+---
+
+ CHANGELOG            |    1 +
+ modules/lookup_sss.c |    2 ++
+ 2 files changed, 3 insertions(+)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -51,6 +51,7 @@
+ - check if /etc/mtab is a link to /proc/self/mounts.
+ - fix nfs4 contacts portmap.
+ - make autofs wait longer for shutdown completion.
++- fix sss map age not updated.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/modules/lookup_sss.c
++++ autofs-5.0.6/modules/lookup_sss.c
+@@ -362,6 +362,8 @@ int lookup_read_map(struct autofs_point
+ 
+ 	endautomntent(ap->logopt, ctxt, &sss_ctxt);
+ 
++	source->age = age;
++
+ 	return NSS_STATUS_SUCCESS;
+ }
+ 
diff --git a/autofs-5.0.6-fix-umount-recovery-of-busy-direct-mount.patch b/autofs-5.0.6-fix-umount-recovery-of-busy-direct-mount.patch
new file mode 100644
index 0000000..bc2bf42
--- /dev/null
+++ b/autofs-5.0.6-fix-umount-recovery-of-busy-direct-mount.patch
@@ -0,0 +1,66 @@
+autofs-5.0.6 - fix umount recovery of busy direct mount
+
+From: Ian Kent <raven at themaw.net>
+
+Reported by Leonardo Chiquitto (along with a problem analysis that lead
+to the resolution). Thanks for the effort Leonardo.
+
+When umounting direct mounts at exit, if any are busy and contain offset
+trigger mounts automount will try and re-mount them when the umount fails
+so they can be used to re-construct the mount tree at restart. But this
+fails because the kernel communication pipe, which is used as a parameter
+when mounting the offsets, has already been closed. To fix this all we
+need do is delay closing the kernel pipe file handle until after the
+direct mounts have been umounted since this doesn't affect the in use
+status of the mounts.
+---
+
+ CHANGELOG       |    1 +
+ daemon/direct.c |   18 +++++++++---------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -53,6 +53,7 @@
+ - make autofs wait longer for shutdown completion.
+ - fix sss map age not updated.
+ - fix remount deadlock.
++- fix umount recovery of busy direct mount.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/direct.c
++++ autofs-5.0.6/daemon/direct.c
+@@ -193,15 +193,6 @@ int umount_autofs_direct(struct autofs_p
+ 	struct mnt_list *mnts;
+ 	struct mapent *me, *ne;
+ 
+-	close(ap->state_pipe[0]);
+-	close(ap->state_pipe[1]);
+-	if (ap->pipefd >= 0)
+-		close(ap->pipefd);
+-	if (ap->kpipefd >= 0) {
+-		close(ap->kpipefd);
+-		ap->kpipefd = -1;
+-	}
+-
+ 	mnts = tree_make_mnt_tree(_PROC_MOUNTS, "/");
+ 	pthread_cleanup_push(mnts_cleanup, mnts);
+ 	nc = ap->entry->master->nc;
+@@ -231,6 +222,15 @@ int umount_autofs_direct(struct autofs_p
+ 	pthread_cleanup_pop(1);
+ 	pthread_cleanup_pop(1);
+ 
++	close(ap->state_pipe[0]);
++	close(ap->state_pipe[1]);
++	if (ap->pipefd >= 0)
++		close(ap->pipefd);
++	if (ap->kpipefd >= 0) {
++		close(ap->kpipefd);
++		ap->kpipefd = -1;
++	}
++
+ 	return 0;
+ }
+ 
diff --git a/autofs-5.0.6-make-autofs-wait-longer-for-shutdown.patch b/autofs-5.0.6-make-autofs-wait-longer-for-shutdown.patch
new file mode 100644
index 0000000..9917f67
--- /dev/null
+++ b/autofs-5.0.6-make-autofs-wait-longer-for-shutdown.patch
@@ -0,0 +1,78 @@
+autofs-5.0.6 - make autofs wait longer for shutdown
+
+From: Ian Kent <ikent at redhat.com>
+
+After signaling the automount daemon to shutdown the autofs init script
+doesn't wait long enough for the daemon to exit. This can be a problem
+if there are a large number of mounts or if servers are slow to respond.
+---
+
+ CHANGELOG                 |    1 +
+ redhat/autofs.init.in     |    5 ++++-
+ samples/autofs.service.in |    1 +
+ samples/rc.autofs.in      |    5 ++++-
+ 4 files changed, 10 insertions(+), 2 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -50,6 +50,7 @@
+ - dont retry ldap connect if not required.
+ - check if /etc/mtab is a link to /proc/self/mounts.
+ - fix nfs4 contacts portmap.
++- make autofs wait longer for shutdown completion.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/redhat/autofs.init.in
++++ autofs-5.0.6/redhat/autofs.init.in
+@@ -108,7 +108,7 @@ function stop() {
+ 	while [ -n "`pidof $prog`" -a $count -lt 15 ] ; do
+ 		killproc $prog -TERM >& /dev/null
+ 		RETVAL=$?
+-		[ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 3
++		[ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 20
+ 		count=`expr $count + 1`
+ 	done
+ 	if [ $RETVAL -eq 0 ]; then
+@@ -129,6 +129,9 @@ function restart() {
+ 	status autofs > /dev/null 2>&1
+ 	if [ $? -eq 0 ]; then
+ 		stop
++		while [ -n "`pidof $prog`" ] ; do
++			sleep 5
++		done
+ 	fi
+ 	start
+ }
+--- autofs-5.0.6.orig/samples/autofs.service.in
++++ autofs-5.0.6/samples/autofs.service.in
+@@ -8,6 +8,7 @@ PIDFile=@@autofspiddir@@/autofs.pid
+ EnvironmentFile=-@@autofsconfdir@@/autofs
+ ExecStart=@@sbindir@@/automount ${OPTIONS} --pid-file @@autofspiddir@@/autofs.pid
+ ExecReload=/usr/bin/kill -HUP $MAINPID
++TimeoutSec=180
+ 
+ [Install]
+ WantedBy=multi-user.target
+--- autofs-5.0.6.orig/samples/rc.autofs.in
++++ autofs-5.0.6/samples/rc.autofs.in
+@@ -91,7 +91,7 @@ function stop() {
+ 	while [ -n "`pidof $prog`" -a $count -lt 15 ] ; do
+ 		killall -TERM $prog >& /dev/null
+ 		RETVAL=$?
+-		[ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 3
++		[ $RETVAL = 0 -a -z "`pidof $prog`" ] || sleep 20
+ 		count=`expr $count + 1`
+ 	done
+ 	if [ -z "`pidof $prog`" ] ; then
+@@ -104,6 +104,9 @@ function stop() {
+ 
+ function restart() {
+ 	stop
++	while [ -n "`pidof $prog`" ] ; do
++		sleep 5
++	done
+ 	start
+ }
+ 
diff --git a/autofs-5.0.6-move-timeout-to-map_source.patch b/autofs-5.0.6-move-timeout-to-map_source.patch
new file mode 100644
index 0000000..6e181c3
--- /dev/null
+++ b/autofs-5.0.6-move-timeout-to-map_source.patch
@@ -0,0 +1,529 @@
+autofs-5.0.6 - move timeout to map_source
+
+From: Ian Kent <ikent at redhat.com>
+
+Move the map entry timeout field from "struct autofs_point" to
+"struct map_source".
+
+The result of this change is that an individual timeout may be
+set for each direct map master map entry.
+---
+
+ CHANGELOG              |    1 +
+ daemon/automount.c     |    2 +-
+ daemon/direct.c        |   32 +++++++++++++++++++++-----------
+ daemon/indirect.c      |    7 +++----
+ daemon/lookup.c        |    2 ++
+ daemon/state.c         |   18 +++++++++++++++++-
+ include/automount.h    |    5 +++--
+ include/master.h       |    3 ++-
+ include/mounts.h       |    2 +-
+ lib/master.c           |    9 ++++-----
+ lib/master_parse.y     |   32 +++++++++++++-------------------
+ lib/mounts.c           |   37 ++++++++++++++++++-------------------
+ modules/mount_autofs.c |    5 +++--
+ 13 files changed, 89 insertions(+), 66 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -45,6 +45,7 @@
+ - report map not read when debug logging.
+ - duplicate parent options for included maps.
+ - update ->timeout() function to not return timeout.
++- move timeout to map_source (allow per direct map timeout).
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/automount.c
++++ autofs-5.0.6/daemon/automount.c
+@@ -1585,7 +1585,7 @@ void *handle_mounts(void *arg)
+ 
+ 	/* We often start several automounters at the same time.  Add some
+ 	   randomness so we don't all expire at the same time. */
+-	if (!ap->submount && ap->exp_timeout)
++	if (!ap->submount && ap->exp_runfreq)
+ 		alarm_add(ap, ap->exp_runfreq + rand() % ap->exp_runfreq);
+ 
+ 	pthread_setcancelstate(cancel_state, NULL);
+--- autofs-5.0.6.orig/daemon/direct.c
++++ autofs-5.0.6/daemon/direct.c
+@@ -286,7 +286,7 @@ static int unlink_active_mounts(struct a
+ 
+ 	if (tree_get_mnt_list(mnts, &list, me->key, 1)) {
+ 		if (ap->state == ST_READMAP) {
+-			time_t tout = ap->exp_timeout;
++			time_t tout = me->source->exp_timeout;
+ 			int save_ioctlfd, ioctlfd;
+ 
+ 			save_ioctlfd = ioctlfd = me->ioctlfd;
+@@ -321,18 +321,26 @@ static int unlink_active_mounts(struct a
+ 	return 1;
+ }
+ 
+-int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me)
++int do_mount_autofs_direct(struct autofs_point *ap,
++			   struct mnt_list *mnts, struct mapent *me,
++			   time_t timeout)
+ {
+ 	const char *str_direct = mount_type_str(t_direct);
+ 	struct ioctl_ops *ops = get_ioctl_ops();
+ 	struct mnt_params *mp;
+-	time_t timeout = ap->exp_timeout;
+ 	struct stat st;
+ 	int status, ret, ioctlfd;
+ 	const char *map_name;
++	time_t runfreq;
+ 
+-	/* Calculate the timeouts */
+-	ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
++	if (timeout) {
++		/* Calculate the expire run frequency */
++		runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
++		if (ap->exp_runfreq)
++			ap->exp_runfreq = min(ap->exp_runfreq, runfreq);
++		else
++			ap->exp_runfreq = runfreq;
++	}
+ 
+ 	if (ops->version && !do_force_unlink) {
+ 		ap->flags |= MOUNT_FLAG_REMOUNT;
+@@ -425,7 +433,7 @@ int do_mount_autofs_direct(struct autofs
+ 	}
+ 
+ 	ops->timeout(ap->logopt, ioctlfd, timeout);
+-	notify_mount_result(ap, me->key, str_direct);
++	notify_mount_result(ap, me->key, timeout, str_direct);
+ 	cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ 	ops->close(ap->logopt, ioctlfd);
+ 
+@@ -473,6 +481,7 @@ int mount_autofs_direct(struct autofs_po
+ 	pthread_cleanup_push(cache_lock_cleanup, nc);
+ 	map = ap->entry->maps;
+ 	while (map) {
++		time_t timeout;
+ 		/*
+ 		 * Only consider map sources that have been read since
+ 		 * the map entry was last updated.
+@@ -483,6 +492,7 @@ int mount_autofs_direct(struct autofs_po
+ 		}
+ 
+ 		mc = map->mc;
++		timeout = map->exp_timeout;
+ 		cache_readlock(mc);
+ 		pthread_cleanup_push(cache_lock_cleanup, mc);
+ 		me = cache_enumerate(mc, NULL);
+@@ -491,7 +501,7 @@ int mount_autofs_direct(struct autofs_po
+ 			if (ne) {
+ 				if (map->master_line < ne->age) {
+ 					/* TODO: check return, locking me */
+-					do_mount_autofs_direct(ap, mnts, me);
++					do_mount_autofs_direct(ap, mnts, me, timeout);
+ 				}
+ 				me = cache_enumerate(mc, me);
+ 				continue;
+@@ -508,7 +518,7 @@ int mount_autofs_direct(struct autofs_po
+ 			}
+ 
+ 			/* TODO: check return, locking me */
+-			do_mount_autofs_direct(ap, mnts, me);
++			do_mount_autofs_direct(ap, mnts, me, timeout);
+ 
+ 			me = cache_enumerate(mc, me);
+ 		}
+@@ -639,7 +649,7 @@ int mount_autofs_offset(struct autofs_po
+ 	struct ioctl_ops *ops = get_ioctl_ops();
+ 	char buf[MAX_ERR_BUF];
+ 	struct mnt_params *mp;
+-	time_t timeout = ap->exp_timeout;
++	time_t timeout = me->source->exp_timeout;
+ 	struct stat st;
+ 	int ioctlfd, status, ret;
+ 	const char *hosts_map_name = "-hosts";
+@@ -774,9 +784,9 @@ int mount_autofs_offset(struct autofs_po
+ 	ops->timeout(ap->logopt, ioctlfd, timeout);
+ 	cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ 	if (ap->logopt & LOGOPT_DEBUG)
+-		notify_mount_result(ap, mountpoint, str_offset);
++		notify_mount_result(ap, mountpoint, timeout, str_offset);
+ 	else
+-		notify_mount_result(ap, me->key, str_offset);
++		notify_mount_result(ap, me->key, timeout, str_offset);
+ 	ops->close(ap->logopt, ioctlfd);
+ 
+ 	debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
+--- autofs-5.0.6.orig/daemon/indirect.c
++++ autofs-5.0.6/daemon/indirect.c
+@@ -87,7 +87,7 @@ static int do_mount_autofs_indirect(stru
+ {
+ 	const char *str_indirect = mount_type_str(t_indirect);
+ 	struct ioctl_ops *ops = get_ioctl_ops();
+-	time_t timeout = ap->exp_timeout;
++	time_t timeout = ap->entry->maps->exp_timeout;
+ 	char *options = NULL;
+ 	const char *hosts_map_name = "-hosts";
+ 	const char *map_name = hosts_map_name;
+@@ -170,13 +170,12 @@ static int do_mount_autofs_indirect(stru
+ 	}
+ 
+ 	ap->dev = st.st_dev;	/* Device number for mount point checks */
+-	ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ 
+ 	ops->timeout(ap->logopt, ap->ioctlfd, timeout);
+ 	if (ap->logopt & LOGOPT_DEBUG)
+-		notify_mount_result(ap, root, str_indirect);
++		notify_mount_result(ap, root, timeout, str_indirect);
+ 	else
+-		notify_mount_result(ap, ap->path, str_indirect);
++		notify_mount_result(ap, ap->path, timeout, str_indirect);
+ 
+ 	return 0;
+ 
+--- autofs-5.0.6.orig/daemon/lookup.c
++++ autofs-5.0.6/daemon/lookup.c
+@@ -413,6 +413,7 @@ static enum nsswitch_status read_map_sou
+ 	tmap.lookup = map->lookup;
+ 	tmap.mc = map->mc;
+ 	tmap.instance = map->instance;
++	tmap.exp_timeout = map->exp_timeout;
+ 	tmap.recurse = map->recurse;
+ 	tmap.depth = map->depth;
+ 	tmap.stale = map->stale;
+@@ -770,6 +771,7 @@ static enum nsswitch_status lookup_map_n
+ 	tmap.format = map->format;
+ 	tmap.mc = map->mc;
+ 	tmap.instance = map->instance;
++	tmap.exp_timeout = map->exp_timeout;
+ 	tmap.recurse = map->recurse;
+ 	tmap.depth = map->depth;
+ 	tmap.argc = 0;
+--- autofs-5.0.6.orig/daemon/state.c
++++ autofs-5.0.6/daemon/state.c
+@@ -400,6 +400,9 @@ static void do_readmap_mount(struct auto
+ 		}
+ 		if (valid) {
+ 			struct mapent_cache *vmc = valid->mc;
++			struct ioctl_ops *ops = get_ioctl_ops();
++			time_t runfreq;
++
+ 			cache_unlock(vmc);
+ 			debug(ap->logopt,
+ 			     "updating cache entry for valid direct trigger %s",
+@@ -412,13 +415,22 @@ static void do_readmap_mount(struct auto
+ 			/* Set device and inode number of the new mapent */
+ 			cache_set_ino_index(vmc, me->key, me->dev, me->ino);
+ 			cache_unlock(vmc);
++			/* Set timeout and calculate the expire run frequency */
++			ops->timeout(ap->logopt, valid->ioctlfd, map->exp_timeout);
++			if (map->exp_timeout) {
++				runfreq = (map->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
++				if (ap->exp_runfreq)
++					ap->exp_runfreq = min(ap->exp_runfreq, runfreq);
++				else
++					ap->exp_runfreq = runfreq;
++			}
+ 		} else if (!tree_is_mounted(mnts, me->key, MNTS_REAL))
+ 			do_umount_autofs_direct(ap, mnts, me);
+ 		else
+ 			debug(ap->logopt,
+ 			      "%s is mounted", me->key);
+ 	} else
+-		do_mount_autofs_direct(ap, mnts, me);
++		do_mount_autofs_direct(ap, mnts, me, map->exp_timeout);
+ 
+ 	return;
+ }
+@@ -466,6 +478,10 @@ static void *do_readmap(void *arg)
+ 	pthread_cleanup_pop(1);
+ 
+ 	if (ap->type == LKP_INDIRECT) {
++		struct ioctl_ops *ops = get_ioctl_ops();
++		time_t timeout = ap->entry->maps->exp_timeout;
++		ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
++		ops->timeout(ap->logopt, ap->ioctlfd, timeout);
+ 		lookup_prune_cache(ap, now);
+ 		status = lookup_ghost(ap, ap->path);
+ 	} else {
+--- autofs-5.0.6.orig/include/automount.h
++++ autofs-5.0.6/include/automount.h
+@@ -114,6 +114,8 @@ int load_autofs4_module(void);
+ #define DB(x)           do { } while(0)
+ #endif
+ 
++#define min(a, b)	(a <= b ? a : b)
++
+ /* Forward declaraion */
+ struct autofs_point; 
+ 
+@@ -461,7 +463,6 @@ struct autofs_point {
+ 	dev_t dev;			/* "Device" number assigned by kernel */
+ 	struct master_mapent *entry;	/* Master map entry for this mount */
+ 	unsigned int type;		/* Type of map direct or indirect */
+-	time_t exp_timeout;		/* Timeout for expiring mounts */
+ 	time_t exp_runfreq;		/* Frequency for polling for timeouts */
+ 	time_t negative_timeout;	/* timeout in secs for failed mounts */
+ 	unsigned int flags;		/* autofs mount flags */
+@@ -495,7 +496,7 @@ void *expire_proc_indirect(void *);
+ void *expire_proc_direct(void *);
+ int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now);
+ int mount_autofs_indirect(struct autofs_point *ap, const char *root);
+-int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me);
++int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me, time_t timeout);
+ int mount_autofs_direct(struct autofs_point *ap);
+ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset);
+ void submount_signal_parent(struct autofs_point *ap, unsigned int success);
+--- autofs-5.0.6.orig/include/master.h
++++ autofs-5.0.6/include/master.h
+@@ -23,6 +23,7 @@
+ struct map_source {
+ 	char *type;
+ 	char *format;
++	time_t exp_timeout;		/* Timeout for expiring mounts */
+ 	time_t age;
+ 	unsigned int master_line;
+ 	struct mapent_cache *mc;
+@@ -78,7 +79,7 @@ void master_mutex_unlock(void);
+ void master_mutex_lock_cleanup(void *);
+ void master_set_default_timeout(void);
+ void master_set_default_ghost_mode(void);
+-int master_add_autofs_point(struct master_mapent *, time_t, unsigned, unsigned, unsigned, int);
++int master_add_autofs_point(struct master_mapent *, unsigned, unsigned, unsigned, int);
+ void master_free_autofs_point(struct autofs_point *);
+ struct map_source *
+ master_add_map_source(struct master_mapent *, char *, char *, time_t, int, const char **);
+--- autofs-5.0.6.orig/include/mounts.h
++++ autofs-5.0.6/include/mounts.h
+@@ -120,7 +120,7 @@ int tree_find_mnt_ents(struct mnt_list *
+ int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type);
+ void set_tsd_user_vars(unsigned int, uid_t, gid_t);
+ const char *mount_type_str(unsigned int);
+-void notify_mount_result(struct autofs_point *, const char *, const char *);
++void notify_mount_result(struct autofs_point *, const char *, time_t, const char *);
+ int try_remount(struct autofs_point *, struct mapent *, unsigned int);
+ int umount_ent(struct autofs_point *, const char *);
+ int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
+--- autofs-5.0.6.orig/lib/master.c
++++ autofs-5.0.6/lib/master.c
+@@ -65,9 +65,8 @@ void master_mutex_lock_cleanup(void *arg
+ 	return;
+ }
+ 
+-int master_add_autofs_point(struct master_mapent *entry, time_t timeout,
+-			    unsigned logopt, unsigned nobind, unsigned ghost,
+-			    int submount)
++int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
++			    unsigned nobind, unsigned ghost, int submount)
+ {
+ 	struct autofs_point *ap;
+ 	int status;
+@@ -91,7 +90,6 @@ int master_add_autofs_point(struct maste
+ 	ap->entry = entry;
+ 	ap->exp_thread = 0;
+ 	ap->readmap_thread = 0;
+-	ap->exp_timeout = timeout;
+ 	/*
+ 	 * Program command line option overrides config.
+ 	 * We can't use 0 negative timeout so use default.
+@@ -100,7 +98,7 @@ int master_add_autofs_point(struct maste
+ 		ap->negative_timeout = defaults_get_negative_timeout();
+ 	else
+ 		ap->negative_timeout = global_negative_timeout;
+-	ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
++	ap->exp_runfreq = 0;
+ 	ap->flags = 0;
+ 	if (ghost)
+ 		ap->flags = MOUNT_FLAG_GHOST;
+@@ -437,6 +435,7 @@ master_add_source_instance(struct map_so
+ 	new->age = age;
+ 	new->master_line = 0;
+ 	new->mc = source->mc;
++	new->exp_timeout = source->exp_timeout;
+ 	new->stale = 1;
+ 
+ 	tmpargv = copy_argv(argc, argv);
+--- autofs-5.0.6.orig/lib/master_parse.y
++++ autofs-5.0.6/lib/master_parse.y
+@@ -765,9 +765,6 @@ int master_parse_entry(const char *buffe
+ 		logopt |= (verbose ? LOGOPT_VERBOSE : 0);
+ 	}
+ 
+-	if (timeout < 0)
+-		timeout = default_timeout;
+-
+ 	new = NULL;
+ 	entry = master_find_mapent(master, path);
+ 	if (!entry) {
+@@ -789,8 +786,19 @@ int master_parse_entry(const char *buffe
+ 		}
+ 	}
+ 
++	if (timeout < 0) {
++		/*
++		 * If no timeout is given get the timout from first
++		 * map (if it exists).
++		 */
++		if (entry->maps)
++			timeout = entry->maps->exp_timeout;
++		else
++			timeout = default_timeout;
++	}
++
+ 	if (!entry->ap) {
+-		ret = master_add_autofs_point(entry, timeout, logopt, nobind, ghost, 0);
++		ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0);
+ 		if (!ret) {
+ 			error(m_logopt, "failed to add autofs_point");
+ 			if (new)
+@@ -798,20 +806,6 @@ int master_parse_entry(const char *buffe
+ 			local_free_vars();
+ 			return 0;
+ 		}
+-	} else {
+-		struct ioctl_ops *ops = get_ioctl_ops();
+-		struct autofs_point *ap = entry->ap;
+-
+-		/*
+-		 * Second and subsequent instances of a mount point
+-		 * use the ghost, log and timeout of the first
+-		 */
+-		if (entry->age < age) {
+-			ap->exp_timeout = timeout;
+-			ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+-			if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
+-				ops->timeout(ap->logopt, ap->ioctlfd, timeout);
+-		}
+ 	}
+ 	if (random_selection)
+ 		entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT;
+@@ -838,7 +832,7 @@ int master_parse_entry(const char *buffe
+ 		local_free_vars();
+ 		return 0;
+ 	}
+-
++	source->exp_timeout = timeout;
+ 	source->master_line = lineno;
+ 
+ 	entry->age = age;
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -1268,13 +1268,12 @@ const char *mount_type_str(const unsigne
+ }
+ 
+ void notify_mount_result(struct autofs_point *ap,
+-			 const char *path, const char *type)
++			 const char *path, time_t timeout, const char *type)
+ {
+-	if (ap->exp_timeout)
++	if (timeout)
+ 		info(ap->logopt,
+ 		    "mounted %s on %s with timeout %u, freq %u seconds",
+-		    type, path,
+-		    (unsigned int) ap->exp_timeout,
++		    type, path, (unsigned int) timeout,
+ 		    (unsigned int) ap->exp_runfreq);
+ 	else
+ 		info(ap->logopt,
+@@ -1382,16 +1381,14 @@ static int do_remount_indirect(struct au
+ }
+ 
+ static int remount_active_mount(struct autofs_point *ap,
+-				struct mapent_cache *mc,
+-				const char *path, dev_t devid,
+-				const unsigned int type,
+-				int *ioctlfd)
++				struct mapent *me, const char *path, dev_t devid,
++				const unsigned int type, int *ioctlfd)
+ {
+ 	struct ioctl_ops *ops = get_ioctl_ops();
+-	time_t timeout = ap->exp_timeout;
+ 	const char *str_type = mount_type_str(type);
+ 	char buf[MAX_ERR_BUF];
+ 	unsigned int mounted;
++	time_t timeout;
+ 	struct stat st;
+ 	int fd;
+ 
+@@ -1401,6 +1398,12 @@ static int remount_active_mount(struct a
+ 	ops->open(ap->logopt, &fd, devid, path);
+ 	if (fd == -1)
+ 		return REMOUNT_OPEN_FAIL;
++	else {
++		if (type == t_indirect || type == t_offset)
++			timeout = ap->entry->maps->exp_timeout;
++		else
++			timeout = me->source->exp_timeout;
++	}
+ 
+ 	/* Re-reading the map, set timeout and return */
+ 	if (ap->state == ST_READMAP) {
+@@ -1434,11 +1437,11 @@ static int remount_active_mount(struct a
+ 		ops->close(ap->logopt, fd);
+ 		return REMOUNT_STAT_FAIL;
+ 	}
+-	if (mc)
+-		cache_set_ino_index(mc, path, st.st_dev, st.st_ino);
++	if (type != t_indirect)
++		cache_set_ino_index(me->mc, path, st.st_dev, st.st_ino);
+ 	else
+ 		ap->dev = st.st_dev;
+-	notify_mount_result(ap, path, str_type);
++	notify_mount_result(ap, path, timeout, str_type);
+ 
+ 	*ioctlfd = fd;
+ 
+@@ -1481,24 +1484,20 @@ static int remount_active_mount(struct a
+ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
+ {
+ 	struct ioctl_ops *ops = get_ioctl_ops();
+-	struct mapent_cache *mc;
+ 	const char *path;
+ 	int ret, fd;
+ 	dev_t devid;
+ 
+-	if (type == t_indirect) {
+-		mc = NULL;
++	if (type == t_indirect)
+ 		path = ap->path;
+-	} else {
+-		mc = me->mc;
++	else
+ 		path = me->key;
+-	}
+ 
+ 	ret = ops->mount_device(ap->logopt, path, type, &devid);
+ 	if (ret == -1 || ret == 0)
+ 		return -1;
+ 
+-	ret = remount_active_mount(ap, mc, path, devid, type, &fd);
++	ret = remount_active_mount(ap, me, path, devid, type, &fd);
+ 
+ 	/*
+ 	 * The directory must exist since we found a device
+--- autofs-5.0.6.orig/modules/mount_autofs.c
++++ autofs-5.0.6/modules/mount_autofs.c
+@@ -51,7 +51,7 @@ int mount_mount(struct autofs_point *ap,
+ 	int argc, status;
+ 	int nobind = ap->flags & MOUNT_FLAG_NOBIND;
+ 	int ghost = ap->flags & MOUNT_FLAG_GHOST;
+-	time_t timeout = ap->exp_timeout;
++	time_t timeout = ap->entry->maps->exp_timeout;
+ 	unsigned logopt = ap->logopt;
+ 	struct map_type_info *info;
+ 	struct master *master;
+@@ -149,7 +149,7 @@ int mount_mount(struct autofs_point *ap,
+ 		return 1;
+ 	}
+ 
+-	ret = master_add_autofs_point(entry, timeout, logopt, nobind, ghost, 1);
++	ret = master_add_autofs_point(entry, logopt, nobind, ghost, 1);
+ 	if (!ret) {
+ 		error(ap->logopt,
+ 		      MODPREFIX "failed to add autofs_point to entry");
+@@ -203,6 +203,7 @@ int mount_mount(struct autofs_point *ap,
+ 		return 1;
+ 	}
+ 	free_map_type_info(info);
++	source->exp_timeout = timeout;
+ 
+ 	mounts_mutex_lock(ap);
+ 
diff --git a/autofs-5.0.6-refactor-lookup-hosts-module.patch b/autofs-5.0.6-refactor-lookup-hosts-module.patch
new file mode 100644
index 0000000..ecc18be
--- /dev/null
+++ b/autofs-5.0.6-refactor-lookup-hosts-module.patch
@@ -0,0 +1,248 @@
+autofs-5.0.6 - refactor hosts lookup module
+
+From: Ian Kent <ikent at redhat.com>
+
+Simplify lookup hosts lookup_mount() function.
+---
+
+ modules/lookup_hosts.c |  206 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 101 insertions(+), 105 deletions(-)
+
+
+--- autofs-5.0.6.orig/modules/lookup_hosts.c
++++ autofs-5.0.6/modules/lookup_hosts.c
+@@ -78,6 +78,94 @@ int lookup_read_master(struct master *ma
+ 	return NSS_STATUS_UNKNOWN;
+ }
+ 
++static char *get_exports(struct autofs_point *ap, const char *host)
++{
++	char *mapent = NULL;
++	exports exp;
++
++	debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
++
++	exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
++
++	mapent = NULL;
++	while (exp) {
++		if (mapent) {
++			int len = strlen(mapent) + 1;
++
++			len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
++			mapent = realloc(mapent, len);
++			if (!mapent) {
++				char *estr;
++				estr = strerror_r(errno, buf, MAX_ERR_BUF);
++				error(ap->logopt, MODPREFIX "malloc: %s", estr);
++				rpc_exports_free(exp);
++				return NSS_STATUS_UNAVAIL;
++			}
++			strcat(mapent, " \"");
++			strcat(mapent, exp->ex_dir);
++			strcat(mapent, "\"");
++		} else {
++			int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
++
++			mapent = malloc(len);
++			if (!mapent) {
++				char *estr;
++				estr = strerror_r(errno, buf, MAX_ERR_BUF);
++				error(ap->logopt, MODPREFIX "malloc: %s", estr);
++				rpc_exports_free(exp);
++				return NSS_STATUS_UNAVAIL;
++			}
++			strcpy(mapent, "\"");
++			strcat(mapent, exp->ex_dir);
++			strcat(mapent, "\"");
++		}
++		strcat(mapent, " \"");
++		strcat(mapent, name);
++		strcat(mapent, ":");
++		strcat(mapent, exp->ex_dir);
++		strcat(mapent, "\"");
++
++		exp = exp->ex_next;
++	}
++	rpc_exports_free(exp);
++
++	if (!mapent)
++		error(ap->logopt, "exports lookup failed for %s", name);
++
++	return mapent;
++}
++
++static int do_parse_mount(struct autofs_point *ap,
++			  const char *name, int name_len, char *mapent,
++			  void *context)
++{
++	int ret;
++
++	master_source_current_wait(ap->entry);
++	ap->entry->current = source;
++
++	ret = ctxt->parse->parse_mount(ap, name, name_len,
++				 mapent, ctxt->parse->context);
++	if (ret) {
++		time_t now = time(NULL);
++		struct mapent_cache *mc = source->mc;
++		struct mapent *me;
++		int rv = CHE_OK;
++
++		cache_writelock(mc);
++		me = cache_lookup_distinct(mc, name);
++		if (!me)
++			rv = cache_update(mc, source, name, NULL, now);
++		if (rv != CHE_FAIL) {
++			me = cache_lookup_distinct(mc, name);
++			me->status = now + ap->negative_timeout;
++		}
++		cache_unlock(mc);
++		return NSS_STATUS_TRYAGAIN;
++	}
++	return NSS_STATUS_SUCCESS;
++}
++
+ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
+ {
+ 	struct map_source *source;
+@@ -209,126 +297,34 @@ int lookup_mount(struct autofs_point *ap
+ 	if (*name == '/') {
+ 		pthread_cleanup_push(cache_lock_cleanup, mc);
+ 		mapent_len = strlen(me->mapent);
+-		mapent = alloca(mapent_len + 1);
++		mapent = malloc(mapent_len + 1);
+ 		if (mapent)
+ 			strcpy(mapent, me->mapent);
+ 		pthread_cleanup_pop(0);
+ 	}
+ 	cache_unlock(mc);
+ 
+-	if (mapent) {
+-		master_source_current_wait(ap->entry);
+-		ap->entry->current = source;
+-
+-		debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
+-
+-		ret = ctxt->parse->parse_mount(ap, name, name_len,
+-				 mapent, ctxt->parse->context);
+-
+-		if (ret) {
+-			time_t now = time(NULL);
+-			int rv = CHE_OK;
+-
+-			cache_writelock(mc);
+-			me = cache_lookup_distinct(mc, name);
+-			if (!me)
+-				rv = cache_update(mc, source, name, NULL, now);
+-			if (rv != CHE_FAIL) {
+-				me = cache_lookup_distinct(mc, name);
+-				me->status = now + ap->negative_timeout;
+-			}
+-			cache_unlock(mc);
+-			return NSS_STATUS_TRYAGAIN;
+-		}
+-		return NSS_STATUS_SUCCESS;
+-	}
+ done:
+-	/*
+-	 * Otherwise we need to get the exports list and add update
+-	 * the cache.
+-	 */
+-	debug(ap->logopt, MODPREFIX "fetchng export list for %s", name);
+-
+-	exp = rpc_get_exports(name, 10, 0, RPC_CLOSE_NOLINGER);
+-
+-	mapent = NULL;
+-	while (exp) {
+-		if (mapent) {
+-			int len = strlen(mapent) + 1;
+-
+-			len += strlen(name) + 2*(strlen(exp->ex_dir) + 2) + 3;
+-			mapent = realloc(mapent, len);
+-			if (!mapent) {
+-				char *estr;
+-				estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-				logerr(MODPREFIX "malloc: %s", estr);
+-				rpc_exports_free(exp);
+-				return NSS_STATUS_UNAVAIL;
+-			}
+-			strcat(mapent, " \"");
+-			strcat(mapent, exp->ex_dir);
+-			strcat(mapent, "\"");
+-		} else {
+-			int len = 2*(strlen(exp->ex_dir) + 2) + strlen(name) + 3;
+-
+-			mapent = malloc(len);
+-			if (!mapent) {
+-				char *estr;
+-				estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-				logerr(MODPREFIX "malloc: %s", estr);
+-				rpc_exports_free(exp);
+-				return NSS_STATUS_UNAVAIL;
+-			}
+-			strcpy(mapent, "\"");
+-			strcat(mapent, exp->ex_dir);
+-			strcat(mapent, "\"");
+-		}
+-		strcat(mapent, " \"");
+-		strcat(mapent, name);
+-		strcat(mapent, ":");
+-		strcat(mapent, exp->ex_dir);
+-		strcat(mapent, "\"");
+-
+-		exp = exp->ex_next;
+-	}
+-	rpc_exports_free(exp);
+-
+-	/* Exports lookup failed so we're outa here */
+-	if (!mapent) {
+-		error(ap->logopt, "exports lookup failed for %s", name);
+-		return NSS_STATUS_UNAVAIL;
+-	}
+-
+ 	debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);
+ 
+-	cache_writelock(mc);
+-	cache_update(mc, source, name, mapent, now);
+-	cache_unlock(mc);
+-
+-	master_source_current_wait(ap->entry);
+-	ap->entry->current = source;
+-
+-	ret = ctxt->parse->parse_mount(ap, name, name_len,
+-				 mapent, ctxt->parse->context);
+-	free(mapent);
++	if (!mapent) {
++		/* We need to get the exports list and update the cache. */
++		mapent = get_exports(ap, name);
+ 
+-	if (ret) {
+-		time_t now = time(NULL);
+-		int rv = CHE_OK;
++		/* Exports lookup failed so we're outa here */
++		if (!mapent)
++			return NSS_STATUS_UNAVAIL;
+ 
+ 		cache_writelock(mc);
+-		me = cache_lookup_distinct(mc, name);
+-		if (!me)
+-			rv = cache_update(mc, source, name, NULL, now);
+-		if (rv != CHE_FAIL) {
+-			me = cache_lookup_distinct(mc, name);
+-			me->status = now + ap->negative_timeout;
+-		}
++		cache_update(mc, source, name, mapent, now);
+ 		cache_unlock(mc);
+-		return NSS_STATUS_TRYAGAIN;
+ 	}
+ 
+-	return NSS_STATUS_SUCCESS;
++	ret = do_parse_mount(ap, name, name_len, mapent, ctxt->parse->context);
++
++	free(mapent);
++
++	return ret;
+ }
+ 
+ int lookup_done(void *context)
diff --git a/autofs-5.0.6-remove-cache-update-from-parse_mount.patch b/autofs-5.0.6-remove-cache-update-from-parse_mount.patch
new file mode 100644
index 0000000..3024b84
--- /dev/null
+++ b/autofs-5.0.6-remove-cache-update-from-parse_mount.patch
@@ -0,0 +1,47 @@
+autofs-5.0.6 - remove cache update from parse_mount()
+
+From: Ian Kent <ikent at redhat.com>
+
+I'm not sure why I added this update in the parse sun module.
+
+The lookup modules have the job of updating the map entry cache and
+I can't see why an entry would be missing since the parse function
+is called following the entry lookup (which does the update).
+---
+
+ modules/parse_sun.c |   23 -----------------------
+ 1 file changed, 23 deletions(-)
+
+
+--- autofs-5.0.6.orig/modules/parse_sun.c
++++ autofs-5.0.6/modules/parse_sun.c
+@@ -1383,29 +1383,6 @@ int parse_mount(struct autofs_point *ap,
+ 			strcat(m_root, name);
+ 		}
+ 
+-		/*
+-		 * Can't take the write lock for direct mount entries here
+-		 * but they should always be present in the map entry cache.
+-		 */
+-		if (ap->type == LKP_INDIRECT) {
+-			cache_writelock(mc);
+-			me = cache_lookup_distinct(mc, name);
+-			if (!me) {
+-				int ret;
+-				/*
+-				 * Not in the cache, perhaps it's a program map
+-				 * or one that doesn't support enumeration.
+-				 */
+-				ret = cache_add(mc, source, name, mapent, age);
+-				if (ret == CHE_FAIL) {
+-					cache_unlock(mc);
+-					free(options);
+-					return 1;
+-				}
+-			}
+-			cache_unlock(mc);
+-		}
+-
+ 		cache_readlock(mc);
+ 		me = cache_lookup_distinct(mc, name);
+ 		if (me) {
diff --git a/autofs-5.0.6-remove-move-mount-code-and-configure-option.patch b/autofs-5.0.6-remove-move-mount-code-and-configure-option.patch
new file mode 100644
index 0000000..16113b2
--- /dev/null
+++ b/autofs-5.0.6-remove-move-mount-code-and-configure-option.patch
@@ -0,0 +1,421 @@
+autofs-5.0.6 - remove move mount code and configure option
+
+From: Ian Kent <ikent at redhat.com>
+
+The code to construct a multi-mount tree in a temporary location and then
+move it into place is obsolete when using a kernel which includes the
+vfs-automount infrastructure.
+
+It is incompatible with systemd and cannot be used if systemd is being used.
+
+So it's being removed.
+---
+
+ autofs.spec         |    2 
+ configure           |   18 ----
+ configure.in        |   10 --
+ daemon/automount.c  |    5 -
+ include/config.h.in |    3 
+ modules/parse_sun.c |  195 +---------------------------------------------------
+ 6 files changed, 7 insertions(+), 226 deletions(-)
+
+
+--- autofs-5.0.6.orig/autofs.spec
++++ autofs-5.0.6/autofs.spec
+@@ -74,7 +74,7 @@ echo %{version}-%{release} > .version
+ %endif
+ 
+ %build
+-CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc --disable-mount-move %{?systemd_configure_arg:}
++CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc %{?systemd_configure_arg:}
+ CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1
+ 
+ %install
+--- autofs-5.0.6.orig/configure
++++ autofs-5.0.6/configure
+@@ -719,7 +719,6 @@ with_openldap
+ with_sasl
+ enable_ext_env
+ enable_mount_locking
+-enable_mount_move
+ enable_forced_shutdown
+ enable_ignore_busy
+ '
+@@ -1343,7 +1342,6 @@ Optional Features:
+   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+   --disable-ext-env	  disable search in environment for substitution variable
+   --disable-mount-locking disable use of locking when spawning mount command
+-  --disable-mount-move    disable use of mount move when when preparing tree of mounts
+   --enable-force-shutdown enable USR1 signal to force unlink umount of any
+ 			  busy mounts during shutdown
+   --enable-ignore-busy	  enable exit without umounting busy mounts during
+@@ -5447,22 +5445,6 @@ $as_echo "#define ENABLE_MOUNT_LOCKING 1
+ 
+ fi
+ 
+-#
+-# Disable use of mount move
+-#
+-# Check whether --enable-mount-move was given.
+-if test "${enable_mount_move+set}" = set; then :
+-  enableval=$enable_mount_move;
+-else
+-  enableval=yes
+-fi
+-
+-if test x$enable_mount_move = xyes -o x$enableval = xyes; then
+-
+-$as_echo "#define ENABLE_MOUNT_MOVE 1" >>confdefs.h
+-
+-fi
+-
+ #
+ # Enable forced shutdown on USR1 signal (unlink umounts all mounts).
+ #
+--- autofs-5.0.6.orig/configure.in
++++ autofs-5.0.6/configure.in
+@@ -338,16 +338,6 @@ if test x$enable_mount_locking = xyes -o
+ fi
+ 
+ #
+-# Disable use of mount move
+-#
+-AC_ARG_ENABLE(mount-move,
+-[  --disable-mount-move    disable use of mount move when when preparing tree of mounts],,
+-	enableval=yes)
+-if test x$enable_mount_move = xyes -o x$enableval = xyes; then
+-	AC_DEFINE(ENABLE_MOUNT_MOVE, 1, [Disable use of mount move when preparing tree of mounts])
+-fi
+-
+-#
+ # Enable forced shutdown on USR1 signal (unlink umounts all mounts).
+ #
+ AC_ARG_ENABLE(forced-shutdown,
+--- autofs-5.0.6.orig/daemon/automount.c
++++ autofs-5.0.6/daemon/automount.c
+@@ -1748,11 +1748,6 @@ static void show_build_info(void)
+ 	count = 22;
+ #endif
+ 
+-#ifndef ENABLE_MOUNT_MOVE
+-	printf("DISABLE_MOUNT_MOVE ");
+-	count = count + 19;
+-#endif
+-
+ #ifdef ENABLE_FORCED_SHUTDOWN
+ 	printf("ENABLE_FORCED_SHUTDOWN ");
+ 	count = count + 23;
+--- autofs-5.0.6.orig/include/config.h.in
++++ autofs-5.0.6/include/config.h.in
+@@ -12,9 +12,6 @@
+ /* Disable use of locking when spawning mount command */
+ #undef ENABLE_MOUNT_LOCKING
+ 
+-/* Disable use of mount move when preparing tree of mounts */
+-#undef ENABLE_MOUNT_MOVE
+-
+ /* define if you have E2FSCK */
+ #undef HAVE_E2FSCK
+ 
+--- autofs-5.0.6.orig/modules/parse_sun.c
++++ autofs-5.0.6/modules/parse_sun.c
+@@ -37,10 +37,6 @@
+ 
+ #define MODPREFIX "parse(sun): "
+ 
+-#define MOUNT_MOVE_NONE		0x00
+-#define MOUNT_MOVE_AUTOFS	0x01
+-#define MOUNT_MOVE_OTHER	0x02
+-
+ int parse_version = AUTOFS_PARSE_VERSION;	/* Required by protocol */
+ 
+ static struct mount_mod *mount_nfs = NULL;
+@@ -1047,86 +1043,6 @@ static int parse_mapent(const char *ent,
+ 	return (p - ent);
+ }
+ 
+-#ifdef ENABLE_MOUNT_MOVE
+-static int move_mount(struct autofs_point *ap,
+-		      const char *mm_tmp_root, const char *mm_root,
+-		      unsigned int move)
+-{
+-	char buf[MAX_ERR_BUF];
+-	int err;
+-
+-	if (move == MOUNT_MOVE_NONE)
+-		return 1;
+-
+-	err = mkdir_path(mm_root, 0555);
+-	if (err < 0 && errno != EEXIST) {
+-		error(ap->logopt,
+-		      "failed to create move target mount point %s", mm_root);
+-		return 0;
+-	}
+-
+-	if (move == MOUNT_MOVE_AUTOFS)
+-		err = mount(mm_tmp_root, mm_root, NULL, MS_MOVE, NULL);
+-	else
+-		err = spawn_mount(ap->logopt,
+-				  "--move", mm_tmp_root, mm_root, NULL);
+-	if (err) {
+-		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+-		error(ap->logopt,
+-		      "failed to move mount from %s to %s: %s",
+-		      mm_tmp_root, mm_root, estr);
+-		return 0;
+-	}
+-
+-	debug(ap->logopt,
+-	      "moved mount tree from %s to %s", mm_tmp_root, mm_root);
+-
+-	return 1;
+-}
+-#endif
+-
+-static void cleanup_multi_root(struct autofs_point *ap, const char *root,
+-					 const char *path, unsigned int move)
+-{
+-	if (move == MOUNT_MOVE_NONE)
+-		return;
+-
+-	if (move == MOUNT_MOVE_OTHER)
+-		spawn_umount(ap->logopt, root, NULL);
+-	else {
+-		struct ioctl_ops *ops = get_ioctl_ops();
+-		struct autofs_point *submount;
+-
+-		mounts_mutex_lock(ap);
+-		submount = __master_find_submount(ap, path);
+-		if (!submount) {
+-			mounts_mutex_unlock(ap);
+-			return;
+-		}
+-
+-		alarm_delete(submount);
+-		st_remove_tasks(submount);
+-		st_wait_state(submount, ST_READY);
+-
+-		submount->parent->submnt_count--;
+-		list_del_init(&submount->mounts);
+-
+-		ops->catatonic(submount->logopt, submount->ioctlfd);
+-
+-		mounts_mutex_unlock(ap);
+-
+-		if (submount->thid) {
+-			pthread_cancel(submount->thid);
+-			close_mount_fds(submount);
+-			umount(root);
+-			destroy_logpri_fifo(submount);
+-			master_free_mapent_sources(submount->entry, 1);
+-			master_free_mapent(ap->entry);
+-		}
+-	}
+-	return;
+-}
+-
+ static void cleanup_multi_triggers(struct autofs_point *ap,
+ 			    struct mapent *me, const char *root, int start,
+ 			    const char *base)
+@@ -1166,49 +1082,15 @@ static void cleanup_multi_triggers(struc
+ 	return;
+ }
+ 
+-#ifdef ENABLE_MOUNT_MOVE
+-static int check_fstype_autofs_option(const char *options)
+-{
+-	char *tok, *tokbuf;
+-	int found;
+-
+-	/*
+-	 * Look for fstype= in options and return true if
+-	 * the last occurrence is fstype=autofs.
+-	 */
+-	found = 0;
+-	tokbuf = alloca(strlen(options) + 2);
+-	strcpy(tokbuf, options);
+-	tok = strtok_r(tokbuf, ",", &tokbuf);
+-	if (tok) {
+-		do {
+-			if (strstr(tok, "fstype=")) {
+-				if (strstr(tok, "autofs"))
+-					found = 1;
+-				else
+-					found = 0;
+-			}
+-		} while ((tok = strtok_r(NULL, ",", &tokbuf)));
+-	}
+-
+-	return found;
+-}
+-#endif
+-
+ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
+ 			 const char *name, char *loc, char *options, void *ctxt)
+ {
+ 	struct mapent *mm;
+ 	struct mapent *ro;
+ 	char *mm_root, *mm_base, *mm_key;
+-	const char *mnt_root, *target;
++	const char *mnt_root;
+ 	unsigned int mm_root_len, mnt_root_len;
+ 	int start, ret = 0, rv;
+-	unsigned int move = MOUNT_MOVE_NONE;
+-#ifdef ENABLE_MOUNT_MOVE
+-	char t_dir[] = "/tmp/autoXXXXXX";
+-	char *mnt_tmp_root = NULL;
+-#endif
+ 
+ 	rv = 0;
+ 
+@@ -1227,26 +1109,12 @@ static int mount_subtree(struct autofs_p
+ 	}
+ 	mm_root_len = strlen(mm_root);
+ 
+-#ifndef ENABLE_MOUNT_MOVE
+ 	mnt_root = mm_root;
+ 	mnt_root_len = mm_root_len;
+-#else
+-	if (ap->flags & MOUNT_FLAG_REMOUNT) {
+-		mnt_root = mm_root;
+-		mnt_root_len = mm_root_len;
+-	} else {
+-		mnt_root = mkdtemp(t_dir);
+-		if (!mnt_root)
+-			return 1;
+-		mnt_root_len = strlen(mnt_root);
+-		mnt_tmp_root = (char *) mnt_root;
+-	}
+-#endif
+ 
+ 	if (me == me->multi) {
+ 		/* name = NULL */
+ 		/* destination = mm_root */
+-		target = mm_root;
+ 		mm_base = "/";
+ 
+ 		/* Mount root offset if it exists */
+@@ -1263,18 +1131,10 @@ static int mount_subtree(struct autofs_p
+ 				warn(ap->logopt,
+ 				      MODPREFIX "failed to parse root offset");
+ 				cache_delete_offset_list(me->mc, name);
+-				goto error_out;
++				return 1;
+ 			}
+ 			ro_len = strlen(ro_loc);
+ 
+-#ifdef ENABLE_MOUNT_MOVE
+-			if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
+-				move = MOUNT_MOVE_OTHER;
+-				if (check_fstype_autofs_option(myoptions))
+-					move = MOUNT_MOVE_AUTOFS;
+-			}
+-#endif
+-
+ 			tmp = alloca(mnt_root_len + 1);
+ 			strcpy(tmp, mnt_root);
+ 			tmp[mnt_root_len] = '/';
+@@ -1293,44 +1153,25 @@ static int mount_subtree(struct autofs_p
+ 				error(ap->logopt, MODPREFIX
+ 					 "failed to mount offset triggers");
+ 				cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
+-				cleanup_multi_root(ap, mnt_root, mm_root, move);
+-				goto error_out;
++				return 1;
+ 			}
+ 		} else if (rv <= 0) {
+-#ifdef ENABLE_MOUNT_MOVE
+-			move = MOUNT_MOVE_NONE;
+-#endif
+ 			ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
+ 			if (ret == -1) {
+ 				error(ap->logopt, MODPREFIX
+ 					 "failed to mount offset triggers");
+ 				cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+-				goto error_out;
++				return 1;
+ 			}
+ 		}
+ 	} else {
+ 		int loclen = strlen(loc);
+ 		int namelen = strlen(name);
+ 
+-#ifndef ENABLE_MOUNT_MOVE
+-		/*
+-		 * When using move mount to mount offsets or direct mounts
+-		 * the base of the tree can be the base of the temporary
+-		 * mount point it needs to be the full path when not moving
+-		 * the mount after construction.
+-		 */
+ 		mnt_root = name;
+-#else
+-		if (!(ap->flags & MOUNT_FLAG_REMOUNT)) {
+-			move = MOUNT_MOVE_OTHER;
+-			if (check_fstype_autofs_option(options))
+-				move = MOUNT_MOVE_AUTOFS;
+-		}
+-#endif
+ 
+ 		/* name = mm_root + mm_base */
+ 		/* destination = mm_root + mm_base = name */
+-		target = name;
+ 		mm_base = &me->key[start];
+ 
+ 		rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt);
+@@ -1340,16 +1181,11 @@ static int mount_subtree(struct autofs_p
+ 				error(ap->logopt, MODPREFIX
+ 					 "failed to mount offset triggers");
+ 				cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
+-				cleanup_multi_root(ap, mnt_root, mm_root, move);
+-				goto error_out;
++				return 1;
+ 			}
+ 		} else if (rv < 0) {
+ 			char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
+ 	
+-#ifdef ENABLE_MOUNT_MOVE
+-			move = MOUNT_MOVE_NONE;
+-#endif
+-
+ 			strcpy(mm_root_base, mm_root);
+ 			strcat(mm_root_base, mm_base);
+ 
+@@ -1358,22 +1194,11 @@ static int mount_subtree(struct autofs_p
+ 				error(ap->logopt, MODPREFIX
+ 					 "failed to mount offset triggers");
+ 				cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+-				goto error_out;
++				return 1;
+ 			}
+ 		}
+ 	}
+ 
+-#ifdef ENABLE_MOUNT_MOVE
+-	if (!move_mount(ap, mnt_root, target, move)) {
+-		cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
+-		cleanup_multi_root(ap, mnt_root, mm_root, move);
+-		goto error_out;
+-	}
+-
+-	if (mnt_tmp_root)
+-		rmdir(mnt_tmp_root);
+-#endif
+-
+ 	/* Mount for base of tree failed */
+ 	if (rv > 0)
+ 		return rv;
+@@ -1386,14 +1211,6 @@ static int mount_subtree(struct autofs_p
+ 		rv = 0;
+ 
+ 	return rv;
+-
+-error_out:
+-#ifdef ENABLE_MOUNT_MOVE
+-	if (mnt_tmp_root)
+-		rmdir(mnt_tmp_root);
+-#endif
+-
+-	return 1;
+ }
+ 
+ /*
diff --git a/autofs-5.0.6-report-map-not-read-when-debug-logging.patch b/autofs-5.0.6-report-map-not-read-when-debug-logging.patch
new file mode 100644
index 0000000..8c14346
--- /dev/null
+++ b/autofs-5.0.6-report-map-not-read-when-debug-logging.patch
@@ -0,0 +1,99 @@
+autofs-5.0.6 - report map not read when debug logging
+
+From: Ian Kent <ikent at redhat.com>
+
+When a map read is called automount will report that is is reading the
+map when debug logging is set. If a map read is not actually needed the
+lookup module read map function should also report that it didn't need
+to read the map.
+---
+
+ CHANGELOG                |    1 +
+ modules/lookup_hosts.c   |    4 +++-
+ modules/lookup_ldap.c    |    4 +++-
+ modules/lookup_nisplus.c |    4 +++-
+ modules/lookup_sss.c     |    4 +++-
+ modules/lookup_yp.c      |    4 +++-
+ 6 files changed, 16 insertions(+), 5 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -42,6 +42,7 @@
+ - fix configure string length tests for sss library.
+ - fix initialization in rpc create_client().
+ - fix libtirpc name clash.
++- report map not read when debug logging.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/modules/lookup_hosts.c
++++ autofs-5.0.6/modules/lookup_hosts.c
+@@ -94,8 +94,10 @@ int lookup_read_map(struct autofs_point
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+-	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
++	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
++		debug(ap->logopt, "map read not needed, so not done");
+ 		return NSS_STATUS_SUCCESS;
++	}
+ 
+ 	mc = source->mc;
+ 
+--- autofs-5.0.6.orig/modules/lookup_ldap.c
++++ autofs-5.0.6/modules/lookup_ldap.c
+@@ -2326,8 +2326,10 @@ static int read_one_map(struct autofs_po
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+-	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
++	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
++		debug(ap->logopt, "map read not needed, so not done");
+ 		return NSS_STATUS_SUCCESS;
++	}
+ 
+ 	sp.ap = ap;
+ 	sp.age = age;
+--- autofs-5.0.6.orig/modules/lookup_nisplus.c
++++ autofs-5.0.6/modules/lookup_nisplus.c
+@@ -185,8 +185,10 @@ int lookup_read_map(struct autofs_point
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+-	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
++	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
++		debug(ap->logopt, "map read not needed, so not done");
+ 		return NSS_STATUS_SUCCESS;
++	}
+ 
+ 	mc = source->mc;
+ 
+--- autofs-5.0.6.orig/modules/lookup_sss.c
++++ autofs-5.0.6/modules/lookup_sss.c
+@@ -275,8 +275,10 @@ int lookup_read_map(struct autofs_point
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+-	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
++	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
++		debug(ap->logopt, "map read not needed, so not done");
+ 		return NSS_STATUS_SUCCESS;
++	}
+ 
+ 	if (!setautomntent(ap->logopt, ctxt, ctxt->mapname, &sss_ctxt))
+ 		return NSS_STATUS_UNAVAIL;
+--- autofs-5.0.6.orig/modules/lookup_yp.c
++++ autofs-5.0.6/modules/lookup_yp.c
+@@ -327,8 +327,10 @@ int lookup_read_map(struct autofs_point
+ 	 * reading the map. We always need to read the whole map for
+ 	 * direct mounts in order to mount the triggers.
+ 	 */
+-	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
++	if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) {
++		debug(ap->logopt, "map read not needed, so not done");
+ 		return NSS_STATUS_SUCCESS;
++	}
+ 
+ 	ypcb_data.ap = ap;
+ 	ypcb_data.source = source;
diff --git a/autofs-5.0.6-update-timeout-function-to-not-return-timeout.patch b/autofs-5.0.6-update-timeout-function-to-not-return-timeout.patch
new file mode 100644
index 0000000..d5f8a37
--- /dev/null
+++ b/autofs-5.0.6-update-timeout-function-to-not-return-timeout.patch
@@ -0,0 +1,171 @@
+autofs-5.0.6 - update ->timeout() function to not return timeout
+
+From: Ian Kent <ikent at redhat.com>
+
+The value returned by the ->timeout() autofs control interface
+function is not used so make that usage explict by not using a
+pass by address parameter. This saves having to take care to
+always use a temporary storage location when using the function.
+---
+
+ CHANGELOG               |    1 +
+ daemon/direct.c         |    6 +++---
+ daemon/indirect.c       |    2 +-
+ include/dev-ioctl-lib.h |    2 +-
+ lib/dev-ioctl-lib.c     |   15 +++++++--------
+ lib/master_parse.y      |    3 +--
+ lib/mounts.c            |    4 ++--
+ 7 files changed, 16 insertions(+), 17 deletions(-)
+
+
+--- autofs-5.0.6.orig/CHANGELOG
++++ autofs-5.0.6/CHANGELOG
+@@ -44,6 +44,7 @@
+ - fix libtirpc name clash.
+ - report map not read when debug logging.
+ - duplicate parent options for included maps.
++- update ->timeout() function to not return timeout.
+ 
+ 28/06/2011 autofs-5.0.6
+ -----------------------
+--- autofs-5.0.6.orig/daemon/direct.c
++++ autofs-5.0.6/daemon/direct.c
+@@ -302,7 +302,7 @@ static int unlink_active_mounts(struct a
+ 				return 0;
+ 			}
+ 
+-			ops->timeout(ap->logopt, ioctlfd, &tout);
++			ops->timeout(ap->logopt, ioctlfd, tout);
+ 
+ 			if (save_ioctlfd == -1)
+ 				ops->close(ap->logopt, ioctlfd);
+@@ -424,7 +424,7 @@ int do_mount_autofs_direct(struct autofs
+ 		goto out_umount;
+ 	}
+ 
+-	ops->timeout(ap->logopt, ioctlfd, &timeout);
++	ops->timeout(ap->logopt, ioctlfd, timeout);
+ 	notify_mount_result(ap, me->key, str_direct);
+ 	cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ 	ops->close(ap->logopt, ioctlfd);
+@@ -771,7 +771,7 @@ int mount_autofs_offset(struct autofs_po
+ 		goto out_umount;
+ 	}
+ 
+-	ops->timeout(ap->logopt, ioctlfd, &timeout);
++	ops->timeout(ap->logopt, ioctlfd, timeout);
+ 	cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ 	if (ap->logopt & LOGOPT_DEBUG)
+ 		notify_mount_result(ap, mountpoint, str_offset);
+--- autofs-5.0.6.orig/daemon/indirect.c
++++ autofs-5.0.6/daemon/indirect.c
+@@ -172,7 +172,7 @@ static int do_mount_autofs_indirect(stru
+ 	ap->dev = st.st_dev;	/* Device number for mount point checks */
+ 	ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ 
+-	ops->timeout(ap->logopt, ap->ioctlfd, &timeout);
++	ops->timeout(ap->logopt, ap->ioctlfd, timeout);
+ 	if (ap->logopt & LOGOPT_DEBUG)
+ 		notify_mount_result(ap, root, str_indirect);
+ 	else
+--- autofs-5.0.6.orig/include/dev-ioctl-lib.h
++++ autofs-5.0.6/include/dev-ioctl-lib.h
+@@ -45,7 +45,7 @@ struct ioctl_ops {
+ 	int (*send_fail)(unsigned int, int, unsigned int, int);
+ 	int (*setpipefd)(unsigned int, int, int);
+ 	int (*catatonic)(unsigned int, int);
+-	int (*timeout)(unsigned int, int, time_t *);
++	int (*timeout)(unsigned int, int, time_t);
+ 	int (*requestor)(unsigned int, int, const char *, uid_t *, gid_t *);
+ 	int (*expire)(unsigned int, int, const char *, unsigned int);
+ 	int (*askumount)(unsigned int, int, unsigned int *);
+--- autofs-5.0.6.orig/lib/dev-ioctl-lib.c
++++ autofs-5.0.6/lib/dev-ioctl-lib.c
+@@ -55,7 +55,7 @@ static int dev_ioctl_send_ready(unsigned
+ static int dev_ioctl_send_fail(unsigned int, int, unsigned int, int);
+ static int dev_ioctl_setpipefd(unsigned int, int, int);
+ static int dev_ioctl_catatonic(unsigned int, int);
+-static int dev_ioctl_timeout(unsigned int, int, time_t *);
++static int dev_ioctl_timeout(unsigned int, int, time_t);
+ static int dev_ioctl_requestor(unsigned int, int, const char *, uid_t *, gid_t *);
+ static int dev_ioctl_expire(unsigned int, int, const char *, unsigned int);
+ static int dev_ioctl_askumount(unsigned int, int, unsigned int *);
+@@ -69,7 +69,7 @@ static int ioctl_close(unsigned int, int
+ static int ioctl_send_ready(unsigned int, int, unsigned int);
+ static int ioctl_send_fail(unsigned int, int, unsigned int, int);
+ static int ioctl_catatonic(unsigned int, int);
+-static int ioctl_timeout(unsigned int, int, time_t *);
++static int ioctl_timeout(unsigned int, int, time_t);
+ static int ioctl_expire(unsigned int, int, const char *, unsigned int);
+ static int ioctl_askumount(unsigned int, int, unsigned int *);
+ 
+@@ -577,25 +577,24 @@ static int ioctl_catatonic(unsigned int
+ }
+ 
+ /* Set the autofs mount timeout */
+-static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
++static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout)
+ {
+ 	struct autofs_dev_ioctl param;
+ 
+ 	init_autofs_dev_ioctl(&param);
+ 	param.ioctlfd = ioctlfd;
+-	param.timeout.timeout = *timeout;
++	param.timeout.timeout = timeout;
+ 
+ 	if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, &param) == -1)
+ 		return -1;
+ 
+-	*timeout = param.timeout.timeout;
+-
+ 	return 0;
+ }
+ 
+-static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t *timeout)
++static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout)
+ {
+-	return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, timeout);
++	time_t tout = timeout;
++	return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout);
+ }
+ 
+ /*
+--- autofs-5.0.6.orig/lib/master_parse.y
++++ autofs-5.0.6/lib/master_parse.y
+@@ -801,7 +801,6 @@ int master_parse_entry(const char *buffe
+ 	} else {
+ 		struct ioctl_ops *ops = get_ioctl_ops();
+ 		struct autofs_point *ap = entry->ap;
+-		time_t tout = timeout;
+ 
+ 		/*
+ 		 * Second and subsequent instances of a mount point
+@@ -811,7 +810,7 @@ int master_parse_entry(const char *buffe
+ 			ap->exp_timeout = timeout;
+ 			ap->exp_runfreq = (ap->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO;
+ 			if (ap->ioctlfd != -1 && ap->type == LKP_INDIRECT)
+-				ops->timeout(ap->logopt, ap->ioctlfd, &tout);
++				ops->timeout(ap->logopt, ap->ioctlfd, timeout);
+ 		}
+ 	}
+ 	if (random_selection)
+--- autofs-5.0.6.orig/lib/mounts.c
++++ autofs-5.0.6/lib/mounts.c
+@@ -1404,7 +1404,7 @@ static int remount_active_mount(struct a
+ 
+ 	/* Re-reading the map, set timeout and return */
+ 	if (ap->state == ST_READMAP) {
+-		ops->timeout(ap->logopt, fd, &timeout);
++		ops->timeout(ap->logopt, fd, timeout);
+ 		ops->close(ap->logopt, fd);
+ 		return REMOUNT_READ_MAP;
+ 	}
+@@ -1426,7 +1426,7 @@ static int remount_active_mount(struct a
+ 		ops->close(ap->logopt, fd);
+ 		return REMOUNT_OPEN_FAIL;
+ 	}
+-	ops->timeout(ap->logopt, fd, &timeout);
++	ops->timeout(ap->logopt, fd, timeout);
+ 	if (fstat(fd, &st) == -1) {
+ 		error(ap->logopt,
+ 		      "failed to stat %s mount %s", str_type, path);


More information about the scm-commits mailing list