[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(¶m);
+ param.ioctlfd = ioctlfd;
+- param.timeout.timeout = *timeout;
++ param.timeout.timeout = timeout;
+
+ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -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