diff --git a/.autofs.metadata b/.autofs.metadata new file mode 100644 index 0000000..37e6984 --- /dev/null +++ b/.autofs.metadata @@ -0,0 +1 @@ +086c327711a7f76692c582264c0742842f3570ba SOURCES/autofs-5.1.7-2.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4976a25 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/autofs-5.1.7-2.tar.gz diff --git a/SOURCES/autofs-5.1.7-Fix-option-for-master_read_wait.patch b/SOURCES/autofs-5.1.7-Fix-option-for-master_read_wait.patch new file mode 100644 index 0000000..2cd873b --- /dev/null +++ b/SOURCES/autofs-5.1.7-Fix-option-for-master_read_wait.patch @@ -0,0 +1,48 @@ +autofs-5.1.7 - Fix option for master read wait + +From: Goldwyn Rodrigues + +The master-wait program option expects a value, and if provided +automount crashes with the following trace: + +#0 __GI_____strtoul_l_internal (nptr=0x0, endptr=0x7fffffffe120, base=0, group=, + loc=0x7ffff77a63a0 <_nl_global_locale>) at ../stdlib/strtol_l.c:292 +#1 0x0000555555562c52 in getnumopt () +#2 0x0000555555564ec0 in main () + +This is because the options string is not correct and does not expect +an argument for master-wait (M), which sets optarg to NULL. + +Fixes: e68f07f ("autofs-5.1.2 - add master read wait option") +Signed-off-by: Goldwyn Rodrigues +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index fe49740e..0b577909 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -4,6 +4,7 @@ + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. ++- Fix option for master read wait. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index e476f6b2..7fa92877 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2274,7 +2274,7 @@ int main(int argc, char *argv[]) + time_t timeout; + time_t age = monotonic_time(NULL); + struct rlimit rlim; +- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM"; ++ const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"pid-file", 1, 0, 'p'}, diff --git a/SOURCES/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch b/SOURCES/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch new file mode 100644 index 0000000..85c745b --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch @@ -0,0 +1,136 @@ +autofs-5.1.7 - add a len field to struct autofs_point + +From: Ian Kent + +Add a path length field to struct autofs_point since the path length +is needed at various times avoiding additional strlen() calls. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 2 +- + daemon/master.c | 1 + + include/automount.h | 1 + + lib/mounts.c | 6 +++--- + modules/parse_amd.c | 4 ++-- + modules/parse_sun.c | 4 ++-- + 7 files changed, 11 insertions(+), 8 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 60924b3f..0dae6761 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -30,6 +30,7 @@ + - rename tree implementation functions. + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). ++- add a len field to struct autofs_point. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 8c9a82b5..5116b927 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap, + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2); ++ m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +diff --git a/daemon/master.c b/daemon/master.c +index da527a61..022fb9dd 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -86,6 +86,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + free(ap); + return 0; + } ++ ap->len = strlen(ap->path); + ap->pref = NULL; + + ap->entry = entry; +diff --git a/include/automount.h b/include/automount.h +index e917515b..34485859 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -548,6 +548,7 @@ struct kernel_mod_version { + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ ++ size_t len; /* Length of mount point name */ + mode_t mode; /* Mount point mode */ + char *pref; /* amd prefix */ + int pipefd; /* File descriptor for pipe */ +diff --git a/lib/mounts.c b/lib/mounts.c +index f6f20fc0..b478ecb4 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + if (!mp) + goto fail; + } else { +- int len = strlen(ap->path) + strlen(name) + 2; ++ int len = ap->len + strlen(name) + 2; + + mp = malloc(len); + if (!mp) +@@ -2495,9 +2495,9 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + dir = strdup(oe->key); + + if (ap->flags & MOUNT_FLAG_GHOST) +- split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1; ++ split = ap->len + strlen(MM_ROOT(oe)->key) + 1; + else +- split = strlen(ap->path); ++ split = ap->len; + + dir[split] = '\0'; + path = &dir[split + 1]; +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index d3e8a450..5a9079d6 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap, + struct mapent *me; + int len; + +- len = strlen(ap->path) + 1 + key_len + 1; ++ len = ap->len + 1 + key_len + 1; + if (len > PATH_MAX) { + error(ap->logopt, MODPREFIX + "error: lookup key is greater than PATH_MAX"); +@@ -1319,7 +1319,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + char *target; + size_t len; + +- len = strlen(ap->path) + strlen(entry->rhost) + 2; ++ len = ap->len + strlen(entry->rhost) + 2; + target = malloc(len); + if (!target) { + warn(ap->logopt, MODPREFIX +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index b11c6693..b1f64ca0 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1154,7 +1154,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + mm_root = mm_key; + start = strlen(mm_key); + } else { +- start = strlen(ap->path) + strlen(mm_key) + 1; ++ start = ap->len + strlen(mm_key) + 1; + mm_root = alloca(start + 3); + strcpy(mm_root, ap->path); + strcat(mm_root, "/"); +@@ -1477,7 +1477,7 @@ dont_expand: + } + strcpy(m_root, name); + } else { +- m_root_len = strlen(ap->path) + name_len + 1; ++ m_root_len = ap->len + name_len + 1; + m_root = alloca(m_root_len + 1); + if (!m_root) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); diff --git a/SOURCES/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch b/SOURCES/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch new file mode 100644 index 0000000..ae2b383 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch @@ -0,0 +1,104 @@ +autofs-5.1.7 - add ext_mount_hash_mutex lock helpers + +From: Ian Kent + +Coverity: check_return: Calling "pthread_mutex_lock" without checking + return value. + +Well, I use helpers to do this in many places so can't really disagree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 26 ++++++++++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b1b28888..ff44ac25 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -65,6 +65,7 @@ + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). ++- add ext_mount_hash_mutex lock helpers. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 3996eb5e..c24d1a88 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path) + return mnt_name; + } + ++static void ext_mount_hash_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void ext_mount_hash_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&ext_mount_hash_mutex); ++ if (status) ++ fatal(status); ++} ++ + static struct ext_mount *ext_mount_lookup(const char *mp) + { + uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); +@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, const char *umount) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (em) { +@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, const char *umount) + + ret = 1; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + + em = ext_mount_lookup(path); + if (!em) +@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path) + ret = 1; + } + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + +@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path) + struct ext_mount *em; + int ret = 0; + +- pthread_mutex_lock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_lock(); + em = ext_mount_lookup(path); + if (!em) + goto done; + ret = em->ref; + done: +- pthread_mutex_unlock(&ext_mount_hash_mutex); ++ ext_mount_hash_mutex_unlock(); + return ret; + } + diff --git a/SOURCES/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch b/SOURCES/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch new file mode 100644 index 0000000..264f83a --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch @@ -0,0 +1,42 @@ +autofs-5.1.7 - add length check in umount_subtree_mounts() + +From: Ian Kent + +Coverity: fixed_size_dest: You might overrun the 4097-character + fixed-size string "key" by copying "me->key" without + checking the length. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 224f58d6..9e385ba9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -55,6 +55,7 @@ + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). ++- add length check in umount_subtree_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 48472d5f..70506d83 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + left++; + } + ++ if (me->len > PATH_MAX) { ++ crit(ap->logopt, "me->key too long for buffer"); ++ return 1; ++ } ++ + strcpy(key, me->key); + + cache_unlock(mc); diff --git a/SOURCES/autofs-5.1.7-add-mapent-tree-implementation.patch b/SOURCES/autofs-5.1.7-add-mapent-tree-implementation.patch new file mode 100644 index 0000000..26ea375 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-mapent-tree-implementation.patch @@ -0,0 +1,177 @@ +autofs-5.1.7 - add mapent tree implementation + +From: Ian Kent + +Add a struct mapent basic tree implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 4 ++++ + include/mounts.h | 8 ++++++++ + lib/cache.c | 9 ++++++++- + lib/mounts.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 71 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 74571570..8841f72f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -32,6 +32,7 @@ + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. + - make tree implementation data independent. ++- add mapent tree implementation. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index 34485859..ebc2007f 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -166,10 +166,14 @@ struct mapent { + struct mapent_cache *mc; + struct map_source *source; + /* Need to know owner if we're a multi-mount */ ++ struct tree_node *mm_root; ++ struct tree_node *mm_parent; ++ struct tree_node node; + struct mapent *multi; + /* Parent nesting point within multi-mount */ + struct mapent *parent; + char *key; ++ size_t len; + char *mapent; + struct stack *stack; + time_t age; +diff --git a/include/mounts.h b/include/mounts.h +index 71d29566..fd7c6183 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -66,6 +66,13 @@ struct tree_node { + #define MNT_LIST(n) (container_of(n, struct mnt_list, node)) + #define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) + ++#define MAPENT(n) (container_of(n, struct mapent, node)) ++#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) ++#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) ++#define MAPENT_PARENT(p) ((struct tree_node *) ((struct mapent *) p)->mm_parent) ++#define MAPENT_SET_ROOT(p, r) { (((struct mapent *) p)->mm_root = (struct tree_node *) r); } ++#define MAPENT_SET_PARENT(p, n) { (((struct mapent *) p)->mm_parent = (struct tree_node *) n); } ++ + typedef struct tree_node *(*tree_new_t) (void *ptr); + typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr); + typedef void (*tree_free_t) (struct tree_node *n); +@@ -161,6 +168,7 @@ unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++struct tree_node *tree_mapent_root(struct mapent *me); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/cache.c b/lib/cache.c +index 629c4d0a..6dfaeff5 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + struct mapent *me, *existing = NULL; + char *pkey, *pent; + u_int32_t hashval = hash(key, mc->size); ++ size_t len; + + me = (struct mapent *) malloc(sizeof(struct mapent)); + if (!me) + return CHE_FAIL; + +- pkey = malloc(strlen(key) + 1); ++ len = strlen(key); ++ ++ pkey = malloc(len + 1); + if (!pkey) { + free(me); + return CHE_FAIL; + } + me->key = strcpy(pkey, key); ++ me->len = len; + + if (mapent) { + pent = malloc(strlen(mapent) + 1); +@@ -575,6 +579,9 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + me->status = 0; + me->mc = mc; + me->source = ms; ++ me->mm_root = NULL; ++ me->mm_parent = NULL; ++ INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); + INIT_LIST_HEAD(&me->multi_list); + me->multi = NULL; +diff --git a/lib/mounts.c b/lib/mounts.c +index a6d1c5a7..40ebf9cf 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = { + }; + static struct tree_ops *tree_mnt_ops = &mnt_ops; + ++static struct tree_node *tree_mapent_new(void *ptr); ++static int tree_mapent_cmp(struct tree_node *n, void *ptr); ++static void tree_mapent_free(struct tree_node *n); ++ ++static struct tree_ops mapent_ops = { ++ .new = tree_mapent_new, ++ .cmp = tree_mapent_cmp, ++ .free = tree_mapent_free, ++}; ++static struct tree_ops *tree_mapent_ops = &mapent_ops; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -1431,6 +1442,45 @@ void mnts_put_expire_list(struct list_head *mnts) + mnts_hash_mutex_unlock(); + } + ++struct tree_node *tree_mapent_root(struct mapent *me) ++{ ++ return tree_root(tree_mapent_ops, me); ++} ++ ++static struct tree_node *tree_mapent_new(void *ptr) ++{ ++ struct tree_node *n = MAPENT_NODE(ptr); ++ ++ n->ops = tree_mapent_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_mapent_cmp(struct tree_node *n, void *ptr) ++{ ++ struct mapent *n_me = MAPENT(n); ++ size_t n_me_len = n_me->len; ++ struct mapent *me = ptr; ++ size_t me_len = me->len; ++ ++ if (strncmp(me->key, n_me->key, n_me_len) == 0) { ++ if (me_len < n_me_len) ++ return -1; ++ else if (me_len > n_me_len) ++ return 1; ++ } ++ return strcmp(me->key, n_me->key); ++} ++ ++static void tree_mapent_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/SOURCES/autofs-5.1.7-add-missing-description-of-null-map-option.patch b/SOURCES/autofs-5.1.7-add-missing-description-of-null-map-option.patch new file mode 100644 index 0000000..52d1e78 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-missing-description-of-null-map-option.patch @@ -0,0 +1,51 @@ +autofs-5.1.7 - add missing desciption of null map option + +From: Ian Kent + +The description of how the -null master map option behaves is +mising from auto.master(5). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + man/auto.master.5.in | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -75,6 +75,7 @@ + - fix hosts map offset order. + - fix direct mount deadlock. + - fix lookup_prune_one_cache() refactoring change. ++- add missing description of null map option. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/man/auto.master.5.in ++++ autofs-5.1.7/man/auto.master.5.in +@@ -265,6 +265,25 @@ accessing /net/myserver will mount expor + NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev" options + unless overridden by explicitly specifying the "suid", "dev" options in the + master map entry. ++.SH BUILTIN MAP \-null ++If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent ++master map entry with the given path. ++.P ++It can only be used for paths that appear in the master map (or in direct mount maps). ++.P ++An indirect mount map top level mount point path can be nulled. If so no mounts from ++the nulled mount are performed (essentially it isn't mounted). ++.P ++Direct mount map path entries can be nulled. Since they must be present at startup ++they are (notionally) part of the master map. ++.P ++A nulled master map entry path will ignore a single subsequent matching entry. Any ++matching entry following that will be treated as it normally would be. An example ++use of this is allowing local master map entries to override remote ones. ++.P ++NOTE: If a duplicate master map entry path is seen (excluding paths of null entries) ++it will be ignored and noted in the log, that is the first encountered master map ++entry is used unless there is a corresponding null entry. + .SH LDAP MAPS + If the map type \fBldap\fP is specified the mapname is of the form + \fB[//servername/]dn\fP, where the optional \fBservername\fP is diff --git a/SOURCES/autofs-5.1.7-add-missing-free-in-handle_mounts.patch b/SOURCES/autofs-5.1.7-add-missing-free-in-handle_mounts.patch new file mode 100644 index 0000000..288e200 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-missing-free-in-handle_mounts.patch @@ -0,0 +1,42 @@ +autofs-5.1.7 - add missing free in handle_mounts() + +From: Ian Kent + +Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice + +No it's not, but root isn't freed before the fatal call which crashes +automount so add a free() before the fatal() call. + +It appears Coverity doesn't recognise pthread_exit() as an exit condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 9c3ede45..62a918a9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -50,6 +50,7 @@ + - check for offset with no mount location. + - remove mounts_mutex. + - remove unused variable from get_exports(). ++- add missing free in handle_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 28c4d1ee..48472d5f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1922,6 +1922,8 @@ void *handle_mounts(void *arg) + status = pthread_mutex_lock(&suc->mutex); + if (status) { + logerr("failed to lock startup condition mutex!"); ++ if (root) ++ free(root); + fatal(status); + } + diff --git a/SOURCES/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch b/SOURCES/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch new file mode 100644 index 0000000..ffac797 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-mount-and-umount-offsets-functions.patch @@ -0,0 +1,310 @@ +autofs-5.1.7 - add mount and umount offsets functions + +From: Ian Kent + +Add tree_mapent_mount_offsets() and tree_mapent_umount_offsets() to +the mapent tree handling implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 2 + lib/mounts.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 263 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 0bd6f181..892f7581 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -39,6 +39,7 @@ + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). ++- add mount and umount offsets functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index 5441ee0e..e56f80ba 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -172,6 +172,8 @@ struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); ++int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); ++int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/mounts.c b/lib/mounts.c +index f075a27e..f7c29475 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct mapent *oe) + } + } + ++static int tree_mapent_rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) ++{ ++ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe)); ++ char *dir, *path; ++ unsigned int split; ++ int ret; ++ ++ if (ap->type == LKP_DIRECT) ++ return rmdir_path(ap, oe->key, mm_root->dev); ++ ++ dir = strdup(oe->key); ++ ++ if (ap->flags & MOUNT_FLAG_GHOST) ++ split = ap->len + mm_root->len + 1; ++ else ++ split = ap->len; ++ ++ dir[split] = '\0'; ++ path = &dir[split + 1]; ++ ++ if (chdir(dir) == -1) { ++ error(ap->logopt, "failed to chdir to %s", dir); ++ free(dir); ++ return -1; ++ } ++ ++ ret = rmdir_path(ap, path, ap->dev); ++ ++ free(dir); ++ ++ if (chdir("/") == -1) ++ error(ap->logopt, "failed to chdir to /"); ++ ++ return ret; ++} ++ ++static int tree_mapent_mount_offset(struct mapent *oe, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct autofs_point *ap = ctxt->ap; ++ int ret; ++ ++ debug(ap->logopt, "mount offset %s", oe->key); ++ ++ ret = mount_autofs_offset(ap, oe); ++ if (ret < MOUNT_OFFSET_OK) { ++ if (ret != MOUNT_OFFSET_IGNORE) { ++ warn(ap->logopt, "failed to mount offset"); ++ return 0; ++ } else { ++ debug(ap->logopt, ++ "ignoring \"nohide\" trigger %s", oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ } ++ ++ return 1; ++} ++ ++static int tree_mapent_umount_offset(struct mapent *oe, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct autofs_point *ap = ctxt->ap; ++ int ret = 1; ++ ++ /* ++ * Check for and umount subtree offsets resulting from ++ * nonstrict mount fail. ++ */ ++ ret = tree_mapent_umount_offsets(oe, ctxt->strict); ++ if (!ret) ++ return 0; ++ ++ /* ++ * 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(oe->key, MNTS_REAL)) { ++ if (umount_ent(ap, oe->key) && ++ is_mounted(oe->key, MNTS_REAL)) { ++ debug(ap->logopt, ++ "offset %s has active mount, invalidate", ++ oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ ++ if (oe->mapent) { ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ return 0; ++ } ++ } ++ ++ /* Don't bother if there's noting to umount. */ ++ if (!is_mounted(oe->key, MNTS_AUTOFS)) ++ goto done; ++ ++ debug(ap->logopt, "umount offset %s", oe->key); ++ ++ if (umount_autofs_offset(ap, oe)) { ++ warn(ap->logopt, "failed to umount offset"); ++ ret = 0; ++ } else { ++ struct stat st; ++ int ret; ++ ++ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) ++ goto done; ++ ++ /* ++ * An error due to partial directory removal is ++ * ok so only try and remount the offset if the ++ * actual mount point still exists. ++ */ ++ ret = tree_mapent_rmdir_path_offset(ap, oe); ++ if (ret == -1 && !stat(oe->key, &st)) { ++ ret = tree_mapent_mount_offset(oe, ctxt); ++ /* But we did origianlly create this */ ++ oe->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++ } ++done: ++ return ret; ++} ++ ++static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct mapent *oe = MAPENT(n); ++ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe)); ++ struct autofs_point *ap = ctxt->ap; ++ int ret; ++ ++ if (!oe->mapent) ++ return 1; ++ ++ /* Stale offset, no longer present in the mapent */ ++ if (oe->age != mm_root->age) { ++ /* Best effort */ ++ tree_mapent_umount_offset(oe, ctxt); ++ return 1; ++ } ++ ++ ret = tree_mapent_mount_offset(oe, ctxt); ++ ++ /* ++ * 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(oe->key, MNTS_REAL)) ++ /* Best effort */ ++ tree_mapent_mount_offsets(oe, !ctxt->strict); ++ } ++ ++ return ret; ++} ++ ++int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct traverse_subtree_context ctxt = { ++ .ap = oe->mc->ap, ++ .base = base, ++ .strict = !nonstrict, ++ }; ++ ++ return tree_mapent_traverse_subtree(base, ++ tree_mapent_mount_offsets_work, &ctxt); ++} ++ ++static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *oe = MAPENT(n); ++ ++ return tree_mapent_umount_offset(oe, ptr); ++} ++ ++int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct autofs_point *ap = oe->mc->ap; ++ struct traverse_subtree_context ctxt = { ++ .ap = ap, ++ .base = base, ++ .strict = !nonstrict, ++ }; ++ int ret; ++ ++ ret = tree_mapent_traverse_subtree(base, ++ tree_mapent_umount_offsets_work, &ctxt); ++ if (ret && tree_mapent_is_root(oe)) { ++ char mp[PATH_MAX + 1]; ++ ++ /* ++ * The map entry cache stores mapent keys. For indirect ++ * mount maps they are single direcory components so when ++ * one of these keys is the root of a multi-mount the mount ++ * path must be constructed. ++ */ ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) { ++ error(ap->logopt, "mount path is too long"); ++ return 0; ++ } ++ ++ /* ++ * Special case. ++ * If we can't umount the root container then we can't ++ * delete the offsets from the cache and we need to put ++ * the offset triggers back. ++ */ ++ if (is_mounted(mp, MNTS_REAL)) { ++ info(ap->logopt, "unmounting dir = %s", mp); ++ if (umount_ent(ap, mp) && ++ is_mounted(mp, MNTS_REAL)) { ++ if (!tree_mapent_mount_offsets(oe, 1)) ++ warn(ap->logopt, ++ "failed to remount offset triggers"); ++ return 0; ++ } ++ } ++ ++ /* check for mounted mount entry and remove it if found */ ++ mnts_remove_mount(mp, MNTS_MOUNTED); ++ ++ } ++ ++ return ret; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/SOURCES/autofs-5.1.7-add-set_offset_tree_catatonic.patch b/SOURCES/autofs-5.1.7-add-set_offset_tree_catatonic.patch new file mode 100644 index 0000000..f243d5a --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-set_offset_tree_catatonic.patch @@ -0,0 +1,50 @@ +autofs-5.1.7 - add set_offset_tree_catatonic() + +From: Ian Kent + +Add tree mapent support function set_offset_tree_catatonic(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 15 +++++++++++++++ + 2 files changed, 16 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 89d4cfa0..0bd6f181 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -38,6 +38,7 @@ + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). ++- add set_offset_tree_catatonic(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index ba573b9a..f075a27e 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2578,6 +2578,21 @@ static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int i + return 0; + } + ++static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *me = MAPENT(n); ++ struct autofs_point *ap = me->mc->ap; ++ ++ set_mount_catatonic(ap, me, me->ioctlfd); ++ ++ return 1; ++} ++ ++static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me) ++{ ++ tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL); ++} ++ + static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + { + if (!list_empty(&me->multi_list)) { diff --git a/SOURCES/autofs-5.1.7-add-some-multi-mount-macros.patch b/SOURCES/autofs-5.1.7-add-some-multi-mount-macros.patch new file mode 100644 index 0000000..a0f152e --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-some-multi-mount-macros.patch @@ -0,0 +1,552 @@ +autofs-5.1.7 - add some multi-mount macros + +From: Ian Kent + +Add convienience macros IS_MM() to check is a mapent is part of a +multi-mount, IS_MM_ROOT() to check if a mapent is the root of a +multi-mount tree and MM_ROOT() to return the multi-mount root mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 14 +++++++------- + daemon/direct.c | 6 +++--- + daemon/lookup.c | 10 +++++----- + include/automount.h | 5 +++++ + lib/cache.c | 30 +++++++++++++++--------------- + lib/mounts.c | 14 +++++++------- + modules/lookup_file.c | 4 ++-- + modules/lookup_hosts.c | 4 ++-- + modules/lookup_ldap.c | 4 ++-- + modules/lookup_nisplus.c | 4 ++-- + modules/lookup_program.c | 4 ++-- + modules/lookup_sss.c | 4 ++-- + modules/lookup_yp.c | 4 ++-- + modules/parse_sun.c | 12 ++++++------ + 15 files changed, 63 insertions(+), 57 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 1bf20699..3ba748d7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -28,6 +28,7 @@ + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. ++- add some multi-mount macros. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 62530b6b..f4608fc9 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + + if (me) { + mc = me->mc; +- is_mm_root = (me->multi == me); ++ is_mm_root = IS_MM_ROOT(me); + } + + left = 0; + +- if (me && me->multi) { ++ if (me && IS_MM(me)) { + char root[PATH_MAX + 1]; + char key[PATH_MAX + 1]; + struct mapent *tmp; + int status; + char *base; + +- if (!strchr(me->multi->key, '/')) ++ if (!strchr(MM_ROOT(me)->key, '/')) + /* Indirect multi-mount root */ + /* sprintf okay - if it's mounted, it's + * PATH_MAX or less bytes */ +- sprintf(root, "%s/%s", ap->path, me->multi->key); ++ sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key); + else +- strcpy(root, me->multi->key); ++ strcpy(root, MM_ROOT(me)->key); + +- if (is_mm_root) ++ if (IS_MM_ROOT(me)) + base = NULL; + else + base = me->key + strlen(root); +@@ -588,7 +588,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + return 0; + } + +- if (!left && is_mm_root) { ++ if (!left && IS_MM_ROOT(me)) { + status = cache_delete_offset_list(mc, me->key); + if (status != CHE_OK) { + warn(ap->logopt, "couldn't delete offset list"); +diff --git a/daemon/direct.c b/daemon/direct.c +index 5c1146a7..3f4f5704 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + * a mount that has been automatically mounted by + * the kernel NFS client. + */ +- if (me->multi != me && ++ if (!IS_MM_ROOT(me) && + is_mounted(me->key, MNTS_REAL)) + return MOUNT_OFFSET_IGNORE; + +@@ -1220,11 +1220,11 @@ static void *do_mount_direct(void *arg) + * for direct mount multi-mounts with no real mount at + * their base so they will be expired. + */ +- if (close_fd && me == me->multi) ++ if (close_fd && IS_MM_ROOT(me)) + close_fd = 0; + if (!close_fd) + me->ioctlfd = mt.ioctlfd; +- if (me->multi && me->multi != me) ++ if (IS_MM(me) && !IS_MM_ROOT(me)) + flags |= MNTS_OFFSET; + } + ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 2fea0c0b..8c9a82b5 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -748,7 +748,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root) + goto next; + + /* It's a busy multi-mount - leave till next time */ +- if (list_empty(&me->multi_list)) ++ if (IS_MM(me)) + error(ap->logopt, + "invalid key %s", me->key); + goto next; +@@ -838,12 +838,12 @@ static int lookup_amd_instance(struct autofs_point *ap, + char *m_key; + + me = cache_lookup_distinct(map->mc, name); +- if (!me || !me->multi) { ++ if (!me || !IS_MM(me)) { + error(ap->logopt, "expected multi mount entry not found"); + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 2); ++ m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +@@ -852,7 +852,7 @@ static int lookup_amd_instance(struct autofs_point *ap, + + strcpy(m_key, ap->path); + strcat(m_key, "/"); +- strcat(m_key, me->multi->key); ++ strcat(m_key, MM_ROOT(me)->key); + + mnt = mnts_find_amdmount(m_key); + free(m_key); +@@ -1355,7 +1355,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + * created on demand and managed by expire and don't + * prune the multi-map owner map entry. + */ +- if (*me->key == '/' || me->multi == me) { ++ if (*me->key == '/' || IS_MM_ROOT(me)) { + me = cache_enumerate(mc, me); + continue; + } +diff --git a/include/automount.h b/include/automount.h +index fa6f5d63..e917515b 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -183,6 +183,11 @@ struct mapent { + ino_t ino; + }; + ++#define IS_MM(me) (me->multi) ++#define IS_MM_ROOT(me) (me->multi == me) ++#define MM_ROOT(me) (me->multi) ++#define MM_PARENT(me) (me->parent) ++ + void cache_lock_cleanup(void *arg); + void cache_readlock(struct mapent_cache *mc); + void cache_writelock(struct mapent_cache *mc); +diff --git a/lib/cache.c b/lib/cache.c +index a90bbb1d..1d9f5cc7 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc) + + while (me) { + /* Multi mount entries are not primary */ +- if (me->multi && me->multi != me) { ++ if (IS_MM(me) && !IS_MM_ROOT(me)) { + me = me->next; + continue; + } +@@ -397,7 +397,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + this = me->next; + while (this) { + /* Multi mount entries are not primary */ +- if (this->multi && this->multi != this) { ++ if (IS_MM(this) && !IS_MM_ROOT(this)) { + this = this->next; + continue; + } +@@ -413,7 +413,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me) + + while (this) { + /* Multi mount entries are not primary */ +- if (this->multi && this->multi != this) { ++ if (IS_MM(this) && !IS_MM_ROOT(this)) { + this = this->next; + continue; + } +@@ -435,7 +435,7 @@ struct mapent *cache_lookup_key_next(struct mapent *me) + next = me->next; + while (next) { + /* Multi mount entries are not primary */ +- if (me->multi && me->multi != me) ++ if (IS_MM(me) && !IS_MM_ROOT(me)) + continue; + if (!strcmp(me->key, next->key)) + return next; +@@ -706,7 +706,7 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k + me = cache_lookup_distinct(mc, key); + if (me) { + cache_add_ordered_offset(me, &owner->multi_list); +- me->multi = owner; ++ MM_ROOT(me) = owner; + goto done; + } + ret = CHE_FAIL; +@@ -814,14 +814,14 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) + this = cache_lookup_distinct(mc, offset); + if (!this) + return 0; +- if (!this->multi) ++ if (!IS_MM(this)) + return 0; + + parent = get_offset_parent(mc, offset); + if (parent) + this->parent = parent; + else +- this->parent = this->multi; ++ this->parent = MM_ROOT(this); + + return 1; + } +@@ -879,7 +879,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key) + return CHE_FAIL; + + if (strcmp(key, me->key) == 0) { +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + return CHE_FAIL; + mc->hash[hashval] = me->next; + goto delete; +@@ -889,7 +889,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key) + pred = me; + me = me->next; + if (strcmp(key, me->key) == 0) { +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + return CHE_FAIL; + pred->next = me->next; + goto delete; +@@ -927,7 +927,7 @@ int cache_delete(struct mapent_cache *mc, const char *key) + me = me->next; + if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; +- if (me->multi && !list_empty(&me->multi_list)) { ++ if (IS_MM(me)) { + ret = CHE_FAIL; + goto done; + } +@@ -956,7 +956,7 @@ int cache_delete(struct mapent_cache *mc, const char *key) + + if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; +- if (me->multi && !list_empty(&me->multi_list)) { ++ if (IS_MM(me)) { + ret = CHE_FAIL; + goto done; + } +@@ -995,7 +995,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key) + return CHE_FAIL; + + /* Not offset list owner */ +- if (me->multi != me) ++ if (!IS_MM_ROOT(me)) + return CHE_FAIL; + + head = &me->multi_list; +@@ -1016,13 +1016,13 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key) + this = list_entry(next, struct mapent, multi_list); + next = next->next; + list_del_init(&this->multi_list); +- this->multi = NULL; ++ MM_ROOT(this) = NULL; + debug(logopt, "deleting offset key %s", this->key); + status = cache_delete(mc, this->key); + if (status == CHE_FAIL) { + warn(logopt, + "failed to delete offset %s", this->key); +- this->multi = me; ++ MM_ROOT(this) = me; + /* TODO: add list back in */ + remain++; + } +@@ -1030,7 +1030,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key) + + if (!remain) { + list_del_init(&me->multi_list); +- me->multi = NULL; ++ MM_ROOT(me) = NULL; + } + + if (remain) +diff --git a/lib/mounts.c b/lib/mounts.c +index f5b905a6..f6f20fc0 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2163,7 +2163,7 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type) + } else { + me->flags &= ~MOUNT_FLAG_DIR_CREATED; + if (type == t_offset) { +- if (!is_mounted(me->parent->key, MNTS_REAL)) ++ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL)) + me->flags |= MOUNT_FLAG_DIR_CREATED; + } + } +@@ -2310,7 +2310,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap) + goto next; + + /* Only need to set offset mounts catatonic */ +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + set_multi_mount_tree_catatonic(ap, me); + next: + me = cache_enumerate(mc, me); +@@ -2330,7 +2330,7 @@ next: + void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + { + /* Set offset mounts catatonic for this mapent */ +- if (me->multi && me->multi == me) ++ if (IS_MM(me) && IS_MM_ROOT(me)) + set_multi_mount_tree_catatonic(ap, me); + set_mount_catatonic(ap, me, me->ioctlfd); + } +@@ -2490,12 +2490,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + int ret; + + if (ap->type == LKP_DIRECT) +- return rmdir_path(ap, oe->key, oe->multi->dev); ++ return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev); + + dir = strdup(oe->key); + + if (ap->flags & MOUNT_FLAG_GHOST) +- split = strlen(ap->path) + strlen(oe->multi->key) + 1; ++ split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1; + else + split = strlen(ap->path); + +@@ -2690,7 +2690,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; +- if (oe->age != me->multi->age) { ++ if (oe->age != MM_ROOT(me)->age) { + /* Best effort */ + do_umount_offset(ap, oe, root, start); + goto cont; +@@ -2724,7 +2724,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + + left = do_umount_multi_triggers(ap, me, root, start, base); + +- if (!left && me->multi == me) { ++ if (!left && IS_MM_ROOT(me)) { + /* + * Special case. + * If we can't umount the root container then we can't +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index f46a04f0..6afc5587 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1199,8 +1199,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index c1ebb7f6..7e101ddb 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct autofs_point *ap, + me = cache_lookup_first(mc); + while (me) { + /* Hosts map entry not yet expanded or already expired */ +- if (!me->multi) ++ if (!IS_MM(me)) + goto next; + + debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key); +@@ -200,7 +200,7 @@ next: + * Hosts map entry not yet expanded, already expired + * or not the base of the tree + */ +- if (!me->multi || me->multi != me) ++ if (!IS_MM(me) || !IS_MM_ROOT(me)) + goto cont; + + debug(ap->logopt, MODPREFIX +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 3624dd86..3e43fc01 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -3700,8 +3700,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index cbd03cdb..6e9a85d1 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -722,8 +722,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index ca209488..70f27545 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -646,7 +646,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + name_len, ent, ctxt->parse->context); + goto out_free; + } else { +- if (me->multi && me->multi != me) { ++ if (IS_MM(me) && !IS_MM_ROOT(me)) { + cache_unlock(mc); + warn(ap->logopt, MODPREFIX + "unexpected lookup for active multi-mount" +@@ -657,7 +657,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + cache_writelock(mc); + me = cache_lookup_distinct(mc, name); + if (me) { +- if (me->multi) ++ if (IS_MM(me)) + cache_delete_offset_list(mc, name); + cache_delete(mc, name); + } +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index ccd605af..ad834626 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -1055,8 +1055,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else + lkp_key = strdup(key); + cache_unlock(mc); +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 38f75497..8bccb72f 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -826,8 +826,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (ap->type == LKP_INDIRECT && *key != '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); +- if (me && me->multi) +- lkp_key = strdup(me->multi->key); ++ if (me && IS_MM(me)) ++ lkp_key = strdup(MM_ROOT(me)->key); + else if (!ap->pref) + lkp_key = strdup(key); + else { +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 34d4441e..b11c6693 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1148,7 +1148,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + + rv = 0; + +- mm_key = me->multi->key; ++ mm_key = MM_ROOT(me)->key; + + if (*mm_key == '/') { + mm_root = mm_key; +@@ -1162,7 +1162,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + } + mm_root_len = strlen(mm_root); + +- if (me == me->multi) { ++ if (IS_MM_ROOT(me)) { + char key[PATH_MAX + 1]; + + if (mm_root_len + 1 > PATH_MAX) { +@@ -1179,7 +1179,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +- if (ro && ro->age == me->multi->age) { ++ if (ro && ro->age == MM_ROOT(me)->age) { + char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; + int ro_len; +@@ -1350,7 +1350,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + if (*name == '/') { + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +- if (me && me->multi && me->multi != me) { ++ if (me && IS_MM(me) && !IS_MM_ROOT(me)) { + cache_unlock(mc); + mapent_len = strlen(mapent) + 1; + pmapent = malloc(mapent_len + 1); +@@ -1505,7 +1505,7 @@ dont_expand: + } + + /* So we know we're the multi-mount root */ +- if (!me->multi) ++ if (!IS_MM(me)) + me->multi = me; + else { + /* +@@ -1630,7 +1630,7 @@ dont_expand: + */ + cache_readlock(mc); + if (*name == '/' && +- (me = cache_lookup_distinct(mc, name)) && me->multi) { ++ (me = cache_lookup_distinct(mc, name)) && IS_MM(me)) { + cache_unlock(mc); + loc = strdup(p); + if (!loc) { diff --git a/SOURCES/autofs-5.1.7-add-tree_mapent_add_node.patch b/SOURCES/autofs-5.1.7-add-tree_mapent_add_node.patch new file mode 100644 index 0000000..11f598c --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-tree_mapent_add_node.patch @@ -0,0 +1,133 @@ +autofs-5.1.7 - add tree_mapent_add_node() + +From: Ian Kent + +Add function tree_mapent_add_node() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 1 + + include/mounts.h | 1 + + lib/cache.c | 5 ++--- + lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 52 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 8841f72f..85730eda 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -33,6 +33,7 @@ + - add a len field to struct autofs_point. + - make tree implementation data independent. + - add mapent tree implementation. ++- add tree_mapent_add_node(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index ebc2007f..f6023e27 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -216,6 +216,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + int cache_lookup_negative(struct mapent *me, const char *key); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); ++struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key); + int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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/include/mounts.h b/include/mounts.h +index fd7c6183..a0e60e24 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -169,6 +169,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); ++int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/cache.c b/lib/cache.c +index 6dfaeff5..7c409a56 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -749,8 +749,7 @@ void cache_update_negative(struct mapent_cache *mc, + } + + +-static struct mapent *get_offset_parent(struct mapent_cache *mc, +- const char *key) ++struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key) + { + struct mapent *me; + char *parent, *tail; +@@ -796,7 +795,7 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) + if (!IS_MM(this)) + return 0; + +- parent = get_offset_parent(mc, offset); ++ parent = cache_get_offset_parent(mc, offset); + if (parent) + this->parent = parent; + else +diff --git a/lib/mounts.c b/lib/mounts.c +index 40ebf9cf..a0bf3d52 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree_node *n) + n->right = NULL; + } + ++int tree_mapent_add_node(struct mapent_cache *mc, ++ const char *root, const char *key) ++{ ++ unsigned int logopt = mc->ap->logopt; ++ struct tree_node *tree, *n; ++ struct mapent *base; ++ struct mapent *parent; ++ struct mapent *me; ++ ++ base = cache_lookup_distinct(mc, root); ++ if (!base) { ++ error(logopt, ++ "failed to find multi-mount root for key %s", key); ++ return 0; ++ } ++ ++ if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { ++ error(logopt, ++ "failed to find multi-mount root of offset tree", ++ key); ++ return 0; ++ } ++ tree = MAPENT_ROOT(base); ++ ++ me = cache_lookup_distinct(mc, key); ++ if (!me) { ++ error(logopt, ++ "failed to find key %s of multi-mount", key); ++ return 0; ++ } ++ ++ n = tree_add_node(tree, me); ++ if (!n) ++ return 0; ++ ++ MAPENT_SET_ROOT(me, tree) ++ ++ /* Set the subtree parent */ ++ parent = cache_get_offset_parent(mc, key); ++ if (!parent) ++ MAPENT_SET_PARENT(me, tree) ++ else ++ MAPENT_SET_PARENT(me, MAPENT_NODE(parent)) ++ ++ return 1; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/SOURCES/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch b/SOURCES/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch new file mode 100644 index 0000000..2a57e9f --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch @@ -0,0 +1,94 @@ +autofs-5.1.7 - add tree_mapent_cleanup_offsets() + +From: Ian Kent + +Add function tree_mapent_cleanup_offsets() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 1 + + lib/mounts.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 47 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index e2fd532c..89d4cfa0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -37,6 +37,7 @@ + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). ++- add tree_mapent_cleanup_offsets(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index b5a1193b..5441ee0e 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); ++void tree_mapent_cleanup_offsets(struct mapent *oe); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/mounts.c b/lib/mounts.c +index 497c28c9..ba573b9a 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key) + return 1; + } + ++static void tree_mapent_umount_mount(struct autofs_point *ap, const char *mp) ++{ ++ if (is_mounted(mp, MNTS_ALL)) { ++ if (umount(mp)) { ++ error(ap->logopt, "error recovering from mount fail"); ++ error(ap->logopt, "cannot umount %s", mp); ++ } ++ } ++} ++ ++static int tree_mapent_cleanup_offsets_work(struct tree_node *n, void *ptr) ++{ ++ struct mapent *oe = MAPENT(n); ++ struct traverse_subtree_context *ctxt = ptr; ++ ++ tree_mapent_umount_mount(ctxt->ap, oe->key); ++ ++ return 1; ++} ++ ++void tree_mapent_cleanup_offsets(struct mapent *oe) ++{ ++ struct tree_node *base = MAPENT_NODE(oe); ++ struct traverse_subtree_context ctxt = { ++ .ap = oe->mc->ap, ++ .base = base, ++ .strict = 0, ++ }; ++ struct autofs_point *ap = oe->mc->ap; ++ ++ tree_mapent_traverse_subtree(base, tree_mapent_cleanup_offsets_work, &ctxt); ++ ++ /* Cleanup base mount after offsets have been cleaned up */ ++ if (*oe->key == '/') ++ tree_mapent_umount_mount(ap, oe->key); ++ else { ++ char mp[PATH_MAX + 1]; ++ ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) ++ error(ap->logopt, "mount path is too long"); ++ else ++ tree_mapent_umount_mount(ap, mp); ++ } ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/SOURCES/autofs-5.1.7-add-tree_mapent_delete_offsets.patch b/SOURCES/autofs-5.1.7-add-tree_mapent_delete_offsets.patch new file mode 100644 index 0000000..6d228ec --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-tree_mapent_delete_offsets.patch @@ -0,0 +1,119 @@ +autofs-5.1.7 - add tree_mapent_delete_offsets() + +From: Ian Kent + +Add function tree_mapent_delete_offsets() to the mapent tree handling +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 1 + + lib/mounts.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 72 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 85730eda..488b4996 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -34,6 +34,7 @@ + - make tree implementation data independent. + - add mapent tree implementation. + - add tree_mapent_add_node(). ++- add tree_mapent_delete_offsets(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index a0e60e24..b5a1193b 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -170,6 +170,7 @@ void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); ++int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/mounts.c b/lib/mounts.c +index a0bf3d52..eb700c79 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_cache *mc, + return 1; + } + ++static int tree_mapent_delete_offset_tree(struct tree_node *root) ++{ ++ struct mapent *me = MAPENT(root); ++ unsigned int logopt = me->mc->ap->logopt; ++ int ret = CHE_OK; ++ ++ if (root->left) { ++ ret = tree_mapent_delete_offset_tree(root->left); ++ if (!ret) ++ return 0; ++ root->left = NULL; ++ } ++ if (root->right) { ++ ret = tree_mapent_delete_offset_tree(root->right); ++ if (!ret) ++ return 0; ++ root->right = NULL; ++ } ++ ++ /* Keep the owner of the multi-mount offset tree and clear ++ * the root and parent when done. ++ */ ++ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { ++ struct tree_node *root = MAPENT_ROOT(me); ++ ++ debug(logopt, "deleting offset key %s", me->key); ++ ++ /* cache_delete won't delete an active offset */ ++ MAPENT_SET_ROOT(me, NULL); ++ ret = cache_delete(me->mc, me->key); ++ if (ret != CHE_OK) { ++ MAPENT_SET_ROOT(me, root); ++ warn(logopt, "failed to delete offset %s", me->key); ++ } ++ } else { ++ MAPENT_SET_ROOT(me, NULL); ++ MAPENT_SET_PARENT(me, NULL); ++ } ++ ++ return ret == CHE_OK ? 1 : 0; ++} ++ ++int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key) ++{ ++ unsigned int logopt = mc->ap->logopt; ++ struct mapent *me; ++ ++ me = cache_lookup_distinct(mc, key); ++ if (!me) { ++ error(logopt, ++ "failed to find multi-mount root for key %s", key); ++ return 0; ++ } ++ ++ /* Not offset list owner */ ++ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) { ++ error(logopt, ++ "mapent for key %s is not multi-mount owner", key); ++ return 0; ++ } ++ ++ if (!tree_mapent_delete_offset_tree(MAPENT_ROOT(me))) { ++ error(logopt, ++ "could not delete map entry offsets for key %s", key); ++ return 0; ++ } ++ ++ return 1; ++} ++ + /* From glibc decode_name() */ + /* Since the values in a line are separated by spaces, a name cannot + * contain a space. Therefore some programs encode spaces in names diff --git a/SOURCES/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch b/SOURCES/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch new file mode 100644 index 0000000..1e0ff93 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-tree_mapent_traverse_subtree.patch @@ -0,0 +1,83 @@ +autofs-5.1.7 - add tree_mapent_traverse_subtree() + +From: Ian Kent + +Add function tree_mapent_traverse_subtree() that enumerates offsets from +a given base node bounded by subtree nesting points. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 488b4996..390028ac 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -35,6 +35,7 @@ + - add mapent tree implementation. + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). ++- add tree_mapent_traverse_subtree(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index eb700c79..fded4c09 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_cache *mc, + return 1; + } + ++static inline int tree_mapent_is_root(struct mapent *oe) ++{ ++ /* Offset "/" is a special case, it's looked up and mounted ++ * seperately because the offset tree may or may not have a ++ * real mount at the base and the triggers inside it need to ++ * be mounted in either case. Also the order requires the ++ * offset at the top of the (sub)tree to be handled after ++ * the traversal. ++ */ ++ return (oe->key[oe->len - 1] == '/' || ++ MAPENT_ROOT(oe) == MAPENT_NODE(oe)); ++} ++ ++struct traverse_subtree_context { ++ struct autofs_point *ap; ++ struct tree_node *base; ++ int strict; ++}; ++ ++static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work, void *ptr) ++{ ++ struct traverse_subtree_context *ctxt = ptr; ++ struct mapent *oe = MAPENT(n); ++ int ret = 1; ++ ++ if (n->left) { ++ ret = tree_mapent_traverse_subtree(n->left, work, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++ ++ /* Node is not multi-mount root and is part of current subtree */ ++ if (!tree_mapent_is_root(oe) && MAPENT_PARENT(oe) == ctxt->base) { ++ ret = work(n, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++ ++ if (n->right) { ++ ret = tree_mapent_traverse_subtree(n->right, work, ctxt); ++ if (!ret && ctxt->strict) ++ goto done; ++ } ++done: ++ return ret; ++} ++ + static int tree_mapent_delete_offset_tree(struct tree_node *root) + { + struct mapent *me = MAPENT(root); diff --git a/SOURCES/autofs-5.1.7-add-xdr_exports.patch b/SOURCES/autofs-5.1.7-add-xdr_exports.patch new file mode 100644 index 0000000..80f7c12 --- /dev/null +++ b/SOURCES/autofs-5.1.7-add-xdr_exports.patch @@ -0,0 +1,335 @@ +autofs-5.1.7 - add xdr_exports() + +From: Ian Kent + +Add an xdr_exports() function to get NFS exports from a server. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 3 + + include/rpc_subs.h | 14 ++++++ + lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++------------- + modules/lookup_hosts.c | 25 +++------- + 4 files changed, 112 insertions(+), 50 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2c48484b..84050e91 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,6 @@ ++ ++- add xdr_exports(). ++ + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. + - update ldap READMEs and schema definitions. +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index 7ba4b93f..080f19d9 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -17,6 +17,7 @@ + #define _RPC_SUBS_H + + #include ++#include + #include + #include + #include +@@ -47,6 +48,17 @@ + + #define HOST_ENT_BUF_SIZE 2048 + ++struct hostinfo { ++ char *name; ++ struct hostinfo *next; ++}; ++ ++struct exportinfo { ++ char *dir; ++ struct hostinfo *hosts; ++ struct exportinfo *next; ++}; ++ + struct conn_info { + const char *host; + struct sockaddr *addr; +@@ -71,6 +83,8 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *); + int rpc_ping_proto(struct conn_info *); + int rpc_ping(const char *, int, unsigned int, long, long, unsigned int); + double monotonic_elapsed(struct timespec, struct timespec); ++struct exportinfo *rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); ++void rpc_exports_free(struct exportinfo *exports); + const char *get_addr_string(struct sockaddr *, char *, socklen_t); + + #endif +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 643b7687..7b8162b4 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -41,7 +41,6 @@ const rpcprog_t rpcb_prog = PMAPPROG; + const rpcvers_t rpcb_version = PMAPVERS; + #endif + +-#include "mount.h" + #include "rpc_subs.h" + #include "replicated.h" + #include "automount.h" +@@ -58,6 +57,17 @@ const rpcvers_t rpcb_version = PMAPVERS; + + #define MAX_NETWORK_LEN 255 + ++#define EXPPATHLEN 1024 ++#define EXPNAMELEN 255 ++ ++#define MOUNTPROG 100005 ++ ++#define MOUNTVERS 1 ++#define MOUNTVERS_NFSV3 3 ++#define MOUNTVERS_POSIX 2 ++ ++#define MOUNTPROC_EXPORT 5 ++ + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + +@@ -1102,7 +1112,55 @@ double monotonic_elapsed(struct timespec start, struct timespec end) + return t2 - t1; + } + +-static int rpc_get_exports_proto(struct conn_info *info, exports *exp) ++static bool_t xdr_host(XDR *xdrs, struct hostinfo *host) ++{ ++ if (!xdr_string(xdrs, &host->name, EXPNAMELEN)) ++ return FALSE; ++ return TRUE; ++} ++ ++static bool_t xdr_hosts(XDR *xdrs, struct hostinfo **hosts) ++{ ++ unsigned int size = sizeof(struct hostinfo); ++ char **host; ++ ++ host = (char **) hosts; ++ while (1) { ++ if (!xdr_pointer(xdrs, host, size, (xdrproc_t) xdr_host)) ++ return FALSE; ++ if (!*host) ++ break; ++ host = (char **) &((struct hostinfo *) *host)->next; ++ } ++ return TRUE; ++} ++ ++static bool_t xdr_export(XDR *xdrs, struct exportinfo *export) ++{ ++ if (!xdr_string(xdrs, &export->dir, EXPPATHLEN)) ++ return FALSE; ++ if (!xdr_hosts(xdrs, &export->hosts)) ++ return FALSE; ++ return TRUE; ++} ++ ++bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports) ++{ ++ unsigned int size = sizeof(struct exportinfo); ++ char **export; ++ ++ export = (char **) exports; ++ while (1) { ++ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) ++ return FALSE; ++ if (!*export) ++ break; ++ export = (char **) &((struct exportinfo *) *export)->next; ++ } ++ return TRUE; ++} ++ ++static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exports) + { + CLIENT *client; + enum clnt_stat status; +@@ -1133,7 +1191,7 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) + while (1) { + status = clnt_call(client, MOUNTPROC_EXPORT, + (xdrproc_t) xdr_void, NULL, +- (xdrproc_t) xdr_exports, (caddr_t) exp, ++ (xdrproc_t) xdr_exports, (caddr_t) exports, + info->timeout); + if (status == RPC_SUCCESS) + break; +@@ -1168,41 +1226,43 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) + return 1; + } + +-static void rpc_export_free(exports item) ++static void rpc_export_free(struct exportinfo *export) + { +- groups grp; +- groups tmp; +- +- if (item->ex_dir) +- free(item->ex_dir); +- +- grp = item->ex_groups; +- while (grp) { +- if (grp->gr_name) +- free(grp->gr_name); +- tmp = grp; +- grp = grp->gr_next; ++ struct hostinfo *host, *tmp; ++ ++ if (export->dir) ++ free(export->dir); ++ ++ host = export->hosts; ++ while (host) { ++ if (host->name) ++ free(host->name); ++ tmp = host; ++ host = host->next; + free(tmp); + } +- free(item); ++ free(export); + } + +-void rpc_exports_free(exports list) ++void rpc_exports_free(struct exportinfo *exports) + { +- exports tmp; ++ struct exportinfo *export, *tmp; + +- while (list) { +- tmp = list; +- list = list->ex_next; ++ export = exports; ++ while (export) { ++ tmp = export; ++ export = export->next; + rpc_export_free(tmp); + } + return; + } + +-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option) ++struct exportinfo *rpc_get_exports(const char *host, ++ long seconds, long micros, ++ unsigned int option) + { + struct conn_info info; +- exports exportlist; ++ struct exportinfo *exports = NULL; + struct pmap parms; + int status; + +@@ -1231,11 +1291,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in + if (status < 0) + goto try_tcp; + +- memset(&exportlist, '\0', sizeof(exportlist)); +- +- status = rpc_get_exports_proto(&info, &exportlist); ++ status = rpc_get_exports_proto(&info, &exports); + if (status) +- return exportlist; ++ return exports; + + try_tcp: + info.proto = IPPROTO_TCP; +@@ -1246,13 +1304,11 @@ try_tcp: + if (status < 0) + return NULL; + +- memset(&exportlist, '\0', sizeof(exportlist)); +- +- status = rpc_get_exports_proto(&info, &exportlist); ++ status = rpc_get_exports_proto(&info, &exports); + if (!status) + return NULL; + +- return exportlist; ++ return exports; + } + + const char *get_addr_string(struct sockaddr *sa, char *name, socklen_t len) +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 744062e2..81a4eb18 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -20,14 +20,6 @@ + #include + #include + +-/* +- * Avoid annoying compiler noise by using an alternate name for +- * typedef name in mount.h +- */ +-#define name __dummy_type_name +-#include "mount.h" +-#undef name +- + #define MODULE_LOOKUP + #include "automount.h" + #include "nsswitch.h" +@@ -43,9 +35,6 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); +-void rpc_exports_free(exports list); +- + int lookup_init(const char *mapfmt, + int argc, const char *const *argv, void **context) + { +@@ -99,7 +88,7 @@ static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; + char *mapent; +- exports exp, this; ++ struct exportinfo *exp, *this; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -111,7 +100,7 @@ static char *get_exports(struct autofs_point *ap, const char *host) + if (mapent) { + int len = strlen(mapent) + 1; + +- len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3; ++ len += strlen(host) + 2*(strlen(this->dir) + 2) + 3; + mapent = realloc(mapent, len); + if (!mapent) { + char *estr; +@@ -121,10 +110,10 @@ static char *get_exports(struct autofs_point *ap, const char *host) + return NULL; + } + strcat(mapent, " \""); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + } else { +- int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3; ++ int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3; + + mapent = malloc(len); + if (!mapent) { +@@ -135,16 +124,16 @@ static char *get_exports(struct autofs_point *ap, const char *host) + return NULL; + } + strcpy(mapent, "\""); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + } + strcat(mapent, " \""); + strcat(mapent, host); + strcat(mapent, ":"); +- strcat(mapent, this->ex_dir); ++ strcat(mapent, this->dir); + strcat(mapent, "\""); + +- this = this->ex_next; ++ this = this->next; + } + rpc_exports_free(exp); + diff --git a/SOURCES/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch b/SOURCES/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch new file mode 100644 index 0000000..062ecdc --- /dev/null +++ b/SOURCES/autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch @@ -0,0 +1,44 @@ +autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list() + +From: Ian Kent + +Coverity: var_deref_model: Passing null pointer "tree" to + "tree_traverse_inorder", which dereferences it. + +This obviously can't happen but deal with it anyway to quiet Coverity. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b79aebc8..b1b28888 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -64,6 +64,7 @@ + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. ++- cater for empty mounts list in mnts_get_expire_list(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 883e3743..3996eb5e 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + } + } + +- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); +- tree_free(tree); ++ if (tree) { ++ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); ++ tree_free(tree); ++ } + done: + mnts_hash_mutex_unlock(); + } diff --git a/SOURCES/autofs-5.1.7-check-for-offset-with-no-mount-location.patch b/SOURCES/autofs-5.1.7-check-for-offset-with-no-mount-location.patch new file mode 100644 index 0000000..b2b8566 --- /dev/null +++ b/SOURCES/autofs-5.1.7-check-for-offset-with-no-mount-location.patch @@ -0,0 +1,50 @@ +autofs-5.1.7 - check for offset with no mount location + +From: Ian Kent + +Offsets need to have a mount location, check for it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index a9209755..42914160 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -47,6 +47,7 @@ + - pass root length to mount_fullpath(). + - remove unused function master_submount_list_empty(). + - move amd mounts removal into lib/mounts.c. ++- check for offset with no mount location. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index b1c2611c..a81d4028 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -801,7 +801,20 @@ update_offset_entry(struct autofs_point *ap, + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + +- /* Internal hosts map may have loc == NULL */ ++ if (!loc || !*loc) { ++ const char *type = ap->entry->maps->type; ++ ++ /* If it's not the internal hosts map it must have a ++ * mount location. ++ */ ++ if (!type || strcmp(type, "hosts")) { ++ error(ap->logopt, ++ MODPREFIX "syntax error in offset %s -> %s", ++ m_offset, loc); ++ return CHE_FAIL; ++ } ++ } ++ + if (!*m_offset) { + error(ap->logopt, + MODPREFIX "syntax error in offset %s -> %s", m_offset, loc); diff --git a/SOURCES/autofs-5.1.7-cleanup-cache_delete-a-little.patch b/SOURCES/autofs-5.1.7-cleanup-cache_delete-a-little.patch new file mode 100644 index 0000000..6697ce9 --- /dev/null +++ b/SOURCES/autofs-5.1.7-cleanup-cache_delete-a-little.patch @@ -0,0 +1,64 @@ +autofs-5.1.7 - cleanup cache_delete() a little + +From: Ian Kent + +There's no reason to use local function storage for the passed in key +just use the given key. + +Also, if there's no hash array entry for the key then there's no cache +entry so don't return a fail for this case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 11 +++-------- + 2 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 6419052d..e822efec 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -24,6 +24,7 @@ + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. ++- cleanup cache_delete() a little. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/cache.c b/lib/cache.c +index 03d0499a..a90bbb1d 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -917,20 +917,15 @@ int cache_delete(struct mapent_cache *mc, const char *key) + struct mapent *me = NULL, *pred; + u_int32_t hashval = hash(key, mc->size); + int ret = CHE_OK; +- char this[PATH_MAX]; +- +- strcpy(this, key); + + me = mc->hash[hashval]; +- if (!me) { +- ret = CHE_FAIL; ++ if (!me) + goto done; +- } + + while (me->next != NULL) { + pred = me; + me = me->next; +- if (strcmp(this, me->key) == 0) { ++ if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; +@@ -959,7 +954,7 @@ int cache_delete(struct mapent_cache *mc, const char *key) + if (!me) + goto done; + +- if (strcmp(this, me->key) == 0) { ++ if (strcmp(key, me->key) == 0) { + struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; diff --git a/SOURCES/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch b/SOURCES/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch new file mode 100644 index 0000000..7e13642 --- /dev/null +++ b/SOURCES/autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch @@ -0,0 +1,207 @@ +autofs-5.1.7 - don't add offset mounts to mounted mounts table + +From: Ian Kent + +Multi-mount offset mounts are added to the mounted mounts table whether +they have a real mount or not. If there are a large number of offsets +this can add unnecessary overhead to the mounted mounts table processing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 14 ++++---------- + daemon/indirect.c | 4 +++- + include/mounts.h | 2 +- + lib/mounts.c | 43 +++++++++++-------------------------------- + 5 files changed, 20 insertions(+), 44 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index cb709773..b144f6aa 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -22,6 +22,7 @@ + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. ++- don't add offset mounts to mounted mounts table. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index 311a98ba..fbfebbdd 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -605,9 +605,6 @@ force_umount: + } else + info(ap->logopt, "umounted offset mount %s", me->key); + +- if (!rv) +- mnts_remove_mount(me->key, MNTS_OFFSET); +- + return rv; + } + +@@ -761,12 +758,6 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + +- mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET); +- if (!mnt) +- error(ap->logopt, +- "failed to add offset mount %s to mounted list", +- me->key); +- + debug(ap->logopt, "mounted trigger %s", me->key); + + return MOUNT_OFFSET_OK; +@@ -1214,6 +1205,7 @@ static void *do_mount_direct(void *arg) + struct mapent *me; + struct statfs fs; + unsigned int close_fd = 0; ++ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; + + sbmnt = mnts_find_submount(mt.name); + if (statfs(mt.name, &fs) == -1 || +@@ -1232,6 +1224,8 @@ static void *do_mount_direct(void *arg) + close_fd = 0; + if (!close_fd) + me->ioctlfd = mt.ioctlfd; ++ if (me->multi && me->multi != me) ++ flags |= MNTS_OFFSET; + } + ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); + cache_unlock(mt.mc); +@@ -1240,7 +1234,7 @@ static void *do_mount_direct(void *arg) + + info(ap->logopt, "mounted %s", mt.name); + +- mnts_set_mounted_mount(ap, mt.name); ++ mnts_set_mounted_mount(ap, mt.name, flags); + + conditional_alarm_add(ap, ap->exp_runfreq); + } else { +diff --git a/daemon/indirect.c b/daemon/indirect.c +index b259ebdc..eddcfff7 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -747,12 +747,14 @@ static void *do_mount_indirect(void *arg) + status = lookup_nss_mount(ap, NULL, mt.name, mt.len); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + if (status) { ++ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED; ++ + ops->send_ready(ap->logopt, + ap->ioctlfd, mt.wait_queue_token); + + info(ap->logopt, "mounted %s", buf); + +- mnts_set_mounted_mount(ap, mt.name); ++ mnts_set_mounted_mount(ap, mt.name, flags); + + conditional_alarm_add(ap, ap->exp_runfreq); + } else { +diff --git a/include/mounts.h b/include/mounts.h +index e3022b23..ac480c06 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -131,7 +131,7 @@ struct mnt_list *get_mnt_list(const char *path, int include); + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); +-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name); ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + int unlink_mount_tree(struct autofs_point *ap, const char *mp); + void free_mnt_list(struct mnt_list *list); + int is_mounted(const char *mp, unsigned int type); +diff --git a/lib/mounts.c b/lib/mounts.c +index 04fe3d00..25ae2e1d 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + this = mnts_get_mount(mp); + if (this) { + this->flags |= flags; +- if (list_empty(&this->mount)) ++ if ((this->flags & MNTS_MOUNTED) && list_empty(&this->mount)) + list_add(&this->mount, &ap->mounts); + } + mnts_hash_mutex_unlock(); +@@ -1193,42 +1193,23 @@ void mnts_remove_mount(const char *mp, unsigned int flags) + this = mnts_lookup(mp); + if (this && this->flags & flags) { + this->flags &= ~flags; +- if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED))) ++ if (!(this->flags & MNTS_MOUNTED)) + list_del_init(&this->mount); + __mnts_put_mount(this); + } + mnts_hash_mutex_unlock(); + } + +-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name) ++void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags) + { + struct mnt_list *mnt; + +- mnt = mnts_add_mount(ap, name, MNTS_MOUNTED); ++ mnt = mnts_add_mount(ap, name, flags); + if (!mnt) { + error(ap->logopt, + "failed to add mount %s to mounted list", name); + return; + } +- +- /* Offset mount failed but non-strict returns success */ +- if (mnt->flags & MNTS_OFFSET && +- !is_mounted(mnt->mp, MNTS_REAL)) { +- mnt->flags &= ~MNTS_MOUNTED; +- mnts_put_mount(mnt); +- } +- +- /* Housekeeping. +- * Set the base type of the mounted mount. +- * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and +- * are used during expire. +- */ +- if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) { +- if (ap->type == LKP_INDIRECT) +- mnt->flags |= MNTS_INDIRECT; +- else +- mnt->flags |= MNTS_DIRECT; +- } + } + + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap) +@@ -1947,17 +1928,13 @@ static int do_remount_direct(struct autofs_point *ap, + + ret = lookup_nss_mount(ap, NULL, path, strlen(path)); + if (ret) { +- struct mnt_list *mnt; ++ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED; + + /* If it's an offset mount add a mount reference */ +- if (type == t_offset) { +- mnt = mnts_add_mount(ap, path, MNTS_OFFSET); +- if (!mnt) +- error(ap->logopt, +- "failed to add mount %s to mounted list", path); +- } ++ if (type == t_offset) ++ flags |= MNTS_OFFSET; + +- mnts_set_mounted_mount(ap, path); ++ mnts_set_mounted_mount(ap, path, flags); + + info(ap->logopt, "re-connected to %s", path); + +@@ -2032,7 +2009,9 @@ static int do_remount_indirect(struct autofs_point *ap, const unsigned int type, + + ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len); + if (ret) { +- mnts_set_mounted_mount(ap, buf); ++ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED; ++ ++ mnts_set_mounted_mount(ap, buf, flags); + + info(ap->logopt, "re-connected to %s", buf); + diff --git a/SOURCES/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch b/SOURCES/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch new file mode 100644 index 0000000..333b6e4 --- /dev/null +++ b/SOURCES/autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch @@ -0,0 +1,64 @@ +autofs-5.1.7 - don't pass root to do_mount_autofs_offset() + +From: Ian Kent + +The root parameter of do_mount_autofs_offset() is used only in a +debug log message. It doesn't really add any value to debugging +so remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 9 ++++----- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0e9ca94f..2a07bd45 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -26,6 +26,7 @@ + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). ++- don't pass root to do_mount_autofs_offset(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 25ae2e1d..289500da 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2453,13 +2453,12 @@ out: + return rv; + } + +-static int do_mount_autofs_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root) ++static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe) + { + int mounted = 0; + int ret; + +- debug(ap->logopt, "mount offset %s at %s", oe->key, root); ++ debug(ap->logopt, "mount offset %s", oe->key); + + ret = mount_autofs_offset(ap, oe); + if (ret >= MOUNT_OFFSET_OK) +@@ -2651,7 +2650,7 @@ static int do_umount_offset(struct autofs_point *ap, + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); ++ ret = do_mount_autofs_offset(ap, oe); + if (ret) + left++; + /* But we did origianlly create this */ +@@ -2697,7 +2696,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + goto cont; + } + +- mounted += do_mount_autofs_offset(ap, oe, root); ++ mounted += do_mount_autofs_offset(ap, oe); + + /* + * If re-constructing a multi-mount it's necessary to walk diff --git a/SOURCES/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch b/SOURCES/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch new file mode 100644 index 0000000..d71cd3e --- /dev/null +++ b/SOURCES/autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch @@ -0,0 +1,45 @@ +autofs-5.1.7 - dont try umount after stat() ENOENT fail + +From: Ian Kent + +Coverity: Calling function "umount" that uses "me->key" after a check + function. This can cause a time-of-check, time-of-use race + condition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 7add6c55..c7bc0c39 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -57,6 +57,7 @@ + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). ++- dont try umount after stat() ENOENT fail. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index a33f9f91..3bd714e6 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + + ret = stat(me->key, &st); + if (ret == -1) { ++ int save_errno = errno; ++ + error(ap->logopt, + "failed to stat direct mount trigger %s", me->key); +- goto out_umount; ++ if (save_errno != ENOENT) ++ goto out_umount; ++ goto out_err; + } + + ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); diff --git a/SOURCES/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch b/SOURCES/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch new file mode 100644 index 0000000..ffd8817 --- /dev/null +++ b/SOURCES/autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch @@ -0,0 +1,112 @@ +autofs-5.1.7 - dont use realloc in host exports list processing + +From: Ian Kent + +If a server exports list is very large calling realloc(3) for each +export is slow. It's better to traverse the exports list twice, once +to calculate the length of the mapent then allocate the memory and +traverse the exports list again to construct the mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 59 +++++++++++++++++++++--------------------------- + 2 files changed, 27 insertions(+), 33 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 19af245e..1bd6ac7f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,7 @@ + + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. ++- dont use realloc in host exports list processing. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 81a4eb18..e3ee0ab8 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_point *ap, const char *host) + char buf[MAX_ERR_BUF]; + char *mapent; + struct exportinfo *exp, *this; ++ size_t hostlen = strlen(host); ++ size_t mapent_len; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + + exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER); + +- mapent = NULL; + this = exp; ++ mapent_len = 0; + while (this) { +- if (mapent) { +- int len = strlen(mapent) + 1; +- +- len += strlen(host) + 2*(strlen(this->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 NULL; +- } +- strcat(mapent, " \""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- } else { +- int len = 2*(strlen(this->dir) + 2) + strlen(host) + 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 NULL; +- } ++ mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; ++ this = this->next; ++ } ++ ++ mapent = malloc(mapent_len + 1); ++ if (!mapent) { ++ char *estr; ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++ *mapent = 0; ++ ++ this = exp; ++ while (this) { ++ if (!*mapent) + strcpy(mapent, "\""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- } ++ else ++ strcat(mapent, " \""); ++ strcat(mapent, this->dir); ++ strcat(mapent, "\""); ++ + strcat(mapent, " \""); + strcat(mapent, host); + strcat(mapent, ":"); +@@ -137,9 +133,6 @@ static char *get_exports(struct autofs_point *ap, const char *host) + } + rpc_exports_free(exp); + +- if (!mapent) +- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host); +- + return mapent; + } + diff --git a/SOURCES/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch b/SOURCES/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch new file mode 100644 index 0000000..ab6524d --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch @@ -0,0 +1,378 @@ +autofs-5.1.7 - eliminate cache_lookup_offset() usage + +From: Ian Kent + +The function cache_lookup_offset() will do a linear search when +looking for an offset. If the number of offsets is large this +can be a lot of overhead. + +But it's possible to use the information already present where +this is called to to do a hashed lookup instead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 82 +++++++++++++++++++++++++++++++++------------------ + modules/parse_sun.c | 77 ++++++++++++++++++++++++++++++------------------ + 3 files changed, 102 insertions(+), 58 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0b577909..484bd866 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. + - Fix option for master read wait. ++- eliminate cache_lookup_offset() usage. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index ccbd52e0..42e8ef07 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2495,24 +2495,27 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + char *offset = path; + struct mapent *oe; + struct list_head *pos = NULL; +- unsigned int fs_path_len; ++ unsigned int root_len = strlen(root); + int mounted; + +- fs_path_len = start + strlen(base); +- if (fs_path_len > PATH_MAX) +- return -1; +- + mounted = 0; + offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); + while (offset) { +- int plen = fs_path_len + strlen(offset); ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + +- if (plen > PATH_MAX) { ++ if (key_len > PATH_MAX) { + warn(ap->logopt, "path loo long"); + goto cont; + } + +- oe = cache_lookup_offset(base, offset, start, &me->multi_list); ++ /* The root offset is always mounted seperately so the ++ * offset path will always be root + offset. ++ */ ++ strcpy(key, root); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; + +@@ -2525,12 +2528,8 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + */ + if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { + if (oe->ioctlfd != -1 || +- is_mounted(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); +- } ++ is_mounted(oe->key, MNTS_REAL)) ++ mount_multi_triggers(ap, oe, key, strlen(key), base); + } + cont: + offset = cache_get_offset(base, +@@ -2584,6 +2583,8 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + const char o_root[] = "/"; + const char *mm_base; + int left, start; ++ unsigned int root_len; ++ unsigned int mm_base_len; + + left = 0; + start = strlen(root); +@@ -2597,11 +2598,28 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + + pos = NULL; + offset = path; ++ root_len = start; ++ mm_base_len = strlen(mm_base); + + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + char *oe_base; + +- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); ++ if (mm_base_len > 1) ++ key_len += mm_base_len; ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ continue; ++ } ++ ++ strcpy(key, root); ++ if (mm_base_len > 1) ++ strcat(key, mm_base); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + /* root offset is a special case */ + if (!oe || (strlen(oe->key) - start) == 1) + continue; +@@ -2686,13 +2704,14 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + 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; ++ unsigned int root_len; ++ unsigned int mm_base_len; + time_t age; + + if (top) +@@ -2720,14 +2739,30 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + + pos = NULL; + offset = path; ++ root_len = start; ++ mm_base_len = strlen(mm_base); + age = me->multi->age; + + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); + char *oe_base; +- char *key; + int ret; + +- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); ++ if (mm_base_len > 1) ++ key_len += mm_base_len; ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ continue; ++ } ++ ++ strcpy(key, root); ++ if (mm_base_len > 1) ++ strcat(key, mm_base); ++ strcat(key, offset); ++ ++ oe = cache_lookup_distinct(me->mc, key); + /* root offset is a special case */ + if (!oe || (strlen(oe->key) - start) == 1) + continue; +@@ -2778,14 +2813,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + } + } + +- 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)) { +@@ -2800,7 +2827,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + if (cache_delete_offset(oe->mc, key) == CHE_FAIL) + error(ap->logopt, + "failed to delete offset key %s", key); +- free(key); + continue; + } + +@@ -2816,7 +2842,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + left++; + /* But we did origianlly create this */ + oe->flags |= MOUNT_FLAG_DIR_CREATED; +- free(key); + continue; + } + /* +@@ -2834,7 +2859,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + error(ap->logopt, + "failed to delete offset key %s", key); + } +- free(key); + } + + return left; +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 4b137f99..819d6adc 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1086,6 +1086,8 @@ static void cleanup_multi_triggers(struct autofs_point *ap, + struct list_head *mm_root, *pos; + const char o_root[] = "/"; + const char *mm_base; ++ unsigned int root_len; ++ unsigned int mm_base_len; + + mm_root = &me->multi->multi_list; + +@@ -1095,16 +1097,31 @@ static void cleanup_multi_triggers(struct autofs_point *ap, + mm_base = base; + + pos = NULL; ++ root_len = strlen(root); ++ mm_base_len = strlen(mm_base); + + /* Make sure "none" of the offsets have an active mount. */ + while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) { +- oe = cache_lookup_offset(mm_base, poffset, start, &me->multi_list); +- /* root offset is a special case */ +- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) ++ unsigned int path_len = root_len + strlen(poffset); ++ ++ if (mm_base_len > 1) ++ path_len += mm_base_len; ++ ++ if (path_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); + continue; ++ } + + strcpy(path, root); ++ if (mm_base_len > 1) ++ strcat(path, mm_base); + strcat(path, poffset); ++ ++ oe = cache_lookup_distinct(me->mc, path); ++ /* root offset is a special case */ ++ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) ++ continue; ++ + if (umount(path)) { + error(ap->logopt, "error recovering from mount fail"); + error(ap->logopt, "cannot umount offset %s", path); +@@ -1117,17 +1134,14 @@ static void cleanup_multi_triggers(struct autofs_point *ap, + 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; +- unsigned int mm_root_len, mnt_root_len; ++ unsigned int mm_root_len; + int start, ret = 0, rv; + + rv = 0; + +- mm = me->multi; +- mm_key = mm->key; ++ mm_key = me->multi->key; + + if (*mm_key == '/') { + mm_root = mm_key; +@@ -1141,20 +1155,26 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + } + mm_root_len = strlen(mm_root); + +- mnt_root = mm_root; +- mnt_root_len = mm_root_len; +- + if (me == me->multi) { ++ char key[PATH_MAX + 1]; ++ ++ if (mm_root_len + 1 > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ return 1; ++ } ++ + /* name = NULL */ + /* destination = mm_root */ + mm_base = "/"; + ++ strcpy(key, mm_root); ++ strcat(key, mm_base); ++ + /* Mount root offset if it exists */ +- ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list); ++ ro = cache_lookup_distinct(me->mc, key); + if (ro) { +- char *myoptions, *ro_loc, *tmp; ++ char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; +- const char *root; + int ro_len; + + myoptions = NULL; +@@ -1172,13 +1192,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + if (ro_loc) + ro_len = strlen(ro_loc); + +- tmp = alloca(mnt_root_len + 2); +- strcpy(tmp, mnt_root); +- tmp[mnt_root_len] = '/'; +- tmp[mnt_root_len + 1] = '\0'; +- root = tmp; +- +- rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt); ++ rv = sun_mount(ap, key, name, namelen, ro_loc, ro_len, myoptions, ctxt); + + free(myoptions); + if (ro_loc) +@@ -1186,11 +1200,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + } + + if (ro && rv == 0) { +- ret = mount_multi_triggers(ap, me, mnt_root, start, mm_base); ++ 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, mnt_root, start, mm_base); ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } else if (rv <= 0) { +@@ -1206,24 +1220,29 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + int loclen = strlen(loc); + int namelen = strlen(name); + +- mnt_root = name; +- + /* name = mm_root + mm_base */ + /* destination = mm_root + mm_base = name */ + mm_base = &me->key[start]; + +- rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt); ++ rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); + if (rv == 0) { +- ret = mount_multi_triggers(ap, me->multi, mnt_root, start, mm_base); ++ ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); + if (ret == -1) { + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base); ++ cleanup_multi_triggers(ap, me, name, start, mm_base); + return 1; + } + } else if (rv < 0) { +- char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1); ++ char mm_root_base[PATH_MAX + 1]; ++ unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; + ++ if (mm_root_base_len > PATH_MAX) { ++ warn(ap->logopt, MODPREFIX "path too long"); ++ cache_delete_offset_list(me->mc, name); ++ return 1; ++ } ++ + strcpy(mm_root_base, mm_root); + strcat(mm_root_base, mm_base); + diff --git a/SOURCES/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch b/SOURCES/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch new file mode 100644 index 0000000..6c3a66f --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch @@ -0,0 +1,290 @@ +autofs-5.1.7 - eliminate clean_stale_multi_triggers() + +From: Ian Kent + +Eliminate clean_stale_multi_triggers() by checking for stale offsets at +the time mount_subtree() is called. + +This should result in the same behaviour but eliminate an additional +seperate traversal of the offset list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 209 ++++++++++----------------------------------------- + modules/parse_sun.c | 10 -- + 3 files changed, 43 insertions(+), 177 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5a3bedc1..b1ce7b69 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,7 @@ + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). ++- eliminate clean_stale_multi_triggers(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 5268ba5b..a9abbebf 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2601,10 +2601,44 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch + oe_base = oe->key + strlen(root); + left += do_umount_multi_triggers(ap, oe, root, oe_base); + ++ /* ++ * 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(oe->key, MNTS_REAL)) { +- left++; +- return left; ++ if (umount_ent(ap, oe->key) && ++ is_mounted(oe->key, MNTS_REAL)) { ++ debug(ap->logopt, ++ "offset %s has active mount, invalidate", ++ oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key. ++ */ ++ if (oe->mapent) { ++ free(oe->mapent); ++ oe->mapent = NULL; ++ } ++ return ++left; ++ } + } + + debug(ap->logopt, "umount offset %s", oe->key); +@@ -2666,6 +2700,11 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + oe = cache_lookup_distinct(me->mc, key); + if (!oe || !oe->mapent) + goto cont; ++ if (oe->age != me->multi->age) { ++ /* Best effort */ ++ do_umount_offset(ap, oe, root); ++ goto cont; ++ } + + mounted += do_mount_autofs_offset(ap, oe, root); + +@@ -2725,169 +2764,3 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + + 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 *offset; +- struct mapent *oe; +- struct list_head *mm_root, *pos; +- const char o_root[] = "/"; +- const char *mm_base; +- int left, start; +- unsigned int root_len; +- unsigned int mm_base_len; +- 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; +- root_len = start; +- mm_base_len = strlen(mm_base); +- age = me->multi->age; +- +- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- char *oe_base; +- int ret; +- +- if (mm_base_len > 1) +- key_len += mm_base_len; +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(key, root); +- if (mm_base_len > 1) +- strcat(key, mm_base); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- /* root offset is a special case */ +- if (!oe || (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(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { +- debug(ap->logopt, +- "offset %s has active mount, invalidate", +- oe->key); +- if (oe->mapent) { +- free(oe->mapent); +- oe->mapent = NULL; +- } +- 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); +- 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_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); +- if (ret) { +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- 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); +- } +- } +- +- return left; +-} +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index f42af7b7..f4d5125c 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1176,7 +1176,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +- if (ro) { ++ if (ro && ro->age == me->multi->age) { + char *myoptions, *ro_loc; + int namelen = name ? strlen(name) : 0; + int ro_len; +@@ -1610,14 +1610,6 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + +- /* +- * We've got the ordered list of multi-mount entries so go +- * 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); +- + rv = mount_subtree(ap, me, name, NULL, options, ctxt); + + cache_multi_unlock(me); diff --git a/SOURCES/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch b/SOURCES/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch new file mode 100644 index 0000000..f39885e --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch @@ -0,0 +1,140 @@ +autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect() + +From: Ian Kent + +The count_mounts() function traverses the directory tree under a given +automount in order to count the number of mounts. + +If there are many directories (such as when there is a very large +number of offset trigger mounts) this can take a long time. + +Eliminate the call in expire_proc_indirect() by changing the expire +ioctl function to better use the expire return from the kernel. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 4 ++-- + daemon/indirect.c | 10 +++++----- + lib/dev-ioctl-lib.c | 21 +++++++++++++-------- + 4 files changed, 21 insertions(+), 15 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c5619d2e..0b78eb62 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -20,6 +20,7 @@ + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. ++- eliminate count_mounts() from expire_proc_indirect(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index c41c680f..311a98ba 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -884,7 +884,7 @@ cont: + ioctlfd = me->ioctlfd; + + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) { ++ if (ret == 1) { + left++; + pthread_setcancelstate(cur_state, NULL); + continue; +@@ -910,7 +910,7 @@ cont: + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) ++ if (ret == 1) + left++; + pthread_setcancelstate(cur_state, NULL); + } +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 65cfe4e3..b259ebdc 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -358,7 +358,6 @@ void *expire_proc_indirect(void *arg) + struct expire_args ec; + unsigned int how; + int offsets, submnts, count; +- int retries; + int ioctlfd, cur_state; + int status, ret, left; + +@@ -496,7 +495,7 @@ void *expire_proc_indirect(void *arg) + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how); +- if (ret) ++ if (ret == 1) + left++; + pthread_setcancelstate(cur_state, NULL); + } +@@ -507,10 +506,11 @@ void *expire_proc_indirect(void *arg) + * so we need to umount or unlink them here. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- retries = (count_mounts(ap, ap->path, ap->dev) + 1); +- while (retries--) { ++ while (1) { + ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how); +- if (ret) ++ if (ret != 0 && errno == EAGAIN) ++ break; ++ if (ret == 1) + left++; + } + pthread_setcancelstate(cur_state, NULL); +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index 7040c3da..e7a1b42a 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -650,6 +650,7 @@ static int expire(unsigned int logopt, + { + int ret, retries = EXPIRE_RETRIES; + unsigned int may_umount; ++ int save_errno = 0; + + while (retries--) { + struct timespec tm = {0, 100000000}; +@@ -657,9 +658,11 @@ static int expire(unsigned int logopt, + /* Ggenerate expire message for the mount. */ + ret = ioctl(fd, cmd, arg); + if (ret == -1) { ++ save_errno = errno; ++ + /* Mount has gone away */ + if (errno == EBADF || errno == EINVAL) +- return 0; ++ break; + + /* + * Other than EAGAIN is an expire error so continue. +@@ -673,14 +676,16 @@ static int expire(unsigned int logopt, + nanosleep(&tm, NULL); + } + +- may_umount = 0; +- if (ctl.ops->askumount(logopt, ioctlfd, &may_umount)) +- return -1; +- +- if (!may_umount) +- return 1; ++ if (!ret || save_errno == EAGAIN) { ++ may_umount = 0; ++ if (!ctl.ops->askumount(logopt, ioctlfd, &may_umount)) { ++ if (!may_umount) ++ ret = 1; ++ } ++ } ++ errno = save_errno; + +- return 0; ++ return ret; + } + + static int dev_ioctl_expire(unsigned int logopt, diff --git a/SOURCES/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch b/SOURCES/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch new file mode 100644 index 0000000..14ca019 --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch @@ -0,0 +1,82 @@ +autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache (from a list.h list) there's no need to lookup the +mapent in tree_mapent_add_node() and validate it. Just use it directly +when calling tree_mapent_add_node() and avoid a cache lookup on every +node addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 13 ++----------- + modules/parse_sun.c | 2 +- + 4 files changed, 5 insertions(+), 13 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -71,6 +71,7 @@ + - fix amd hosts mount expire. + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). ++- eliminate redundant cache lookup in tree_mapent_add_node(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/include/mounts.h ++++ autofs-5.1.7/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- struct tree_node *root, const char *key) ++ struct tree_node *root, struct mapent *me) + { +- unsigned int logopt = mc->ap->logopt; + struct tree_node *n; + struct mapent *parent; +- struct mapent *me; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) { +- error(logopt, +- "failed to find key %s of multi-mount", key); +- return 0; +- } + + n = tree_add_node(root, me); + if (!n) +@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_c + MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ +- parent = cache_get_offset_parent(mc, key); ++ parent = cache_get_offset_parent(mc, me->key); + if (!parent) + MAPENT_SET_PARENT(me, root) + else +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -1546,7 +1546,7 @@ dont_expand: + return 1; + } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/SOURCES/autofs-5.1.7-eliminate-some-more-alloca-usage.patch b/SOURCES/autofs-5.1.7-eliminate-some-more-alloca-usage.patch new file mode 100644 index 0000000..092ef9a --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-some-more-alloca-usage.patch @@ -0,0 +1,217 @@ +autofs-5.1.7 - eliminate some more alloca usage + +From: Ian Kent + +Quite a bit of the alloca(3) usage has been eliminated over time. +Use malloc(3) for some more cases that might need to allocate a largish +amount of storage. + +Signed-off-by: Ian Kent +--- + +autofs-5.1.7 - eliminate some more alloca usage + +From: Ian Kent + +Quite a bit of the alloca(3) usage has been eliminated over time. +Use malloc(3) for some more cases that might need to allocate a largish +amount of storage. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_program.c | 11 ++++++++++- + modules/lookup_yp.c | 22 +++++++++++++++++++--- + modules/parse_sun.c | 18 ++++++++++++++---- + modules/replicated.c | 19 ++++++------------- + 5 files changed, 50 insertions(+), 21 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -78,6 +78,7 @@ + - add missing description of null map option. + - fix nonstrict offset mount fail handling. + - fix concat_options() error handling. ++- eliminate some more alloca usage. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/lookup_program.c ++++ autofs-5.1.7/modules/lookup_program.c +@@ -636,7 +636,14 @@ int lookup_mount(struct autofs_point *ap + char *ent = NULL; + + if (me->mapent) { +- ent = alloca(strlen(me->mapent) + 1); ++ ent = malloc(strlen(me->mapent) + 1); ++ if (!ent) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ goto out_free; ++ } + strcpy(ent, me->mapent); + } + cache_unlock(mc); +@@ -644,6 +651,8 @@ int lookup_mount(struct autofs_point *ap + ap->entry->current = source; + ret = ctxt->parse->parse_mount(ap, name, + name_len, ent, ctxt->parse->context); ++ if (ent) ++ free(ent); + goto out_free; + } else { + if (IS_MM(me) && !IS_MM_ROOT(me)) { +--- autofs-5.1.7.orig/modules/lookup_yp.c ++++ autofs-5.1.7/modules/lookup_yp.c +@@ -254,7 +254,7 @@ int yp_all_master_callback(int status, c + + len = ypkeylen + 1 + vallen + 2; + +- buffer = alloca(len); ++ buffer = malloc(len); + if (!buffer) { + error(logopt, MODPREFIX "could not malloc parse buffer"); + return 0; +@@ -267,6 +267,8 @@ int yp_all_master_callback(int status, c + + master_parse_entry(buffer, timeout, logging, age); + ++ free(buffer); ++ + return 0; + } + +@@ -368,7 +370,12 @@ int yp_all_callback(int status, char *yp + return 0; + } + +- mapent = alloca(vallen + 1); ++ mapent = malloc(vallen + 1); ++ if (!mapent) { ++ error(logopt, MODPREFIX "could not malloc mapent buffer"); ++ free(key); ++ return 0; ++ } + strncpy(mapent, val, vallen); + *(mapent + vallen) = '\0'; + +@@ -377,6 +384,7 @@ int yp_all_callback(int status, char *yp + cache_unlock(mc); + + free(key); ++ free(mapent); + + if (ret == CHE_FAIL) + return -1; +@@ -904,7 +912,14 @@ int lookup_mount(struct autofs_point *ap + } + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); +- mapent = alloca(mapent_len + 1); ++ mapent = malloc(mapent_len + 1); ++ if (!mapent) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ free(lkp_key); ++ return NSS_STATUS_TRYAGAIN; ++ } + strcpy(mapent, me->mapent); + } + } +@@ -929,6 +944,7 @@ int lookup_mount(struct autofs_point *ap + + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); ++ free(mapent); + if (ret) { + /* Don't update negative cache when re-connecting */ + if (ap->flags & MOUNT_FLAG_REMOUNT) +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -668,9 +668,16 @@ static int sun_mount(struct autofs_point + } + } + ++ what = malloc(loclen + 1); ++ if (!what) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) { +- what = alloca(loclen + 1); + memcpy(what, loc, loclen); + what[loclen] = '\0'; + +@@ -706,10 +713,10 @@ static int sun_mount(struct autofs_point + rv = mount_nfs->mount_mount(ap, root, name, namelen, + what, fstype, options, mount_nfs->context); + } else { +- if (!loclen) ++ if (!loclen) { ++ free(what); + what = NULL; +- else { +- what = alloca(loclen + 1); ++ } else { + if (*loc == ':') { + loclen--; + memcpy(what, loc + 1, loclen); +@@ -728,6 +735,9 @@ static int sun_mount(struct autofs_point + /* Generic mount routine */ + rv = do_mount(ap, root, name, namelen, what, fstype, options); + } ++ if (what) ++ free(what); ++ + pthread_setcancelstate(cur_state, NULL); + + if (nonstrict && rv) +--- autofs-5.1.7.orig/modules/replicated.c ++++ autofs-5.1.7/modules/replicated.c +@@ -1041,25 +1041,18 @@ done: + return ret; + } + +-static int add_path(struct host *hosts, const char *path, int len) ++static int add_path(struct host *hosts, const char *path) + { + struct host *this; +- char *tmp, *tmp2; +- +- tmp = alloca(len + 1); +- if (!tmp) +- return 0; +- +- strncpy(tmp, path, len); +- tmp[len] = '\0'; ++ char *tmp; + + this = hosts; + while (this) { + if (!this->path) { +- tmp2 = strdup(tmp); +- if (!tmp2) ++ tmp = strdup(path); ++ if (!tmp) + return 0; +- this->path = tmp2; ++ this->path = tmp; + } + this = this->next; + } +@@ -1188,7 +1181,7 @@ int parse_location(unsigned logopt, stru + } + } + +- if (!add_path(*hosts, path, strlen(path))) { ++ if (!add_path(*hosts, path)) { + free_host_list(hosts); + free(str); + return 0; diff --git a/SOURCES/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch b/SOURCES/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch new file mode 100644 index 0000000..29aabc6 --- /dev/null +++ b/SOURCES/autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch @@ -0,0 +1,128 @@ +autofs-5.1.7 - eliminate some strlen calls in offset handling + +From: Ian Kent + +There are a number of places where strlen() is used to re-calculate +the length of a string. Eliminate some of those by calculating the +length once and passing it to the functions that do the re-calculation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 30 +++++++++++++++++------------- + 2 files changed, 18 insertions(+), 13 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0b78eb62..cb709773 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -21,6 +21,7 @@ + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). ++- eliminate some strlen calls in offset handling. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 0fcd4087..04fe3d00 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2540,10 +2540,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + return ret; + } + +-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root); ++static int do_umount_offset(struct autofs_point *ap, ++ struct mapent *oe, const char *root, int start); + + static int do_umount_multi_triggers(struct autofs_point *ap, +- struct mapent *me, const char *root, const char *base) ++ struct mapent *me, const char *root, ++ int start, const char *base) + { + char path[PATH_MAX + 1]; + char *offset; +@@ -2551,12 +2553,11 @@ static int do_umount_multi_triggers(struct autofs_point *ap, + struct list_head *mm_root, *pos; + const char o_root[] = "/"; + const char *mm_base; +- int left, start; ++ int left; + unsigned int root_len; + unsigned int mm_base_len; + + left = 0; +- start = strlen(root); + + mm_root = &me->multi->multi_list; + +@@ -2592,13 +2593,14 @@ static int do_umount_multi_triggers(struct autofs_point *ap, + if (!oe || (strlen(oe->key) - start) == 1) + continue; + +- left += do_umount_offset(ap, oe, root); ++ left += do_umount_offset(ap, oe, root, start); + } + + return left; + } + +-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root) ++static int do_umount_offset(struct autofs_point *ap, ++ struct mapent *oe, const char *root, int start) + { + char *oe_base; + int left = 0; +@@ -2607,8 +2609,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch + * Check for and umount subtree offsets resulting from + * nonstrict mount fail. + */ +- oe_base = oe->key + strlen(root); +- left += do_umount_multi_triggers(ap, oe, root, oe_base); ++ oe_base = oe->key + start; ++ left += do_umount_multi_triggers(ap, oe, root, start, oe_base); + + /* + * If an offset that has an active mount has been removed +@@ -2712,7 +2714,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + goto cont; + if (oe->age != me->multi->age) { + /* Best effort */ +- do_umount_offset(ap, oe, root); ++ do_umount_offset(ap, oe, root, start); + goto cont; + } + +@@ -2726,7 +2728,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) { + if (oe->ioctlfd != -1 || + is_mounted(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, strlen(key), base); ++ mount_multi_triggers(ap, oe, key, key_len, base); + } + cont: + offset = cache_get_offset(base, +@@ -2738,9 +2740,11 @@ cont: + + int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) + { +- int left; ++ int left, start; ++ ++ start = strlen(root); + +- left = do_umount_multi_triggers(ap, me, root, base); ++ left = do_umount_multi_triggers(ap, me, root, start, base); + + if (!left && me->multi == me) { + /* +@@ -2753,7 +2757,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + info(ap->logopt, "unmounting dir = %s", root); + if (umount_ent(ap, root) && + is_mounted(root, MNTS_REAL)) { +- if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) ++ if (mount_multi_triggers(ap, me, root, start, "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); + return ++left; diff --git a/SOURCES/autofs-5.1.7-fix-amd-hosts-mount-expire.patch b/SOURCES/autofs-5.1.7-fix-amd-hosts-mount-expire.patch new file mode 100644 index 0000000..baeaa40 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-amd-hosts-mount-expire.patch @@ -0,0 +1,48 @@ +autofs-5.1.7 - fix amd hosts mount expire + +From: Ian Kent + +When swicthing to use the mnt_list to track mounts for expire, if the +amd hosts map entry name is for the host short name, the amd mount +entry for the short name gets removed. This causes a subsequent mounts +for host exports to fail. + +What should happen is the short name amd entry not be removed and a +mounted mount entry for the symlinked FQDN mount added so it expires. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 9 +++++---- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -68,6 +68,7 @@ + - add ext_mount_hash_mutex lock helpers. + - fix dangling symlink creation if nis support is not available. + - fix amd section mounts map reload. ++- fix amd hosts mount expire. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/parse_amd.c ++++ autofs-5.1.7/modules/parse_amd.c +@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, + if (!rv) { + /* + * If entry->path doesn't match the mnt->mp then +- * the mount point path has changed and a new +- * mnt_list entry added for it, so remove the +- * original. ++ * it's a "host" map and the mount point path is ++ * different to the lookup name. Add a new mnt_list ++ * entry so that both the symlinked name and the ++ * mount expire. + */ + if (strcmp(this->path, mnt->mp)) +- mnts_remove_amdmount(this->path); ++ mnts_add_mount(ap, this->rhost, MNTS_INDIRECT|MNTS_MOUNTED); + break; + } + /* Not mounted, remove the mnt_list entry from amdmount list */ diff --git a/SOURCES/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch b/SOURCES/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch new file mode 100644 index 0000000..2bb5968 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-amd-section-mounts-map-reload.patch @@ -0,0 +1,120 @@ +autofs-5.1.7 - fix amd section mounts map reload + +From: Ian Kent + +Master map section mounts (amd format mounts) get umounted on reload. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/master.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 81 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -67,6 +67,7 @@ + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. + - fix dangling symlink creation if nis support is not available. ++- fix amd section mounts map reload. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/master.c ++++ autofs-5.1.7/daemon/master.c +@@ -882,6 +882,83 @@ struct master *master_new(const char *na + return master; + } + ++static void master_update_amd_mount_section_mount(struct master *master, ++ const char *path, time_t age) ++{ ++ unsigned int m_logopt = master->logopt; ++ struct master_mapent *entry; ++ struct map_source *source; ++ unsigned int loglevel; ++ unsigned int logopt; ++ unsigned int flags; ++ time_t timeout; ++ char *map; ++ char *opts; ++ ++ entry = master_find_mapent(master, path); ++ if (!entry) ++ return; ++ ++ map = conf_amd_get_map_name(path); ++ if (!map) ++ return; ++ ++ /* amd top level mounts have only one map */ ++ source = entry->maps; ++ if (strcmp(source->name, map) != 0) { ++ struct map_source *new; ++ char *type; ++ char *argv[2]; ++ ++ type = conf_amd_get_map_type(path); ++ argv[0] = map; ++ argv[1] = NULL; ++ ++ new = master_add_map_source(entry, type, "amd", ++ age, 1, (const char **) argv); ++ if (!new) { ++ error(m_logopt, ++ "failed to add source for amd section mount %s", ++ path); ++ if (type) ++ free(type); ++ goto out; ++ } ++ master_free_map_source(source, 0); ++ entry->maps = new; ++ source = new; ++ if (type) ++ free(type); ++ } ++ ++ loglevel = conf_amd_get_log_options(); ++ logopt = m_logopt; ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ flags = conf_amd_get_flags(path); ++ if (flags & CONF_BROWSABLE_DIRS) ++ entry->ap->flags |= MOUNT_FLAG_GHOST; ++ ++ opts = conf_amd_get_map_options(path); ++ if (opts) { ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ ++ entry->ap->logopt = logopt; ++ ++ timeout = conf_amd_get_dismount_interval(path); ++ set_exp_timeout(entry->ap, source, timeout); ++ source->master_line = 0; ++ entry->age = age; ++out: ++ free(map); ++} ++ + static void master_add_amd_mount_section_mounts(struct master *master, time_t age) + { + unsigned int m_logopt = master->logopt; +@@ -916,8 +993,10 @@ static void master_add_amd_mount_section + * master map it's not a duplicate, don't issue + * an error message. + */ +- if (ret == 1) ++ if (ret == 1) { ++ master_update_amd_mount_section_mount(master, path, age); + goto next; ++ } + info(m_logopt, + "amd section mount path conflict, %s ignored", + path); diff --git a/SOURCES/autofs-5.1.7-fix-arg-not-used-in-print.patch b/SOURCES/autofs-5.1.7-fix-arg-not-used-in-print.patch new file mode 100644 index 0000000..52b8a6e --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-arg-not-used-in-print.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - fix arg not used in error print + +From: Ian Kent + +Coverity: extra_argument: This argument was not used by the format + string: "key". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f11aa1c7..1d56c96f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -60,6 +60,7 @@ + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). ++- fix arg not used in error print. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 018b9c80..883e3743 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc, + } + + if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, +- "failed to find multi-mount root of offset tree", +- key); ++ error(logopt, "key %s is not multi-mount root", root); + return 0; + } + tree = MAPENT_ROOT(base); diff --git a/SOURCES/autofs-5.1.7-fix-concat_options-error-handling.patch b/SOURCES/autofs-5.1.7-fix-concat_options-error-handling.patch new file mode 100644 index 0000000..4b837f4 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-concat_options-error-handling.patch @@ -0,0 +1,120 @@ +autofs-5.1.7 - fix concat_options() error handling + +From: Ian Kent + +There's a possibility of a memory leak in the mount options processing +when calling concat_options() in parse_mount() of the Sun format map +entry parsing. + +There's also a case in do_init() of the Sun map format parsing where +a previously freed value is used in a logging statement without being +set to MULL. + +So ensure concat_options() always frees it's arguments so that the +handling can be consistent in all places. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 24 +++++++++++------------- + 2 files changed, 12 insertions(+), 13 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -77,6 +77,7 @@ + - fix lookup_prune_one_cache() refactoring change. + - add missing description of null map option. + - fix nonstrict offset mount fail handling. ++- fix concat_options() error handling. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -380,7 +380,8 @@ static int do_init(int argc, const char + if (!tmp) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "concat_options: %s", estr); +- free(gbl_options); ++ /* freed in concat_options */ ++ ctxt->optstr = NULL; + } else + ctxt->optstr = tmp; + } else { +@@ -492,12 +493,16 @@ static char *concat_options(char *left, + char *ret; + + if (left == NULL || *left == '\0') { ++ if (!right || *right == '\0') ++ return NULL; + ret = strdup(right); + free(right); + return ret; + } + + if (right == NULL || *right == '\0') { ++ if (left == NULL || *left == '\0') ++ return NULL; + ret = strdup(left); + free(left); + return ret; +@@ -508,6 +513,8 @@ static char *concat_options(char *left, + if (ret == NULL) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "malloc: %s", estr); ++ free(left); ++ free(right); + return NULL; + } + +@@ -989,14 +996,13 @@ static int parse_mapent(const char *ent, + if (newopt && strstr(newopt, myoptions)) { + free(myoptions); + myoptions = newopt; +- } else { ++ } else if (newopt) { + tmp = concat_options(myoptions, newopt); + if (!tmp) { + char *estr; + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX + "concat_options: %s", estr); +- free(myoptions); + return 0; + } + myoptions = tmp; +@@ -1358,16 +1364,12 @@ dont_expand: + if (mnt_options && noptions && strstr(noptions, mnt_options)) { + free(mnt_options); + mnt_options = noptions; +- } else { ++ } else if (noptions) { + tmp = concat_options(mnt_options, noptions); + if (!tmp) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + MODPREFIX "concat_options: %s", estr); +- if (noptions) +- free(noptions); +- if (mnt_options) +- free(mnt_options); + free(options); + free(pmapent); + return 1; +@@ -1387,15 +1389,11 @@ dont_expand: + if (options && mnt_options && strstr(mnt_options, options)) { + free(options); + options = mnt_options; +- } else { ++ } else if (mnt_options) { + tmp = concat_options(options, mnt_options); + if (!tmp) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, MODPREFIX "concat_options: %s", estr); +- if (options) +- free(options); +- if (mnt_options) +- free(mnt_options); + free(pmapent); + return 1; + } diff --git a/SOURCES/autofs-5.1.7-fix-dangling-symlink-creation-if-nis-support-is-not-available.patch b/SOURCES/autofs-5.1.7-fix-dangling-symlink-creation-if-nis-support-is-not-available.patch new file mode 100644 index 0000000..778dfa2 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-dangling-symlink-creation-if-nis-support-is-not-available.patch @@ -0,0 +1,35 @@ +autofs-5.1.7 - fix dangling symlink creation if nis support is not available + +From: Ian Kent + +If NIS support is not available a dangling symlink is created pointing +from lookup_nis.so to (a non-existent) lookup_yp.so. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/Makefile | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -66,6 +66,7 @@ + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. ++- fix dangling symlink creation if nis support is not available. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/modules/Makefile ++++ autofs-5.1.7/modules/Makefile +@@ -77,7 +77,9 @@ install: all + install -c $(MODS) -m 755 $(INSTALLROOT)$(autofslibdir) + -rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so + ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so ++ifeq ($(YPCLNT), 1) + ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so ++endif + ifeq ($(LDAP), 1) + ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so + endif diff --git a/SOURCES/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch b/SOURCES/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch new file mode 100644 index 0000000..a32bf7b --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch @@ -0,0 +1,55 @@ +autofs-5.1.7 - fix dead code in mnts_add_mount() + +From: Ian Kent + +Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 ++------ + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f95b1aa6..f11aa1c7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -59,6 +59,7 @@ + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). ++- fix dead code in mnts_add_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index ef69cec1..018b9c80 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + if (*name == '/') { + mp = strdup(name); + if (!mp) +- goto fail; ++ return NULL; + } else { + int len = ap->len + strlen(name) + 2; + + mp = malloc(len); + if (!mp) +- goto fail; ++ return NULL; + strcpy(mp, ap->path); + strcat(mp, "/"); + strcat(mp, name); +@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap, + free(mp); + + return this; +-fail: +- if (mp) +- free(mp); +- return NULL; + } + + void mnts_remove_mount(const char *mp, unsigned int flags) diff --git a/SOURCES/autofs-5.1.7-fix-direct-mount-deadlock.patch b/SOURCES/autofs-5.1.7-fix-direct-mount-deadlock.patch new file mode 100644 index 0000000..ee08d24 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-direct-mount-deadlock.patch @@ -0,0 +1,129 @@ +autofs-5.1.7 - fix direct mount deadlock + +From: Ian Kent + +When umounting direct mounts at exit or when umounting mounts no +longer in the map on re-load a deadlock can occur. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 22 +++++++++++++++++++++- + daemon/state.c | 14 +++++++++----- + 3 files changed, 31 insertions(+), 6 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -73,6 +73,7 @@ + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. ++- fix direct mount deadlock. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/direct.c ++++ autofs-5.1.7/daemon/direct.c +@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg) + int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); ++ struct mapent_cache *mc = me->mc; + char buf[MAX_ERR_BUF]; + int ioctlfd = -1, rv, left, retries; ++ char key[PATH_MAX + 1]; ++ struct mapent *tmp; + int opened = 0; + +- left = umount_multi(ap, me->key, 0); ++ if (me->len > PATH_MAX) { ++ error(ap->logopt, "path too long"); ++ return 1; ++ } ++ strcpy(key, me->key); ++ ++ cache_unlock(mc); ++ left = umount_multi(ap, key, 0); ++ cache_readlock(mc); ++ tmp = cache_lookup_distinct(mc, key); ++ if (tmp != me) { ++ error(ap->logopt, "key %s no longer in mapent cache", key); ++ return -1; ++ } + if (left) { + warn(ap->logopt, "could not unmount %d dirs under %s", + left, me->key); +@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_p + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { + int error; +@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_p + * failed umount. + */ + error = do_umount_autofs_direct(ap, me); ++ /* cache became invalid, restart */ ++ if (error == -1) ++ goto restart; + if (!error) + goto done; + +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/daemon/state.c +@@ -324,11 +324,12 @@ static void do_readmap_cleanup(void *arg + return; + } + +-static void do_readmap_mount(struct autofs_point *ap, ++static int do_readmap_mount(struct autofs_point *ap, + struct map_source *map, struct mapent *me, time_t now) + { + struct mapent_cache *nc; + struct mapent *ne, *nested, *valid; ++ int ret = 0; + + nc = ap->entry->master->nc; + +@@ -387,7 +388,7 @@ static void do_readmap_mount(struct auto + cache_unlock(vmc); + error(ap->logopt, + "failed to find expected existing valid map entry"); +- return; ++ return ret; + } + /* Take over the mount if there is one */ + valid->ioctlfd = me->ioctlfd; +@@ -406,14 +407,14 @@ static void do_readmap_mount(struct auto + ap->exp_runfreq = runfreq; + } + } else if (!is_mounted(me->key, MNTS_REAL)) +- do_umount_autofs_direct(ap, me); ++ ret = do_umount_autofs_direct(ap, me); + else + debug(ap->logopt, + "%s is mounted", me->key); + } else + do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map)); + +- return; ++ return ret; + } + + static void *do_readmap(void *arg) +@@ -480,9 +481,12 @@ static void *do_readmap(void *arg) + mc = map->mc; + pthread_cleanup_push(cache_lock_cleanup, mc); + cache_readlock(mc); ++restart: + me = cache_enumerate(mc, NULL); + while (me) { +- do_readmap_mount(ap, map, me, now); ++ int ret = do_readmap_mount(ap, map, me, now); ++ if (ret == -1) ++ goto restart; + me = cache_enumerate(mc, me); + } + lookup_prune_one_cache(ap, map->mc, now); diff --git a/SOURCES/autofs-5.1.7-fix-double-free-in-parse_mapent.patch b/SOURCES/autofs-5.1.7-fix-double-free-in-parse_mapent.patch new file mode 100644 index 0000000..64ec0c8 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-double-free-in-parse_mapent.patch @@ -0,0 +1,39 @@ +autofs-5.1.7 - fix double free in parse_mapent() + +From: Ian Kent + +Coverity: +in parse_mapent(): double_free: Calling "free" frees pointer "newopt" + which has already been freed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 2 -- + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ff3d88eb..81461978 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -62,6 +62,7 @@ + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). ++- fix double free in parse_mapent(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 5d15f892..03a63290 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char * + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(logopt, MODPREFIX + "concat_options: %s", estr); +- if (newopt) +- free(newopt); + free(myoptions); + return 0; + } diff --git a/SOURCES/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch b/SOURCES/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch new file mode 100644 index 0000000..d08b942 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-double-unlock-in-parse_mount.patch @@ -0,0 +1,37 @@ +autofs-5.1.7 - fix double unlock in parse_mount() + +From: Ian Kent + +Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it + is unlocked. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2e3b9fd7..224f58d6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -54,6 +54,7 @@ + - remove redundant if check. + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). ++- fix double unlock in parse_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index a81d4028..05f53fc2 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1526,7 +1526,6 @@ dont_expand: + if (!loc) { + free(options); + free(pmapent); +- cache_unlock(mc); + warn(ap->logopt, MODPREFIX "out of memory"); + return 1; + } diff --git a/SOURCES/autofs-5.1.7-fix-flag-check-in-umount_multi.patch b/SOURCES/autofs-5.1.7-fix-flag-check-in-umount_multi.patch new file mode 100644 index 0000000..eaa784c --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-flag-check-in-umount_multi.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - fix flags check in umount_multi() + +From: Ian Kent + +Coverity: operator_confusion: "ap->flags | 1" is always 1/true + regardless of the values of its operand. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 9e385ba9..7add6c55 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -56,6 +56,7 @@ + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). ++- fix flags check in umount_multi(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 70506d83..23235a7d 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) + /* Check if the autofs mount has browse mode enabled. + * If so re-create the directory entry. + */ +- if (ap->flags | MOUNT_FLAG_GHOST) { ++ if (ap->flags & MOUNT_FLAG_GHOST) { + int ret; + + /* If the browse directory create fails log an diff --git a/SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch b/SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch new file mode 100644 index 0000000..3fcf58f --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch @@ -0,0 +1,289 @@ +autofs-5.1.7 - fix hosts map offset order + +From: Ian Kent + +Map entry offset paths to be in shortest to longest order but exports +from a server could come in any order. If there are a large number of +exports this can result in a lot of overhead when adding the offset +to the ordered list use to mount the offset during parsing since the +path length of exports can cary a lot. + +So leverage the tree implemention to sort the export offsets into +shortest to longest order as we go when constructing the mapent from +the exports list. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 2 - + include/mounts.h | 8 +++++ + include/rpc_subs.h | 3 ++ + lib/mounts.c | 57 +++++++++++++++++++++++++++++++++++++-- + modules/lookup_hosts.c | 71 ++++++++++++++++++++++++++++++++++++++----------- + 6 files changed, 124 insertions(+), 18 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -72,6 +72,7 @@ + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). ++- fix hosts map offset order. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -31,9 +31,9 @@ + #include "master.h" + #include "macros.h" + #include "log.h" ++#include "mounts.h" + #include "rpc_subs.h" + #include "parse_subs.h" +-#include "mounts.h" + #include "dev-ioctl-lib.h" + #include "parse_amd.h" + +--- autofs-5.1.7.orig/include/mounts.h ++++ autofs-5.1.7/include/mounts.h +@@ -52,6 +52,7 @@ extern const unsigned int t_direct; + extern const unsigned int t_offset; + + struct mnt_list; ++struct exportinfo; + struct mapent; + + struct tree_ops; +@@ -66,6 +67,9 @@ struct tree_node { + #define MNT_LIST(n) (container_of(n, struct mnt_list, node)) + #define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) + ++#define EXPORTINFO(n) (container_of(n, struct exportinfo, node)) ++#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node) ++ + #define MAPENT(n) (container_of(n, struct mapent, node)) + #define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node) + #define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root) +@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); + unsigned int mnts_has_mounted_mounts(struct autofs_point *ap); ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr); ++void tree_free(struct tree_node *root); + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap); + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); ++struct tree_node *tree_host_root(struct exportinfo *exp); ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp); + struct tree_node *tree_mapent_root(struct mapent *me); + int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); +--- autofs-5.1.7.orig/include/rpc_subs.h ++++ autofs-5.1.7/include/rpc_subs.h +@@ -23,6 +23,8 @@ + #include + #include + ++#include "automount.h" ++ + #define NFS4_VERSION 4 + + /* rpc helper subs */ +@@ -57,6 +59,7 @@ struct exportinfo { + char *dir; + struct hostinfo *hosts; + struct exportinfo *next; ++ struct tree_node node; + }; + + struct conn_info { +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = { + }; + static struct tree_ops *tree_mnt_ops = &mnt_ops; + ++static struct tree_node *tree_host_new(void *ptr); ++static int tree_host_cmp(struct tree_node *n, void *ptr); ++static void tree_host_free(struct tree_node *n); ++ ++static struct tree_ops host_ops = { ++ .new = tree_host_new, ++ .cmp = tree_host_cmp, ++ .free = tree_host_free, ++}; ++static struct tree_ops *tree_host_ops = &host_ops; ++ + static struct tree_node *tree_mapent_new(void *ptr); + static int tree_mapent_cmp(struct tree_node *n, void *ptr); + static void tree_mapent_free(struct tree_node *n); +@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s + return NULL; + } + +-static void tree_free(struct tree_node *root) ++void tree_free(struct tree_node *root) + { + struct tree_ops *ops = root->ops; + +@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node * + ops->free(root); + } + +-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) ++int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) + { + int ret; + +@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he + mnts_hash_mutex_unlock(); + } + ++struct tree_node *tree_host_root(struct exportinfo *exp) ++{ ++ return tree_root(tree_host_ops, exp); ++} ++ ++static struct tree_node *tree_host_new(void *ptr) ++{ ++ struct tree_node *n = EXPORT_NODE(ptr); ++ ++ n->ops = tree_host_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_host_cmp(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *n_exp = EXPORTINFO(n); ++ size_t n_exp_len = strlen(n_exp->dir); ++ struct exportinfo *exp = ptr; ++ size_t exp_len = strlen(exp->dir); ++ int eq; ++ ++ eq = strcmp(exp->dir, n_exp->dir); ++ if (!eq) ++ return 0; ++ return (exp_len < n_exp_len) ? -1 : 1; ++} ++ ++static void tree_host_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ ++struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp) ++{ ++ return tree_add_node(root, exp); ++} ++ + struct tree_node *tree_mapent_root(struct mapent *me) + { + return tree_root(tree_mapent_ops, me); +--- autofs-5.1.7.orig/modules/lookup_hosts.c ++++ autofs-5.1.7/modules/lookup_hosts.c +@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma + return NSS_STATUS_UNKNOWN; + } + ++struct work_info { ++ char *mapent; ++ const char *host; ++ int pos; ++}; ++ ++static int tree_host_work(struct tree_node *n, void *ptr) ++{ ++ struct exportinfo *exp = EXPORTINFO(n); ++ struct work_info *wi = ptr; ++ int len; ++ ++ if (!wi->pos) ++ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ else ++ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"", ++ exp->dir, wi->host, exp->dir); ++ wi->pos += len; ++ ++ return 1; ++} ++ + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; + char *mapent; + struct exportinfo *exp, *this; ++ struct tree_node *tree = NULL; ++ struct work_info wi; + size_t hostlen = strlen(host); + size_t mapent_len; +- int len, pos; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p + this = exp; + mapent_len = 0; + while (this) { ++ struct tree_node *n; ++ + mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3; ++ ++ if (!tree) { ++ tree = tree_host_root(this); ++ if (!tree) { ++ error(ap->logopt, "failed to create exports tree root"); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++ goto next; ++ } ++ ++ n = tree_host_add_node(tree, this); ++ if (!n) { ++ error(ap->logopt, "failed to add exports tree node"); ++ tree_free(tree); ++ rpc_exports_free(exp); ++ return NULL; ++ } ++next: + this = this->next; + } + +@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p + } + *mapent = 0; + +- pos = 0; +- this = exp; +- if (this) { +- len = sprintf(mapent, "\"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; +- } +- +- while (this) { +- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"", +- this->dir, host, this->dir); +- pos += len; +- this = this->next; ++ wi.mapent = mapent; ++ wi.host = host; ++ wi.pos = 0; ++ ++ if (!tree) { ++ free(mapent); ++ mapent = NULL; ++ } else { ++ tree_traverse_inorder(tree, tree_host_work, &wi); ++ tree_free(tree); + } + rpc_exports_free(exp); + diff --git a/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch b/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch new file mode 100644 index 0000000..34f3171 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch @@ -0,0 +1,251 @@ +autofs-5.1.7 - fix inconsistent locking in parse_mount() + +From: Ian Kent + +Some map entry cache locking inconsistencies have crept in. + +In parse_mount() of the sun format parser the cache read lock is too +heavily used and has too broad a scope. This has lead to some operations +that should hold the write lock being called with only the read lock. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 9 ++++++++- + modules/parse_sun.c | 53 ++++++++++++++++++++++++++++++++------------------- + 3 files changed, 42 insertions(+), 21 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c60a9ed3..d25b19c8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -18,6 +18,7 @@ + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). ++- fix inconsistent locking in parse_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 5ebfe5fd..0fcd4087 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2491,6 +2491,12 @@ static int do_mount_autofs_offset(struct autofs_point *ap, + else { + debug(ap->logopt, "ignoring \"nohide\" trigger %s", + oe->key); ++ /* ++ * Ok, so we shouldn't modify the mapent but ++ * mount requests are blocked at a point above ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. ++ */ + free(oe->mapent); + oe->mapent = NULL; + } +@@ -2634,7 +2640,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch + /* + * Ok, so we shouldn't modify the mapent but + * mount requests are blocked at a point above +- * this and expire only uses the mapent key. ++ * this and expire only uses the mapent key or ++ * holds the cache write lock. + */ + if (oe->mapent) { + free(oe->mapent); +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 95251bee..a6630a76 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -851,10 +851,12 @@ update_offset_entry(struct autofs_point *ap, + strcpy(m_mapent, loc); + } + ++ cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + + if (!cache_set_offset_parent(mc, m_key)) + error(ap->logopt, "failed to set offset parent"); ++ cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX +@@ -1128,14 +1130,22 @@ static void cleanup_multi_triggers(struct autofs_point *ap, + return; + } + +-static int mount_subtree(struct autofs_point *ap, struct mapent *me, ++static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + const char *name, char *loc, char *options, void *ctxt) + { ++ struct mapent *me; + struct mapent *ro; + char *mm_root, *mm_base, *mm_key; + unsigned int mm_root_len; + int start, ret = 0, rv; + ++ cache_readlock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ return 0; ++ } ++ + rv = 0; + + mm_key = me->multi->key; +@@ -1180,9 +1190,12 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + rv = parse_mapent(ro->mapent, + options, &myoptions, &ro_loc, ap->logopt); + if (!rv) { ++ cache_unlock(mc); + warn(ap->logopt, + MODPREFIX "failed to parse root offset"); +- cache_delete_offset_list(me->mc, name); ++ cache_writelock(mc); ++ cache_delete_offset_list(mc, name); ++ cache_unlock(mc); + return 1; + } + ro_len = 0; +@@ -1199,9 +1212,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + if ((ro && rv == 0) || rv <= 0) { + ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } +@@ -1217,9 +1231,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + if (rv == 0) { + ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, name, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, name, start, mm_base); + return 1; + } + } else if (rv < 0) { +@@ -1227,8 +1242,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; + + if (mm_root_base_len > PATH_MAX) { ++ cache_unlock(mc); + warn(ap->logopt, MODPREFIX "path too long"); +- cache_delete_offset_list(me->mc, name); ++ cache_writelock(mc); ++ cache_delete_offset_list(mc, name); ++ cache_unlock(mc); + return 1; + } + +@@ -1237,13 +1255,15 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + + ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base); + if (ret == -1) { ++ cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); + return 1; + } + } + } ++ cache_unlock(mc); + + /* Mount for base of tree failed */ + if (rv > 0) +@@ -1484,7 +1504,6 @@ dont_expand: + return 1; + } + +- cache_multi_writelock(me); + /* So we know we're the multi-mount root */ + if (!me->multi) + me->multi = me; +@@ -1509,14 +1528,13 @@ dont_expand: + if (source->flags & MAP_FLAG_FORMAT_AMD) { + free(options); + free(pmapent); +- cache_multi_unlock(me); + cache_unlock(mc); + pthread_setcancelstate(cur_state, NULL); + return 0; + } + } +- + age = me->age; ++ cache_unlock(mc); + + /* It's a multi-mount; deal with it */ + do { +@@ -1537,8 +1555,8 @@ dont_expand: + + if (!path) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(options); + free(pmapent); +@@ -1554,8 +1572,8 @@ dont_expand: + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(path); + free(options); +@@ -1573,8 +1591,8 @@ dont_expand: + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); ++ cache_writelock(mc); + cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); + cache_unlock(mc); + free(path); + free(options); +@@ -1592,10 +1610,7 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + +- rv = mount_subtree(ap, me, name, NULL, options, ctxt); +- +- cache_multi_unlock(me); +- cache_unlock(mc); ++ rv = mount_subtree(ap, mc, name, NULL, options, ctxt); + + free(options); + free(pmapent); +@@ -1616,6 +1631,7 @@ dont_expand: + cache_readlock(mc); + if (*name == '/' && + (me = cache_lookup_distinct(mc, name)) && me->multi) { ++ cache_unlock(mc); + loc = strdup(p); + if (!loc) { + free(options); +@@ -1624,10 +1640,7 @@ dont_expand: + warn(ap->logopt, MODPREFIX "out of memory"); + return 1; + } +- cache_multi_writelock(me); +- rv = mount_subtree(ap, me, name, loc, options, ctxt); +- cache_multi_unlock(me); +- cache_unlock(mc); ++ rv = mount_subtree(ap, mc, name, loc, options, ctxt); + free(loc); + free(options); + free(pmapent); diff --git a/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch b/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch new file mode 100644 index 0000000..817d7f3 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch @@ -0,0 +1,135 @@ +autofs-5.1.7 - fix inconsistent locking in umount_subtree_mounts() + +From: Ian Kent + +Some map entry cache locking inconsistencies have crept in. + +In umount_subtree_mounts() the cache write lock should be held when +deleting multi-mount cache entries. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 42 ++++++++++++++++++++++++++++++------------ + lib/mounts.c | 8 -------- + 3 files changed, 31 insertions(+), 20 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 1dded118..64e619ec 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. ++- fix inconsistent locking in umount_subtree_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 7fa92877..93bd8556 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + struct mapent_cache *mc; + struct mapent *me; + unsigned int is_mm_root = 0; ++ int cur_state; + int left; + ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ + me = lookup_source_mapent(ap, path, LKP_DISTINCT); + if (!me) { + char *ind_key; +@@ -548,11 +551,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + left = 0; + + if (me && me->multi) { +- char root[PATH_MAX]; ++ char root[PATH_MAX + 1]; ++ char key[PATH_MAX + 1]; ++ struct mapent *tmp; ++ int status; + char *base; +- int cur_state; +- +- pthread_cleanup_push(cache_lock_cleanup, mc); + + if (!strchr(me->multi->key, '/')) + /* Indirect multi-mount root */ +@@ -567,25 +570,40 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + else + base = me->key + strlen(root); + +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- /* Lock the closest parent nesting point for umount */ +- cache_multi_writelock(me->parent); +- if (umount_multi_triggers(ap, me, root, base)) { ++ left = umount_multi_triggers(ap, me, root, base); ++ if (left) { + warn(ap->logopt, + "some offset mounts still present under %s", path); ++ } ++ ++ strcpy(key, me->key); ++ ++ cache_unlock(mc); ++ cache_writelock(mc); ++ tmp = cache_lookup_distinct(mc, key); ++ /* mapent went away while we waited? */ ++ if (tmp != me) { ++ cache_unlock(mc); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ ++ if (!left && is_mm_root) { ++ status = cache_delete_offset_list(mc, me->key); ++ if (status != CHE_OK) ++ warn(ap->logopt, "couldn't delete offset list"); + left++; + } +- cache_multi_unlock(me->parent); ++ + if (ap->entry->maps && + (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD)) + cache_pop_mapent(me); +- pthread_setcancelstate(cur_state, NULL); +- pthread_cleanup_pop(0); + } +- + if (me) + cache_unlock(mc); + ++ pthread_setcancelstate(cur_state, NULL); ++ + if (left || is_autofs_fs) + return left; + +diff --git a/lib/mounts.c b/lib/mounts.c +index 87813b16..5ebfe5fd 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2736,9 +2736,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + left = do_umount_multi_triggers(ap, me, root, base); + + if (!left && me->multi == me) { +- struct mapent_cache *mc = me->mc; +- int status; +- + /* + * Special case. + * If we can't umount the root container then we can't +@@ -2756,11 +2753,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + } + } + +- /* We're done - clean out the offsets */ +- status = cache_delete_offset_list(mc, me->key); +- if (status != CHE_OK) +- warn(ap->logopt, "couldn't delete offset list"); +- + /* check for mounted mount entry and remove it if found */ + mnts_remove_mount(root, MNTS_MOUNTED); + } diff --git a/SOURCES/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch b/SOURCES/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch new file mode 100644 index 0000000..8eebf47 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch @@ -0,0 +1,64 @@ +autofs-5.1.7 - fix is mounted check on non existent path + +From: Ian Kent + +When checking if a path is a mount point the case of a non-existent path +was not being handled. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/dev-ioctl-lib.c | 3 +++ + lib/mounts.c | 12 +++++++++++- + 3 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 484bd866..e55fd66a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -6,6 +6,7 @@ + - fix mnts_remove_amdmount() uses wrong list. + - Fix option for master read wait. + - eliminate cache_lookup_offset() usage. ++- fix is mounted check on non existent path. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c +index e8519236..7040c3da 100644 +--- a/lib/dev-ioctl-lib.c ++++ b/lib/dev-ioctl-lib.c +@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsigned int logopt, + int save_errno = errno; + free_dev_ioctl_path(param); + errno = save_errno; ++ /* Path doesn't exist */ ++ if (errno == ENOENT) ++ return 0; + return -1; + } + +diff --git a/lib/mounts.c b/lib/mounts.c +index 42e8ef07..fe931b20 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1649,8 +1649,18 @@ static int table_is_mounted(const char *mp, unsigned int type) + struct mntent mnt_wrk; + char buf[PATH_MAX * 3]; + size_t mp_len = strlen(mp); ++ struct stat st; + FILE *tab; +- int ret = 0; ++ int ret; ++ ++ ret = stat(mp, &st); ++ if (ret == -1) { ++ if (errno == ENOENT) { ++ /* Path does not exist */ ++ return 0; ++ } ++ ret = 0; ++ } + + if (!mp || !mp_len || mp_len >= PATH_MAX) + return 0; diff --git a/SOURCES/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch b/SOURCES/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch new file mode 100644 index 0000000..8f81881 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch @@ -0,0 +1,56 @@ +autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change + +From: Ian Kent + +Commit 256963d6b (autofs-5.1.7 - refactor lookup_prune_one_cache() a bit) +changed the position of the getting the next enumeration map entry but +failed to update a couple of other locations that assume the next map +entry has been set. Under certain fairly common conditions this leads +to an infinite loop. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -74,6 +74,7 @@ + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. + - fix direct mount deadlock. ++- fix lookup_prune_one_cache() refactoring change. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/lookup.c ++++ autofs-5.1.7/daemon/lookup.c +@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autof + if (!key || strchr(key, '*')) { + if (key) + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1386,6 +1387,7 @@ void lookup_prune_one_cache(struct autof + if (!path) { + warn(ap->logopt, "can't malloc storage for path"); + free(key); ++ me = cache_enumerate(mc, me); + continue; + } + +@@ -1413,9 +1415,10 @@ void lookup_prune_one_cache(struct autof + } + if (!valid && + is_mounted(path, MNTS_REAL)) { +- debug(ap->logopt, "prune posponed, %s mounted", path); ++ debug(ap->logopt, "prune postponed, %s mounted", path); + free(key); + free(path); ++ me = cache_enumerate(mc, me); + continue; + } + if (valid) diff --git a/SOURCES/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch b/SOURCES/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch new file mode 100644 index 0000000..8b1d211 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch @@ -0,0 +1,36 @@ +autofs-5.1.7 - fix missing lock release in mount_subtree() + +From: Ian Kent + +Covarity: missing_unlock: Returning without unlocking "mc->rwlock". + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 1d56c96f..ff3d88eb 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -61,6 +61,7 @@ + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. ++- fix missing lock release in mount_subtree(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 05f53fc2..5d15f892 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); + if (!len) { + warn(ap->logopt, "path loo long"); ++ cache_unlock(mc); + return 1; + } + key[len] = '/'; diff --git a/SOURCES/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch b/SOURCES/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch new file mode 100644 index 0000000..b09b045 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - fix mnts_get_expire_list() expire list construction + +From: Ian Kent + +The mnts_get_expire_list() function is supposed to return an ordered +list of expire candidates but it is not checking the mounted status +of list entries and is returning a larger list than is needed. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 3 +++ + 2 files changed, 4 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index f5c5641a..1dded118 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. ++- fix mnts_get_expire_list() expire list construction. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index a9abbebf..87813b16 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + list_for_each_entry(mnt, &ap->mounts, mount) { + struct node *n; + ++ if (!(mnt->flags & MNTS_MOUNTED)) ++ continue; ++ + __mnts_get_mount(mnt); + + if (!tree) { diff --git a/SOURCES/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch b/SOURCES/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch new file mode 100644 index 0000000..b1eb16e --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - fix mnts_remove_amdmount() uses wrong list + +From: Ian Kent + +Function mnts_remove_amdmount() uses the wrong list when removing an +amd mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index d613e5ca..fe49740e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. ++- fix mnts_remove_amdmount() uses wrong list. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index dbeb77b5..ccbd52e0 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1124,7 +1124,7 @@ void mnts_remove_amdmount(const char *mp) + if (!(this && this->flags & MNTS_AMD_MOUNT)) + goto done; + this->flags &= ~MNTS_AMD_MOUNT; +- list_del_init(&this->submount); ++ list_del_init(&this->amdmount); + if (this->ext_mp) { + free(this->ext_mp); + this->ext_mp = NULL; diff --git a/SOURCES/autofs-5.1.7-fix-mount_fullpath.patch b/SOURCES/autofs-5.1.7-fix-mount_fullpath.patch new file mode 100644 index 0000000..e573692 --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-mount_fullpath.patch @@ -0,0 +1,67 @@ +autofs-5.1.7 - fix mount_fullpath() + +From: Ian Kent + +mount_fullpath() incorrecly fills fullpath with the contents of root +when name[0] == '/'. The cases root[last] == '/' and name[0] == '/' +need to be handled seperately. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 4 +++- + modules/parse_amd.c | 6 ++++-- + 3 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 390028ac..e2fd532c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -36,6 +36,7 @@ + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). ++- fix mount_fullpath(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index fded4c09..497c28c9 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_t max_len, + /* Root offset of multi-mount or direct or offset mount. + * Direct or offset mount, name (or root) is absolute path. + */ +- if (root[last] == '/' || *name == '/') ++ if (root[last] == '/') + len = snprintf(fullpath, max_len, "%s", root); ++ else if (*name == '/') ++ len = snprintf(fullpath, max_len, "%s", name); + else + len = snprintf(fullpath, max_len, "%s/%s", root, name); + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 5a9079d6..64c1ce63 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + * the automount filesystem. + */ + if (!is_mounted(entry->fs, MNTS_REAL)) { +- ret = do_mount(ap, entry->fs, "/", 1, ++ ret = do_mount(ap, entry->fs, ++ entry->fs, strlen(entry->fs), + target, entry->type, opts); + if (ret) + goto out; +@@ -1227,7 +1228,8 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + mount_nfs->context); + } else { + if (!is_mounted(entry->fs, MNTS_REAL)) { +- ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1, ++ ret = mount_nfs->mount_mount(ap, entry->fs, ++ entry->fs, strlen(entry->fs), + target, entry->type, opts, + mount_nfs->context); + if (ret) diff --git a/SOURCES/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch b/SOURCES/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch new file mode 100644 index 0000000..184afdf --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch @@ -0,0 +1,54 @@ +autofs-5.1.7 - fix nonstrict offset mount fail handling + +From: Ian Kent + +If a triggered offset mount fails automount is not handling nonstrict +mount failure correctly. + +The nonstrict mount failure handling needs to convert an offset mount +failure to a success if the offset subtree below the failed mount is not +empty otherwise it must return the failure. The previous implementation +used -1 to indicate the subtree was empty and that was used to detect +when the mount should fail instead of converting the fail to a success. + +Make the new implementation do the same. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 2 +- + modules/parse_sun.c | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -76,6 +76,7 @@ + - fix direct mount deadlock. + - fix lookup_prune_one_cache() refactoring change. + - add missing description of null map option. ++- fix nonstrict offset mount fail handling. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree( + { + struct traverse_subtree_context *ctxt = ptr; + struct mapent *oe = MAPENT(n); +- int ret = 1; ++ int ret = -1; + + if (n->left) { + ret = tree_mapent_traverse_subtree(n->left, work, ctxt); +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_p + * offsets to be mounted. + */ + rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); +- if (rv == 0) { ++ if (rv <= 0) { + ret = tree_mapent_mount_offsets(me, 1); + if (!ret) { + tree_mapent_cleanup_offsets(me); diff --git a/SOURCES/autofs-5.1.7-fix-offset-entries-order.patch b/SOURCES/autofs-5.1.7-fix-offset-entries-order.patch new file mode 100644 index 0000000..8843d2c --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-offset-entries-order.patch @@ -0,0 +1,199 @@ +autofs-5.1.7 - fix offset entries order + +From: Ian Kent + +While it's rare it's possible that a mapent entry might not have +it's offsets in shortest to longest path order. + +If this happens adding an entry to the mapent tree can result in +an incorrect tree topology that doesn't work. That's because adding +tree entries ensures that nodes in a sub-tree are placed below the +containing node so the containing node must be present for that to +work. This topology is critical to the performance of map entries +that have a very large number of offsets such as an NFS server with +many exports. + +There's no other choice but make a traversal after the offset entries +have all been added to create the mapent tree. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 1 + lib/cache.c | 1 + modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++----------- + 4 files changed, 62 insertions(+), 15 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -69,6 +69,7 @@ + - fix dangling symlink creation if nis support is not available. + - fix amd section mounts map reload. + - fix amd hosts mount expire. ++- fix offset entries order. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/include/automount.h ++++ autofs-5.1.7/include/automount.h +@@ -169,6 +169,7 @@ struct mapent { + /* Parent nesting point within multi-mount */ + struct tree_node *mm_parent; + struct tree_node node; ++ struct list_head work; + char *key; + size_t len; + char *mapent; +--- autofs-5.1.7.orig/lib/cache.c ++++ autofs-5.1.7/lib/cache.c +@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s + me->mm_parent = NULL; + INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); ++ INIT_LIST_HEAD(&me->work); + me->ioctlfd = -1; + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -789,14 +789,15 @@ static int check_is_multi(const char *ma + + static int + update_offset_entry(struct autofs_point *ap, +- struct mapent_cache *mc, const char *name, +- const char *m_root, int m_root_len, ++ struct mapent_cache *mc, struct list_head *offsets, ++ const char *name, const char *m_root, int m_root_len, + const char *m_offset, const char *myoptions, + const char *loc, time_t age) + { + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; + int o_len, m_key_len, m_options_len, m_mapent_len; ++ struct mapent *me; + int ret; + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); +@@ -862,8 +863,29 @@ update_offset_entry(struct autofs_point + cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + +- if (!tree_mapent_add_node(mc, name, m_key)) +- error(ap->logopt, "failed to add offset %s to tree", m_key); ++ me = cache_lookup_distinct(mc, m_key); ++ if (me && list_empty(&me->work)) { ++ struct list_head *last; ++ ++ /* Offset entries really need to be in shortest to ++ * longest path order. If not and the list of offsets ++ * is large there will be a performace hit. ++ */ ++ list_for_each_prev(last, offsets) { ++ struct mapent *this; ++ ++ this = list_entry(last, struct mapent, work); ++ if (me->len >= this->len) { ++ if (last->next == offsets) ++ list_add_tail(&me->work, offsets); ++ else ++ list_add_tail(&me->work, last); ++ break; ++ } ++ } ++ if (list_empty(&me->work)) ++ list_add(&me->work, offsets); ++ } + cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { +@@ -1209,6 +1231,25 @@ static char *do_expandsunent(const char + return mapent; + } + ++static void cleanup_offset_entries(struct autofs_point *ap, ++ struct mapent_cache *mc, ++ struct list_head *offsets) ++{ ++ struct mapent *me, *tmp; ++ int ret; ++ ++ if (list_empty(offsets)) ++ return; ++ cache_writelock(mc); ++ list_for_each_entry_safe(me, tmp, offsets, work) { ++ list_del(&me->work); ++ ret = cache_delete(mc, me->key); ++ if (ret != CHE_OK) ++ crit(ap->logopt, "failed to delete offset %s", me->key); ++ } ++ cache_unlock(mc); ++} ++ + /* + * syntax is: + * [-options] location [location] ... +@@ -1228,7 +1269,8 @@ int parse_mount(struct autofs_point *ap, + char buf[MAX_ERR_BUF]; + struct map_source *source; + struct mapent_cache *mc; +- struct mapent *me; ++ struct mapent *me, *oe, *tmp; ++ LIST_HEAD(offsets); + char *pmapent, *options; + const char *p; + int mapent_len, rv = 0; +@@ -1444,9 +1486,7 @@ dont_expand: + + if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(options); + free(pmapent); + pthread_setcancelstate(cur_state, NULL); +@@ -1461,9 +1501,7 @@ dont_expand: + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1474,15 +1512,13 @@ dont_expand: + p += l; + p = skipspace(p); + +- status = update_offset_entry(ap, mc, ++ status = update_offset_entry(ap, mc, &offsets, + name, m_root, m_root_len, + m_offset, myoptions, loc, age); + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); +- cache_writelock(mc); +- tree_mapent_delete_offsets(mc, name); +- cache_unlock(mc); ++ cleanup_offset_entries(ap, mc, &offsets); + free(m_offset); + free(options); + free(pmapent); +@@ -1499,6 +1535,14 @@ dont_expand: + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + ++ cache_writelock(mc); ++ list_for_each_entry_safe(oe, tmp, &offsets, work) { ++ if (!tree_mapent_add_node(mc, name, oe->key)) ++ error(ap->logopt, "failed to add offset %s to tree", oe->key); ++ list_del_init(&oe->work); ++ } ++ cache_unlock(mc); ++ + rv = mount_subtree(ap, mc, name, NULL, options, ctxt); + + free(options); diff --git a/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch b/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch new file mode 100644 index 0000000..c2ea9df --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch @@ -0,0 +1,38 @@ +autofs-5.1.7 - fix possible memory leak in master_parse() + +From: Ian Kent + +Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)" + leaks the storage that "path" points to. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master_parse.y | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 2186cbe3..b797f6dc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -52,6 +52,7 @@ + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). + - remove redundant if check. ++- fix possible memory leak in master_parse(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master_parse.y b/daemon/master_parse.y +index 08e44b57..7480c36a 100644 +--- a/daemon/master_parse.y ++++ b/daemon/master_parse.y +@@ -155,6 +155,8 @@ file: { + line: + | PATH mapspec + { ++ if (path) ++ free(path); + path = master_strdup($1); + if (!path) { + local_free_vars(); diff --git a/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch b/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch new file mode 100644 index 0000000..5b7c9cc --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch @@ -0,0 +1,58 @@ +autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount() + +From: Ian Kent + +Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks + the storage it points to. + +Same applies to the other duped fields destined for the mnt_list struct. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 20 ++++++++++---------- + 2 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b797f6dc..2e3b9fd7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -53,6 +53,7 @@ + - add missing free in handle_mounts(). + - remove redundant if check. + - fix possible memory leak in master_parse(). ++- fix possible memory leak in mnts_add_amdmount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index c8a7bf00..ef69cec1 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en + + mnts_hash_mutex_lock(); + this = mnts_get_mount(entry->path); +- if (this) { +- this->ext_mp = ext_mp; +- this->amd_pref = pref; +- this->amd_type = type; +- this->amd_opts = opts; +- this->amd_cache_opts = entry->cache_opts; +- this->flags |= MNTS_AMD_MOUNT; +- if (list_empty(&this->amdmount)) +- list_add_tail(&this->amdmount, &ap->amdmounts); +- } ++ if (!this) ++ goto fail; ++ this->ext_mp = ext_mp; ++ this->amd_pref = pref; ++ this->amd_type = type; ++ this->amd_opts = opts; ++ this->amd_cache_opts = entry->cache_opts; ++ this->flags |= MNTS_AMD_MOUNT; ++ if (list_empty(&this->amdmount)) ++ list_add_tail(&this->amdmount, &ap->amdmounts); + mnts_hash_mutex_unlock(); + + return this; diff --git a/SOURCES/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch b/SOURCES/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch new file mode 100644 index 0000000..7ea2f2f --- /dev/null +++ b/SOURCES/autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch @@ -0,0 +1,44 @@ +autofs-5.1.7 - fix return from umount_subtree_mounts() on offset list delete + +From: Ian Kent + +When there are no mounts left in a subtree of offset mounts the offset +list is deleted. If all goes well deleting the list this shouldn't cause +a positive return from umount_subtree_mounts() (essentially saying that +the umount of the subtree has not succeeded). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 64e619ec..6e0edd74 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). ++- fix return from umount_subtree_mounts() on offset list delete. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 93bd8556..62530b6b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + + if (!left && is_mm_root) { + status = cache_delete_offset_list(mc, me->key); +- if (status != CHE_OK) ++ if (status != CHE_OK) { + warn(ap->logopt, "couldn't delete offset list"); +- left++; ++ left++; ++ } + } + + if (ap->entry->maps && diff --git a/SOURCES/autofs-5.1.7-make-tree-implementation-data-independent.patch b/SOURCES/autofs-5.1.7-make-tree-implementation-data-independent.patch new file mode 100644 index 0000000..31a0d60 --- /dev/null +++ b/SOURCES/autofs-5.1.7-make-tree-implementation-data-independent.patch @@ -0,0 +1,352 @@ +autofs-5.1.7 - make tree implementation data independent + +From: Ian Kent + +Generalise the tree implementation so that it's independent of the +data structure that's used. + +Do this by refactoring it into core tree functions and functions +specific to the data structure to be used so that different data +structures can be used when needed by adding an implementation for +the data structure specific functions. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/mounts.h | 29 +++++++++ + lib/mounts.c | 174 ++++++++++++++++++++++++++++++++++-------------------- + 3 files changed, 140 insertions(+), 64 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0dae6761..74571570 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -31,6 +31,7 @@ + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. ++- make tree implementation data independent. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index ac480c06..71d29566 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -51,10 +51,36 @@ extern const unsigned int t_indirect; + extern const unsigned int t_direct; + extern const unsigned int t_offset; + ++struct mnt_list; + struct mapent; + ++struct tree_ops; ++ ++struct tree_node { ++ struct tree_ops *ops; ++ struct tree_node *left; ++ struct tree_node *right; ++}; ++#define INIT_TREE_NODE(ptr) ((ptr)->ops = NULL, (ptr)->left = NULL, (ptr)->right = NULL) ++ ++#define MNT_LIST(n) (container_of(n, struct mnt_list, node)) ++#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node) ++ ++typedef struct tree_node *(*tree_new_t) (void *ptr); ++typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr); ++typedef void (*tree_free_t) (struct tree_node *n); ++ ++struct tree_ops { ++ tree_new_t new; ++ tree_cmp_t cmp; ++ tree_free_t free; ++}; ++ ++typedef int (*tree_work_fn_t) (struct tree_node *n, void *ptr); ++ + struct mnt_list { + char *mp; ++ size_t len; + unsigned int flags; + + /* Hash of all mounts */ +@@ -79,6 +105,9 @@ struct mnt_list { + unsigned int amd_cache_opts; + struct list_head amdmount; + ++ /* Tree operations */ ++ struct tree_node node; ++ + /* + * List operations ie. get_mnt_list. + */ +diff --git a/lib/mounts.c b/lib/mounts.c +index b478ecb4..a6d1c5a7 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER; + static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS); + static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER; + ++static struct tree_node *tree_mnt_new(void *ptr); ++static int tree_mnt_cmp(struct tree_node *n, void *ptr); ++static void tree_mnt_free(struct tree_node *n); ++ ++static struct tree_ops mnt_ops = { ++ .new = tree_mnt_new, ++ .cmp = tree_mnt_cmp, ++ .free = tree_mnt_free, ++}; ++static struct tree_ops *tree_mnt_ops = &mnt_ops; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -904,6 +915,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp) + this = NULL; + goto done; + } ++ this->len = strlen(mp); + + this->ref = 1; + INIT_HLIST_NODE(&this->hash); +@@ -912,6 +924,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp) + INIT_LIST_HEAD(&this->submount_work); + INIT_LIST_HEAD(&this->amdmount); + INIT_LIST_HEAD(&this->expire); ++ INIT_TREE_NODE(&this->node); + done: + return this; + } +@@ -1225,91 +1238,58 @@ done: + return has_mounted_mounts; + } + +-struct tree_node { +- struct mnt_list *mnt; +- struct tree_node *left; +- struct tree_node *right; +-}; +- +-static struct tree_node *tree_new(struct mnt_list *mnt) ++static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr) + { +- struct tree_node *n; +- +- n = malloc(sizeof(struct tree_node)); +- if (!n) +- return NULL; +- memset(n, 0, sizeof(struct tree_node)); +- n->mnt = mnt; +- +- return n; +-} +- +-static struct tree_node *tree_root(struct mnt_list *mnt) +-{ +- struct tree_node *n; +- +- n = tree_new(mnt); +- if (!n) { +- error(LOGOPT_ANY, "failed to allcate tree root"); +- return NULL; +- } +- +- return n; ++ return ops->new(ptr); + } + +-static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt) ++static struct tree_node *tree_add_left(struct tree_node *n, void *ptr) + { + struct tree_node *new; + +- new = tree_new(mnt); +- if (!new) { +- error(LOGOPT_ANY, "failed to allcate tree node"); +- return NULL; +- } ++ new = n->ops->new(ptr); + n->left = new; + +- return n; ++ return new; + } + +-static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt) ++static struct tree_node *tree_add_right(struct tree_node *n, void *ptr) + { + struct tree_node *new; + +- new = tree_new(mnt); +- if (!new) { +- error(LOGOPT_ANY, "failed to allcate tree node"); +- return NULL; +- } ++ new = n->ops->new(ptr); + n->right = new; + +- return n; ++ return new; + } + +-static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt) ++static struct tree_node *tree_add_node(struct tree_node *root, void *ptr) + { + struct tree_node *p, *q; +- unsigned int mp_len; +- +- mp_len = strlen(mnt->mp); ++ struct tree_ops *ops = root->ops; ++ int eq; + + q = root; + p = root; + +- while (q && strcmp(mnt->mp, p->mnt->mp)) { ++ while (q) { + p = q; +- if (mp_len < strlen(p->mnt->mp)) ++ eq = ops->cmp(p, ptr); ++ if (!eq) ++ break; ++ if (eq < 0) + q = p->left; + else + q = p->right; + } + +- if (strcmp(mnt->mp, p->mnt->mp) == 0) +- error(LOGOPT_ANY, "duplicate entry in mounts list"); ++ if (!eq) ++ error(LOGOPT_ANY, "cannot add duplicate entry to tree"); + else { +- if (mp_len < strlen(p->mnt->mp)) +- return tree_add_left(p, mnt); ++ if (eq < 0) ++ return tree_add_left(p, ptr); + else +- return tree_add_right(p, mnt); ++ return tree_add_right(p, ptr); + } + + return NULL; +@@ -1317,26 +1297,92 @@ static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list * + + static void tree_free(struct tree_node *root) + { ++ struct tree_ops *ops = root->ops; ++ + if (root->right) + tree_free(root->right); + if (root->left) + tree_free(root->left); +- free(root); ++ ops->free(root); + } + +-static void tree_traverse(struct tree_node *n, struct list_head *mnts) ++static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr) + { +- if (n->right) +- tree_traverse(n->right, mnts); +- list_add_tail(&n->mnt->expire, mnts); +- if (n->left) +- tree_traverse(n->left, mnts); ++ int ret; ++ ++ if (n->left) { ++ ret = tree_traverse_inorder(n->left, work, ptr); ++ if (!ret) ++ goto done; ++ } ++ ret = work(n, ptr); ++ if (!ret) ++ goto done; ++ if (n->right) { ++ ret = tree_traverse_inorder(n->right, work, ptr); ++ if (!ret) ++ goto done; ++ } ++done: ++ return ret; ++} ++ ++static struct tree_node *tree_mnt_root(struct mnt_list *mnt) ++{ ++ return tree_root(tree_mnt_ops, mnt); ++} ++ ++static struct tree_node *tree_mnt_new(void *ptr) ++{ ++ struct tree_node *n = MNT_LIST_NODE(ptr); ++ ++ n->ops = tree_mnt_ops; ++ n->left = NULL; ++ n->right = NULL; ++ ++ return n; ++} ++ ++static int tree_mnt_cmp(struct tree_node *n, void *ptr) ++{ ++ struct mnt_list *n_mnt = MNT_LIST(n); ++ size_t n_mnt_len = n_mnt->len; ++ struct mnt_list *mnt = ptr; ++ size_t mnt_len = mnt->len; ++ int eq; ++ ++ eq = strcmp(mnt->mp, n_mnt->mp); ++ if (!eq) ++ return 0; ++ return (mnt_len < n_mnt_len) ? -1 : 1; ++} ++ ++static void tree_mnt_free(struct tree_node *n) ++{ ++ n->ops = NULL; ++ n->left = NULL; ++ n->right = NULL; ++} ++ ++static int tree_mnt_expire_list_work(struct tree_node *n, void *ptr) ++{ ++ struct mnt_list *mnt = MNT_LIST(n); ++ struct list_head *mnts = ptr; ++ ++ /* The expire of the root offset of an offset tree is the same ++ * as expiring the offset tree root itself (if theree is a root ++ * offset). ++ */ ++ if (mnt->mp[mnt->len - 1] != '/') ++ list_add(&mnt->expire, mnts); ++ ++ return 1; + } + + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + { +- struct mnt_list *mnt; + struct tree_node *tree = NULL; ++ struct mnt_list *mnt; + + mnts_hash_mutex_lock(); + if (list_empty(&ap->mounts)) +@@ -1351,7 +1397,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + __mnts_get_mount(mnt); + + if (!tree) { +- tree = tree_root(mnt); ++ tree = tree_mnt_root(mnt); + if (!tree) { + error(LOGOPT_ANY, "failed to create expire tree root"); + goto done; +@@ -1367,7 +1413,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + } + } + +- tree_traverse(tree, mnts); ++ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts); + tree_free(tree); + done: + mnts_hash_mutex_unlock(); diff --git a/SOURCES/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch b/SOURCES/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch new file mode 100644 index 0000000..bb158e2 --- /dev/null +++ b/SOURCES/autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch @@ -0,0 +1,118 @@ +autofs-5.1.7 - move amd mounts removal into lib/mounts.c + +From: Ian Kent + +Move the amd mounts removal from master_free_autofs_point() into +lib/mounts.c along with the rest of the amd mount handling. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 12 +----------- + include/mounts.h | 1 + + lib/mounts.c | 28 ++++++++++++++++++++++++---- + 4 files changed, 27 insertions(+), 15 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 002da042..a9209755 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -46,6 +46,7 @@ + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). + - remove unused function master_submount_list_empty(). ++- move amd mounts removal into lib/mounts.c. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master.c b/daemon/master.c +index af9cd79f..b288e070 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -143,22 +143,12 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + + void master_free_autofs_point(struct autofs_point *ap) + { +- struct list_head *p, *head; + int status; + + if (!ap) + return; + +- mounts_mutex_lock(ap); +- head = &ap->amdmounts; +- p = head->next; +- while (p != head) { +- struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); +- p = p->next; +- ext_mount_remove(mnt->ext_mp); +- mnts_remove_amdmount(mnt->mp); +- } +- mounts_mutex_unlock(ap); ++ mnts_remove_amdmounts(ap); + + status = pthread_mutex_destroy(&ap->mounts_mutex); + if (status) +diff --git a/include/mounts.h b/include/mounts.h +index d7980976..1b376b3d 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -161,6 +161,7 @@ void mnts_remove_submount(const char *mp); + struct mnt_list *mnts_find_amdmount(const char *path); + struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry); + void mnts_remove_amdmount(const char *mp); ++void mnts_remove_amdmounts(struct autofs_point *ap); + struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags); + void mnts_remove_mount(const char *mp, unsigned int flags); + struct mnt_list *get_mnt_list(const char *path, int include); +diff --git a/lib/mounts.c b/lib/mounts.c +index 6b8e4c92..c8a7bf00 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1144,14 +1144,13 @@ fail: + return NULL; + } + +-void mnts_remove_amdmount(const char *mp) ++static void __mnts_remove_amdmount(const char *mp) + { + struct mnt_list *this; + +- mnts_hash_mutex_lock(); + this = mnts_lookup(mp); + if (!(this && this->flags & MNTS_AMD_MOUNT)) +- goto done; ++ return; + this->flags &= ~MNTS_AMD_MOUNT; + list_del_init(&this->amdmount); + if (this->ext_mp) { +@@ -1172,7 +1171,28 @@ void mnts_remove_amdmount(const char *mp) + } + this->amd_cache_opts = 0; + __mnts_put_mount(this); +-done: ++} ++ ++void mnts_remove_amdmount(const char *mp) ++{ ++ mnts_hash_mutex_lock(); ++ __mnts_remove_amdmount(mp); ++ mnts_hash_mutex_unlock(); ++} ++ ++void mnts_remove_amdmounts(struct autofs_point *ap) ++{ ++ struct list_head *head, *p; ++ ++ mnts_hash_mutex_lock(); ++ head = &ap->amdmounts; ++ p = head->next; ++ while (p != head) { ++ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount); ++ p = p->next; ++ ext_mount_remove(mnt->ext_mp); ++ __mnts_remove_amdmount(mnt->mp); ++ } + mnts_hash_mutex_unlock(); + } + diff --git a/SOURCES/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch b/SOURCES/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch new file mode 100644 index 0000000..1dffc83 --- /dev/null +++ b/SOURCES/autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch @@ -0,0 +1,72 @@ +autofs-5.1.7 - pass mapent_cache to update_offset_entry() + +From: Ian Kent + +Pass mapent_cache to update_offset_entry() rather than use the wait/signal +mechanism, it isn't needed here. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 22 ++++++---------------- + 2 files changed, 7 insertions(+), 16 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 6e0edd74..c60a9ed3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -17,6 +17,7 @@ + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. ++- pass mapent_cache to update_offset_entry(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 1142e8a3..95251bee 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -793,24 +793,17 @@ static int check_is_multi(const char *mapent) + } + + static int +-update_offset_entry(struct autofs_point *ap, const char *name, ++update_offset_entry(struct autofs_point *ap, ++ struct mapent_cache *mc, const char *name, + const char *m_root, int m_root_len, +- const char *path, const char *myoptions, const char *loc, +- time_t age) ++ const char *path, const char *myoptions, ++ const char *loc, time_t age) + { +- struct map_source *source; +- struct mapent_cache *mc; + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; + int p_len, m_key_len, m_options_len, m_mapent_len; + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + + /* Internal hosts map may have loc == NULL */ +@@ -1574,11 +1567,8 @@ dont_expand: + p += l; + p = skipspace(p); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = update_offset_entry(ap, name, +- m_root, m_root_len, ++ status = update_offset_entry(ap, mc, ++ name, m_root, m_root_len, + path, myoptions, loc, age); + + if (status != CHE_OK) { diff --git a/SOURCES/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch b/SOURCES/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch new file mode 100644 index 0000000..56180c1 --- /dev/null +++ b/SOURCES/autofs-5.1.7-pass-root-length-to-mount_fullpath.patch @@ -0,0 +1,171 @@ +autofs-5.1.7 - pass root length to mount_fullpath() + +From: Ian Kent + +The length of root may already be known, add a parameter to allow +passing it to mount_fullpath() so a strlen() call can be avoided. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 11 +++++++---- + modules/mount_bind.c | 2 +- + modules/mount_changer.c | 2 +- + modules/mount_ext2.c | 2 +- + modules/mount_generic.c | 2 +- + modules/mount_nfs.c | 2 +- + modules/parse_sun.c | 4 ++-- + 9 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 8494f0dc..1c9e2a2d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -44,6 +44,7 @@ + - remove obsolete functions. + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). ++- pass root length to mount_fullpath(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/mounts.h b/include/mounts.h +index ec895e1c..d7980976 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -131,7 +131,7 @@ int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *); + extern unsigned int nfs_mount_uses_string_options; + + int mount_fullpath(char *fullpath, size_t max_len, +- const char *root, const char *name); ++ const char *root, size_t root_len, const char *name); + + struct amd_entry; + +diff --git a/lib/mounts.c b/lib/mounts.c +index c120d2a8..6b8e4c92 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_mount_vers *vers, + #endif + + int mount_fullpath(char *fullpath, size_t max_len, +- const char *root, const char *name) ++ const char *root, size_t root_len, const char *name) + { + int last, len; + +- last = strlen(root) - 1; ++ if (root_len) ++ last = root_len - 1; ++ else ++ last = strlen(root) - 1; + + /* Root offset of multi-mount or direct or offset mount. + * Direct or offset mount, name (or root) is absolute path. +@@ -1685,7 +1688,7 @@ void tree_mapent_cleanup_offsets(struct mapent *oe) + else { + char mp[PATH_MAX + 1]; + +- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) + error(ap->logopt, "mount path is too long"); + else + tree_mapent_umount_mount(ap, mp); +@@ -1922,7 +1925,7 @@ int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict) + * one of these keys is the root of a multi-mount the mount + * path must be constructed. + */ +- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) { ++ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) { + error(ap->logopt, "mount path is too long"); + return 0; + } +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index c17c6f18..7f64332b 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } + } + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index d02b5f45..8adb9f9a 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + fstype = "iso9660"; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 53e6ee10..f4002e58 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index c9deb7ae..8cd0f4ab 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (defaults_get_mount_verbose()) + mountlog = &log_info; + +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index c70210f4..0314a78f 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } + + /* Construct mount point directory */ +- len = mount_fullpath(fullpath, PATH_MAX, root, name); ++ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name); + if (!len) { + error(ap->logopt, + MODPREFIX "mount point path too long"); +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index d3fc6c7f..b1c2611c 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1089,7 +1089,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + struct mapent *ro; + size_t len; + +- len = mount_fullpath(key, PATH_MAX, ap->path, me->key); ++ len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); + if (!len) { + warn(ap->logopt, "path loo long"); + return 1; +@@ -1359,7 +1359,7 @@ dont_expand: + time_t age; + int l; + +- m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name); ++ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, ap->len, name); + if (!m_root_len) { + error(ap->logopt, + MODPREFIX "multi-mount root path too long"); diff --git a/SOURCES/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch b/SOURCES/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch new file mode 100644 index 0000000..54c0a50 --- /dev/null +++ b/SOURCES/autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch @@ -0,0 +1,83 @@ +autofs-5.1.7 - reduce umount EBUSY check delay + +From: Ian Kent + +Some time ago I had to wait and retry umount() for autofs mounts +becuase I found EBUSY would be returned for a time after the call +causing false negative umount returns. + +I think that problem has been resolved but removing the retry is +probably a little risky. + +But the wait time is quite long at one fifth of a second so reduce +that to one twentieth of a second and increase the retries to make +it more resposive. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 4 ++-- + daemon/indirect.c | 2 +- + include/automount.h | 2 +- + 4 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b144f6aa..6419052d 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -23,6 +23,7 @@ + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. ++- reduce umount EBUSY check delay. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index fbfebbdd..5c1146a7 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me) + + retries = UMOUNT_RETRIES; + while ((rv = umount(me->key)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +@@ -573,7 +573,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) + + retries = UMOUNT_RETRIES; + while ((rv = umount(me->key)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +diff --git a/daemon/indirect.c b/daemon/indirect.c +index eddcfff7..9f2ca6a0 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root) + + retries = UMOUNT_RETRIES; + while ((rv = umount(mountpoint)) == -1 && retries--) { +- struct timespec tm = {0, 200000000}; ++ struct timespec tm = {0, 50000000}; + if (errno != EBUSY) + break; + nanosleep(&tm, NULL); +diff --git a/include/automount.h b/include/automount.h +index 69445b92..fa6f5d63 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -140,7 +140,7 @@ struct autofs_point; + #define NULL_MAP_HASHSIZE 64 + #define NEGATIVE_TIMEOUT 10 + #define POSITIVE_TIMEOUT 120 +-#define UMOUNT_RETRIES 8 ++#define UMOUNT_RETRIES 16 + #define EXPIRE_RETRIES 3 + + struct mapent_cache { diff --git a/SOURCES/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch b/SOURCES/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch new file mode 100644 index 0000000..e013a52 --- /dev/null +++ b/SOURCES/autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch @@ -0,0 +1,75 @@ +autofs-5.1.7 - refactor lookup_prune_one_cache() a bit + +From: Ian Kent + +Coverity: use: Using an unreliable value of "me" inside the second locked + section. + +Change lookup_prune_one_cache() a little, move the location the next +key is set (before releasing the lock) and add a comment explaining +why we don't care about the side effects of the read lock release/ +write lock aquire/write lock release/read lock reaquire. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 20 +++++++++++++++++++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 81461978..b79aebc8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -63,6 +63,7 @@ + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). ++- refactor lookup_prune_one_cache() a bit. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 32dbc24d..3e9722e4 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1375,7 +1375,6 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + } + + key = strdup(me->key); +- me = cache_enumerate(mc, me); + /* Don't consider any entries with a wildcard */ + if (!key || strchr(key, '*')) { + if (key) +@@ -1422,6 +1421,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (valid) + cache_unlock(valid->mc); + ++ me = cache_enumerate(mc, me); + if (me) + next_key = strdup(me->key); + +@@ -1456,6 +1456,24 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + next: + cache_readlock(mc); + if (next_key) { ++ /* The lock release and reaquire above can mean ++ * a number of things could happen. ++ * ++ * First, mapents could be added between the ++ * current mapent and the mapent of next_key. ++ * Don't care about that because there's no ++ * need to prune newly added entries. ++ * ++ * Second, the next mapent data could have ++ * changed. Don't care about that either since ++ * we are looking to prune stale map entries ++ * and don't care when they become stale. ++ * ++ * Finally, the mapent of next_key could have ++ * gone away. Again don't care about this either, ++ * the loop will exit prematurely so just wait ++ * until the next prune and try again. ++ */ + me = cache_lookup_distinct(mc, next_key); + free(next_key); + } diff --git a/SOURCES/autofs-5.1.7-refactor-umount_multi_triggers.patch b/SOURCES/autofs-5.1.7-refactor-umount_multi_triggers.patch new file mode 100644 index 0000000..39b7e10 --- /dev/null +++ b/SOURCES/autofs-5.1.7-refactor-umount_multi_triggers.patch @@ -0,0 +1,259 @@ +autofs-5.1.7 - refactor umount_multi_triggers() + +From: Ian Kent + +Refactor umount_multi_triggers() to try the umount of an offset subtree +in a seperate function. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/mounts.c | 187 ++++++++++++++++++++++++++++++++-------------------------- + 2 files changed, 104 insertions(+), 84 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3eda995c..5a3bedc1 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). ++- refactor umount_multi_triggers(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 8e88182f..5268ba5b 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2496,57 +2496,6 @@ static int do_mount_autofs_offset(struct autofs_point *ap, + return mounted; + } + +-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, +- const char *root, unsigned int start, const char *base) +-{ +- char path[PATH_MAX + 1]; +- char *offset = path; +- struct mapent *oe; +- struct list_head *pos = NULL; +- unsigned int root_len = strlen(root); +- int mounted; +- +- mounted = 0; +- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); +- while (offset) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- goto cont; +- } +- +- /* The root offset is always mounted seperately so the +- * offset path will always be root + offset. +- */ +- strcpy(key, root); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- if (!oe || !oe->mapent) +- goto cont; +- +- mounted += do_mount_autofs_offset(ap, oe, root); +- +- /* +- * 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(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, strlen(key), base); +- } +-cont: +- offset = cache_get_offset(base, +- offset, start, &me->multi_list, &pos); +- } +- +- return mounted; +-} +- + static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + { + char *dir, *path; +@@ -2582,7 +2531,10 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) + return ret; + } + +-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) ++static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root); ++ ++static int do_umount_multi_triggers(struct autofs_point *ap, ++ struct mapent *me, const char *root, const char *base) + { + char path[PATH_MAX + 1]; + char *offset; +@@ -2612,7 +2564,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { + char key[PATH_MAX + 1]; + int key_len = root_len + strlen(offset); +- char *oe_base; + + if (mm_base_len > 1) + key_len += mm_base_len; +@@ -2632,47 +2583,116 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + if (!oe || (strlen(oe->key) - start) == 1) + continue; + ++ left += do_umount_offset(ap, oe, root); ++ } ++ ++ return left; ++} ++ ++static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root) ++{ ++ char *oe_base; ++ int left = 0; ++ ++ /* ++ * Check for and umount subtree offsets resulting from ++ * nonstrict mount fail. ++ */ ++ oe_base = oe->key + strlen(root); ++ left += do_umount_multi_triggers(ap, oe, root, oe_base); ++ ++ if (oe->ioctlfd != -1 || ++ is_mounted(oe->key, MNTS_REAL)) { ++ left++; ++ return left; ++ } ++ ++ 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)) ++ return left; ++ + /* +- * Check for and umount subtree offsets resulting from +- * nonstrict mount fail. ++ * An error due to partial directory removal is ++ * ok so only try and remount the offset if the ++ * actual mount point still exists. + */ +- oe_base = oe->key + strlen(root); +- left += umount_multi_triggers(ap, oe, root, oe_base); ++ ret = rmdir_path_offset(ap, oe); ++ if (ret == -1 && !stat(oe->key, &st)) { ++ ret = do_mount_autofs_offset(ap, oe, root); ++ if (ret) ++ left++; ++ /* But we did origianlly create this */ ++ oe->flags |= MOUNT_FLAG_DIR_CREATED; ++ } ++ } ++ return left; ++} + +- if (oe->ioctlfd != -1 || +- is_mounted(oe->key, MNTS_REAL)) { +- left++; +- continue; ++int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, ++ const char *root, unsigned int start, const char *base) ++{ ++ char path[PATH_MAX + 1]; ++ char *offset = path; ++ struct mapent *oe; ++ struct list_head *pos = NULL; ++ unsigned int root_len = strlen(root); ++ int mounted; ++ ++ mounted = 0; ++ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); ++ while (offset) { ++ char key[PATH_MAX + 1]; ++ int key_len = root_len + strlen(offset); ++ ++ if (key_len > PATH_MAX) { ++ warn(ap->logopt, "path loo long"); ++ goto cont; + } + +- debug(ap->logopt, "umount offset %s", oe->key); ++ /* The root offset is always mounted seperately so the ++ * offset path will always be root + offset. ++ */ ++ strcpy(key, root); ++ strcat(key, offset); + +- if (umount_autofs_offset(ap, oe)) { +- warn(ap->logopt, "failed to umount offset"); +- left++; +- } else { +- struct stat st; +- int ret; ++ oe = cache_lookup_distinct(me->mc, key); ++ if (!oe || !oe->mapent) ++ goto cont; + +- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) +- continue; ++ mounted += do_mount_autofs_offset(ap, oe, root); + +- /* +- * 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_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root); +- if (ret) +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- } ++ /* ++ * 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(oe->key, MNTS_REAL)) ++ mount_multi_triggers(ap, oe, key, strlen(key), base); + } ++cont: ++ offset = cache_get_offset(base, ++ offset, start, &me->multi_list, &pos); + } + ++ return mounted; ++} ++ ++int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) ++{ ++ int left; ++ ++ left = do_umount_multi_triggers(ap, me, root, base); ++ + if (!left && me->multi == me) { + struct mapent_cache *mc = me->mc; + int status; +@@ -2871,4 +2891,3 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + + return left; + } +- diff --git a/SOURCES/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch b/SOURCES/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch new file mode 100644 index 0000000..4c837dc --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch @@ -0,0 +1,574 @@ +autofs-5.1.7 - remove mount.x and rpcgen dependencies + +From: Ian Kent + +Adding a local implementation to get the exports list from a server +means the the rpcgen generataed code is no longer needed so remove +mount.x and the build dependencies. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + Makefile.conf.in | 1 + autofs.spec | 2 + configure | 58 --------- + configure.in | 1 + include/automount.h | 1 + include/config.h.in | 3 + lib/Makefile | 26 ---- + lib/mount.x | 345 --------------------------------------------------- + 9 files changed, 5 insertions(+), 433 deletions(-) + delete mode 100644 lib/mount.x + +diff --git a/CHANGELOG b/CHANGELOG +index 84050e91..19af245e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,5 +1,6 @@ + + - add xdr_exports(). ++- remove mount.x and rpcgen dependencies. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/Makefile.conf.in b/Makefile.conf.in +index df678eec..12f26eb8 100644 +--- a/Makefile.conf.in ++++ b/Makefile.conf.in +@@ -65,7 +65,6 @@ FEDFS = @ENABLE_FEDFS@ + + LEX = @PATH_LEX@ + YACC = @PATH_YACC@ +-RPCGEN = @PATH_RPCGEN@ + RANLIB = @PATH_RANLIB@ + + # Use libtirpc if requested and available +diff --git a/autofs.spec b/autofs.spec +index 3c2b144a..823735a3 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -39,7 +39,7 @@ BuildRequires: libtirpc-devel + %endif + BuildRequires: autoconf, openldap-devel, bison, flex, libxml2-devel + BuildRequires: cyrus-sasl-devel, openssl-devel, util-linux +-BuildRequires: libtirpc-devel, rpcgen, libnsl2-devel, krb5-devel ++BuildRequires: libtirpc-devel, libnsl2-devel, krb5-devel + Requires: chkconfig + Requires: /bin/bash sed grep /bin/ps + %if %{with_systemd} +diff --git a/configure b/configure +index de968f0e..3c5fe78b 100755 +--- a/configure ++++ b/configure +@@ -650,8 +650,6 @@ XML_CFLAGS + ENABLE_FEDFS + sssldir + HAVE_SSS_AUTOFS +-PATH_RPCGEN +-RPCGEN + PATH_RANLIB + RANLIB + PATH_YACC +@@ -4205,62 +4203,6 @@ else + as_fn_error $? "required program RANLIB not found" "$LINENO" 5 + fi + +-for ac_prog in rpcgen +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_RPCGEN+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $RPCGEN in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $searchpath +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-fi +-RPCGEN=$ac_cv_path_RPCGEN +-if test -n "$RPCGEN"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5 +-$as_echo "$RPCGEN" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$RPCGEN" && break +-done +- +-if test -n "$RPCGEN"; then +- +-cat >>confdefs.h <<_ACEOF +-#define PATH_RPCGEN "$RPCGEN" +-_ACEOF +- +- PATH_RPCGEN="$RPCGEN" +-else +- as_fn_error $? "required program RPCGEN not found" "$LINENO" 5 +-fi +- + + if test -z "$sssldir"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sssd autofs library" >&5 +diff --git a/configure.in b/configure.in +index a38d6655..e774b4cc 100644 +--- a/configure.in ++++ b/configure.in +@@ -164,7 +164,6 @@ AF_PATH_INCLUDE(E4FSCK, fsck.ext4 e4fsck, , $searchpath) + AF_CHECK_PROG(LEX, flex lex, , $searchpath) + AF_CHECK_PROG(YACC, bison, , $searchpath) + AF_CHECK_PROG(RANLIB, ranlib, , $searchpath) +-AF_CHECK_PROG(RPCGEN, rpcgen, , $searchpath) + + AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so) + AC_SUBST(HAVE_SSS_AUTOFS) +diff --git a/include/automount.h b/include/automount.h +index 1ae40786..2f09e8e7 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -32,7 +32,6 @@ + #include "macros.h" + #include "log.h" + #include "rpc_subs.h" +-#include "mounts.h" + #include "parse_subs.h" + #include "mounts.h" + #include "dev-ioctl-lib.h" +diff --git a/include/config.h.in b/include/config.h.in +index a4879494..4e36b390 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -135,9 +135,6 @@ + /* define if you have RANLIB */ + #undef PATH_RANLIB + +-/* define if you have RPCGEN */ +-#undef PATH_RPCGEN +- + /* define if you have UMOUNT */ + #undef PATH_UMOUNT + +diff --git a/lib/Makefile b/lib/Makefile +index 83a80a1e..d18c67b5 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -8,10 +8,9 @@ include ../Makefile.rules + SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \ + nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \ + parse_subs.c dev-ioctl-lib.c +-RPCS = mount.h mount_clnt.c mount_xdr.c +-OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \ +- mounts.o log.o nsswitch.o nss_tok.o nss_parse.tab.o args.o \ +- alarm.o macros.o defaults.o parse_subs.o dev-ioctl-lib.o ++OBJS = cache.o cat_path.o rpc_subs.o mounts.o log.o nsswitch.o \ ++ nss_tok.o nss_parse.tab.o args.o alarm.o macros.o defaults.o \ ++ parse_subs.o dev-ioctl-lib.o + + YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h + +@@ -33,23 +32,6 @@ libautofs.so: $(OBJS) + $(CC) $(SOLDFLAGS) $(CFLAGS) -o $*.so $^ $(LDFLAGS) $(LIBS) + $(STRIP) $*.so + +-mount.h: mount.x +- $(RPCGEN) -h -o mount.h mount.x +- +-mount_clnt.c: mount.h +- $(RPCGEN) -l -o mount_clnt.c mount.x +- +-mount_clnt.o: mount_clnt.c +- $(CC) $(CFLAGS) -o mount_clnt.o -c mount_clnt.c +- $(STRIP) mount_clnt.o +- +-mount_xdr.c: mount.h +- $(RPCGEN) -c -o mount_xdr.c mount.x +- +-mount_xdr.o: mount_xdr.c +- $(CC) $(CFLAGS) -Wno-unused-variable -o mount_xdr.o -c mount_xdr.c +- $(STRIP) mount_xdr.o +- + nss_tok.c: nss_tok.l + $(LEX) -o$@ -Pnss_ $? + +@@ -60,8 +42,6 @@ nss_tok.o: nss_tok.c nss_parse.tab.h + + nss_parse.tab.o: nss_parse.tab.c nss_parse.tab.h + +-rpc_subs.o: mount.h +- + install: all + install -d -m 755 $(INSTALLROOT)$(autofslibdir) + install -c $(LIB) -m 755 $(INSTALLROOT)$(sharedlibdir) +diff --git a/lib/mount.x b/lib/mount.x +deleted file mode 100644 +index f504e7cf..00000000 +--- a/lib/mount.x ++++ /dev/null +@@ -1,345 +0,0 @@ +-%/* +-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +-% * unrestricted use provided that this legend is included on all tape +-% * media and as a part of the software program in whole or part. Users +-% * may copy or modify Sun RPC without charge, but are not authorized +-% * to license or distribute it to anyone else except as part of a product or +-% * program developed by the user or with the express written consent of +-% * Sun Microsystems, Inc. +-% * +-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +-% * +-% * Sun RPC is provided with no support and without any obligation on the +-% * part of Sun Microsystems, Inc. to assist in its use, correction, +-% * modification or enhancement. +-% * +-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +-% * OR ANY PART THEREOF. +-% * +-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +-% * or profits or other special, indirect and consequential damages, even if +-% * Sun has been advised of the possibility of such damages. +-% * +-% * Sun Microsystems, Inc. +-% * 2550 Garcia Avenue +-% * Mountain View, California 94043 +-% */ +- +-%/* +-% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc. +-% */ +-% +-%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */ +- +-/* +- * Protocol description for the mount program +- */ +- +-#ifdef RPC_HDR +-%#ifndef _rpcsvc_mount_h +-%#define _rpcsvc_mount_h +-%#include +-#endif +- +-const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +-const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +-const FHSIZE = 32; /* size in bytes of a file handle */ +- +-/* +- * The fhandle is the file handle that the server passes to the client. +- * All file operations are done using the file handles to refer to a file +- * or a directory. The file handle can contain whatever information the +- * server needs to distinguish an individual file. +- */ +-typedef opaque fhandle[FHSIZE]; +- +-/* +- * If a status of zero is returned, the call completed successfully, and +- * a file handle for the directory follows. A non-zero status indicates +- * some sort of error. The status corresponds with UNIX error numbers. +- */ +-union fhstatus switch (unsigned fhs_status) { +-case 0: +- fhandle fhs_fhandle; +-default: +- void; +-}; +- +-/* +- * The type dirpath is the pathname of a directory +- */ +-typedef string dirpath; +- +-/* +- * The type name is used for arbitrary names (hostnames, groupnames) +- */ +-typedef string name; +- +-/* +- * A list of who has what mounted +- */ +-typedef struct mountbody *mountlist; +-struct mountbody { +- name ml_hostname; +- dirpath ml_directory; +- mountlist ml_next; +-}; +- +-/* +- * A list of netgroups +- */ +-typedef struct groupnode *groups; +-struct groupnode { +- name gr_name; +- groups gr_next; +-}; +- +-/* +- * A list of what is exported and to whom +- */ +-typedef struct exportnode *exports; +-struct exportnode { +- dirpath ex_dir; +- groups ex_groups; +- exports ex_next; +-}; +- +-/* +- * POSIX pathconf information +- */ +-struct ppathcnf { +- int pc_link_max; /* max links allowed */ +- short pc_max_canon; /* max line len for a tty */ +- short pc_max_input; /* input a tty can eat all at once */ +- short pc_name_max; /* max file name length (dir entry) */ +- short pc_path_max; /* max path name length (/x/y/x/.. ) */ +- short pc_pipe_buf; /* size of a pipe (bytes) */ +- u_char pc_vdisable; /* safe char to turn off c_cc[i] */ +- char pc_xxx; /* alignment padding; cc_t == char */ +- short pc_mask[2]; /* validity and boolean bits */ +-}; +- +-/* +- * NFSv3 file handle +- */ +-const FHSIZE3 = 64; /* max size of NFSv3 file handle in bytes */ +-typedef opaque fhandle3; +- +-/* +- * NFSv3 mount status +- */ +-enum mountstat3 { +- MNT_OK = 0, /* no error */ +- MNT3ERR_PERM = 1, /* not owner */ +- MNT3ERR_NOENT = 2, /* no such file or directory */ +- MNT3ERR_IO = 5, /* I/O error */ +- MNT3ERR_ACCES = 13, /* Permission denied */ +- MNT3ERR_NOTDIR = 20, /* Not a directory */ +- MNT3ERR_INVAL = 22, /* Invalid argument */ +- MNT3ERR_NAMETOOLONG = 63, /* File name too long */ +- MNT3ERR_NOTSUPP = 10004,/* Operation not supported */ +- MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ +-}; +- +-/* +- * NFSv3 mount result +- */ +-struct mountres3_ok { +- fhandle3 fhandle; +- int auth_flavors<>; +-}; +- +-union mountres3 switch (mountstat3 fhs_status) { +-case MNT_OK: +- mountres3_ok mountinfo; /* File handle and supported flavors */ +-default: +- void; +-}; +- +-program MOUNTPROG { +- /* +- * Version one of the mount protocol communicates with version two +- * of the NFS protocol. The only connecting point is the fhandle +- * structure, which is the same for both protocols. +- */ +- version MOUNTVERS { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- fhstatus +- MOUNTPROC_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC_EXPORT(void) = 5; +- +- /* +- * Identical to MOUNTPROC_EXPORT above +- */ +- exports +- MOUNTPROC_EXPORTALL(void) = 6; +- } = 1; +- +- /* +- * Version two of the mount protocol communicates with version two +- * of the NFS protocol. +- * The only difference from version one is the addition of a POSIX +- * pathconf call. +- */ +- version MOUNTVERS_POSIX { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- fhstatus +- MOUNTPROC_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC_EXPORT(void) = 5; +- +- /* +- * Identical to MOUNTPROC_EXPORT above +- */ +- exports +- MOUNTPROC_EXPORTALL(void) = 6; +- +- /* +- * POSIX pathconf info (Sun hack) +- */ +- ppathcnf +- MOUNTPROC_PATHCONF(dirpath) = 7; +- } = 2; +- +- /* +- * Version 3 of the protocol is for NFSv3 +- */ +- version MOUNTVERS_NFSV3 { +- /* +- * Does no work. It is made available in all RPC services +- * to allow server reponse testing and timing +- */ +- void +- MOUNTPROC3_NULL(void) = 0; +- +- /* +- * If fhs_status is 0, then fhs_fhandle contains the +- * file handle for the directory. This file handle may +- * be used in the NFS protocol. This procedure also adds +- * a new entry to the mount list for this client mounting +- * the directory. +- * Unix authentication required. +- */ +- mountres3 +- MOUNTPROC3_MNT(dirpath) = 1; +- +- /* +- * Returns the list of remotely mounted filesystems. The +- * mountlist contains one entry for each hostname and +- * directory pair. +- */ +- mountlist +- MOUNTPROC3_DUMP(void) = 2; +- +- /* +- * Removes the mount list entry for the directory +- * Unix authentication required. +- */ +- void +- MOUNTPROC3_UMNT(dirpath) = 3; +- +- /* +- * Removes all of the mount list entries for this client +- * Unix authentication required. +- */ +- void +- MOUNTPROC3_UMNTALL(void) = 4; +- +- /* +- * Returns a list of all the exported filesystems, and which +- * machines are allowed to import it. +- */ +- exports +- MOUNTPROC3_EXPORT(void) = 5; +- } = 3; +-} = 100005; +- +-#ifdef RPC_HDR +-%#endif /*!_rpcsvc_mount_h*/ +-#endif diff --git a/SOURCES/autofs-5.1.7-remove-mounts_mutex.patch b/SOURCES/autofs-5.1.7-remove-mounts_mutex.patch new file mode 100644 index 0000000..7fdebe7 --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-mounts_mutex.patch @@ -0,0 +1,178 @@ +autofs-5.1.7 - remove mounts_mutex + +From: Ian Kent + +The mounts_mutex is no longer used, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 8 +------- + daemon/master.c | 13 ------------- + include/automount.h | 1 - + modules/mount_autofs.c | 8 -------- + 5 files changed, 2 insertions(+), 29 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 42914160..9d0f4278 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -48,6 +48,7 @@ + - remove unused function master_submount_list_empty(). + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. ++- remove mounts_mutex. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index 7833dfae..28c4d1ee 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1754,7 +1754,6 @@ static void handle_mounts_cleanup(void *arg) + * here. + */ + if (submount) { +- mounts_mutex_unlock(ap->parent); + master_source_unlock(ap->parent->entry); + master_free_mapent_sources(ap->entry, 1); + master_free_mapent(ap->entry); +@@ -1792,13 +1791,9 @@ static int submount_source_writelock_nested(struct autofs_point *ap) + if (status) + goto done; + +- mounts_mutex_lock(parent); +- + status = pthread_rwlock_trywrlock(&ap->entry->source_lock); +- if (status) { +- mounts_mutex_unlock(parent); ++ if (status) + master_source_unlock(parent->entry); +- } + + done: + if (status && status != EBUSY) { +@@ -1814,7 +1809,6 @@ static void submount_source_unlock_nested(struct autofs_point *ap) + struct autofs_point *parent = ap->parent; + + master_source_unlock(ap->entry); +- mounts_mutex_unlock(parent); + master_source_unlock(parent->entry); + } + +diff --git a/daemon/master.c b/daemon/master.c +index b288e070..30d7cf98 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -69,7 +69,6 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + unsigned nobind, unsigned ghost, int submount) + { + struct autofs_point *ap; +- int status; + + ap = malloc(sizeof(struct autofs_point)); + if (!ap) +@@ -128,12 +127,6 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + INIT_LIST_HEAD(&ap->amdmounts); + ap->shutdown = 0; + +- status = pthread_mutex_init(&ap->mounts_mutex, NULL); +- if (status) { +- free(ap->path); +- free(ap); +- return 0; +- } + ap->mode = 0; + + entry->ap = ap; +@@ -143,17 +136,11 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + + void master_free_autofs_point(struct autofs_point *ap) + { +- int status; +- + if (!ap) + return; + + mnts_remove_amdmounts(ap); + +- status = pthread_mutex_destroy(&ap->mounts_mutex); +- if (status) +- fatal(status); +- + if (ap->pref) + free(ap->pref); + free(ap->path); +diff --git a/include/automount.h b/include/automount.h +index e33ee8d2..51a0bf0e 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -565,7 +565,6 @@ struct autofs_point { + enum states state; /* Current state */ + int state_pipe[2]; /* State change router pipe */ + struct autofs_point *parent; /* Owner of mounts list for submount */ +- pthread_mutex_t mounts_mutex; /* Protect mount lists */ + struct list_head mounts; /* List of autofs mounts at current level */ + unsigned int submount; /* Is this a submount */ + unsigned int submnt_count; /* Number of submounts */ +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 1c40e27a..0bcbb343 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -283,8 +283,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + set_exp_timeout(nap, NULL, timeout); + nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + +- mounts_mutex_lock(ap); +- + if (source->flags & MAP_FLAG_FORMAT_AMD) { + struct mnt_list *mnt; + +@@ -305,7 +303,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + if (handle_mounts_startup_cond_init(&suc)) { + crit(ap->logopt, MODPREFIX + "failed to init startup cond for mount %s", entry->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -316,7 +313,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + crit(ap->logopt, + MODPREFIX "failed to allocate mount %s", realpath); + handle_mounts_startup_cond_destroy(&suc); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -335,7 +331,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + realpath); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -346,7 +341,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + if (status) { + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + fatal(status); +@@ -358,7 +352,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + MODPREFIX "failed to create submount for %s", realpath); + handle_mounts_startup_cond_destroy(&suc); + mnts_remove_submount(nap->path); +- mounts_mutex_unlock(ap); + master_free_map_source(source, 1); + master_free_mapent(entry); + return 1; +@@ -368,7 +361,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + ap->submnt_count++; + + handle_mounts_startup_cond_destroy(&suc); +- mounts_mutex_unlock(ap); + + return 0; + } diff --git a/SOURCES/autofs-5.1.7-remove-obsolete-functions.patch b/SOURCES/autofs-5.1.7-remove-obsolete-functions.patch new file mode 100644 index 0000000..45c22fb --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-obsolete-functions.patch @@ -0,0 +1,752 @@ +autofs-5.1.7 - remove obsolete functions + +From: Ian Kent + +Remove the code that's no longer used due to the tree mapent +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/automount.h | 10 -- + include/mounts.h | 2 + lib/cache.c | 227 ------------------------------------- + lib/mounts.c | 311 --------------------------------------------------- + modules/parse_sun.c | 56 --------- + 6 files changed, 2 insertions(+), 605 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5ac09f77..76fccf70 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -41,6 +41,7 @@ + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. ++- remove obsolete functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index a71b8674..e33ee8d2 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -162,16 +162,13 @@ struct stack { + struct mapent { + struct mapent *next; + struct list_head ino_index; +- struct list_head multi_list; + struct mapent_cache *mc; + struct map_source *source; + /* Need to know owner if we're a multi-mount */ + struct tree_node *mm_root; ++ /* Parent nesting point within multi-mount */ + struct tree_node *mm_parent; + struct tree_node node; +- struct mapent *multi; +- /* Parent nesting point within multi-mount */ +- struct mapent *parent; + char *key; + size_t len; + char *mapent; +@@ -209,7 +206,6 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me); + struct mapent *cache_lookup_key_next(struct mapent *me); + struct mapent *cache_lookup(struct mapent_cache *mc, const char *key); + 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); + struct mapent *cache_partial_match_wild(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); +@@ -217,16 +213,12 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k + int cache_lookup_negative(struct mapent *me, const char *key); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); + struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key); +-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); +-int cache_delete_offset_list(struct mapent_cache *mc, const char *key); + void cache_release(struct map_source *map); + void cache_clean_null_cache(struct mapent_cache *mc); + void cache_release_null_cache(struct master *master); + struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me); +-char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos); + + /* Utility functions */ + +diff --git a/include/mounts.h b/include/mounts.h +index e56f80ba..ec895e1c 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -187,8 +187,6 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *); + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); + int umount_amd_ext_mount(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 +diff --git a/lib/cache.c b/lib/cache.c +index 93b02daf..ef761739 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -461,30 +461,6 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key) + return NULL; + } + +-/* Lookup an offset within a multi-mount entry */ +-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head) +-{ +- struct list_head *p; +- struct mapent *this; +- /* Keys for direct maps may be as long as a path name */ +- char o_key[PATH_MAX]; +- /* Avoid "//" at the beginning of paths */ +- const char *path_prefix = strlen(prefix) > 1 ? prefix : ""; +- size_t size; +- +- /* root offset duplicates "/" */ +- size = snprintf(o_key, sizeof(o_key), "%s%s", path_prefix, offset); +- if (size >= sizeof(o_key)) +- return NULL; +- +- list_for_each(p, head) { +- this = list_entry(p, struct mapent, multi_list); +- if (!strcmp(&this->key[start], o_key)) +- return this; +- } +- return NULL; +-} +- + /* cache must be read locked by caller */ + static struct mapent *__cache_partial_match(struct mapent_cache *mc, + const char *prefix, +@@ -583,9 +559,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + me->mm_parent = NULL; + INIT_TREE_NODE(&me->node); + INIT_LIST_HEAD(&me->ino_index); +- INIT_LIST_HEAD(&me->multi_list); +- me->multi = NULL; +- me->parent = NULL; + me->ioctlfd = -1; + me->dev = (dev_t) -1; + me->ino = (ino_t) -1; +@@ -615,33 +588,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + return CHE_OK; + } + +-/* cache must be write locked by caller */ +-static void cache_add_ordered_offset(struct mapent *me, struct list_head *head) +-{ +- struct list_head *p; +- struct mapent *this; +- +- list_for_each(p, head) { +- size_t tlen; +- int eq; +- +- this = list_entry(p, struct mapent, multi_list); +- tlen = strlen(this->key); +- +- eq = strncmp(this->key, me->key, tlen); +- if (!eq && tlen == strlen(me->key)) +- return; +- +- if (eq > 0) { +- list_add_tail(&me->multi_list, p); +- return; +- } +- } +- list_add_tail(&me->multi_list, p); +- +- return; +-} +- + /* cache must be write locked by caller */ + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age) + { +@@ -777,25 +723,6 @@ struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key) + return NULL; + } + +-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) +-{ +- struct mapent *this, *parent; +- +- this = cache_lookup_distinct(mc, offset); +- if (!this) +- return 0; +- if (!IS_MM(this)) +- return 0; +- +- parent = cache_get_offset_parent(mc, offset); +- if (parent) +- this->parent = parent; +- else +- this->parent = MM_ROOT(this); +- +- return 1; +-} +- + /* cache must be write locked by caller */ + int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age) + { +@@ -837,50 +764,6 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key + return ret; + } + +-/* cache write 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 (IS_MM(me) && IS_MM_ROOT(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 (IS_MM(me) && IS_MM_ROOT(me)) +- return CHE_FAIL; +- pred->next = me->next; +- goto delete; +- } +- } +- +- return CHE_FAIL; +- +-delete: +- 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) + { +@@ -1054,113 +937,3 @@ struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me) + + return cache_lookup_next(mc, me); + } +- +-/* +- * Get each offset from list head under prefix. +- * Maintain traversal current position in pos for subsequent calls. +- * Return each offset into offset. +- */ +-/* cache must be read locked by caller */ +-char *cache_get_offset(const char *prefix, char *offset, int start, +- struct list_head *head, struct list_head **pos) +-{ +- struct list_head *next; +- struct mapent *this; +- size_t plen = strlen(prefix); +- size_t len = 0; +- +- if (*pos == head) +- return NULL; +- +- /* Find an offset */ +- *offset = '\0'; +- next = *pos ? (*pos)->next : head->next; +- while (next != head) { +- char *offset_start, *pstart, *pend; +- +- this = list_entry(next, struct mapent, multi_list); +- *pos = next; +- next = next->next; +- +- offset_start = &this->key[start]; +- if (strlen(offset_start) <= plen) +- continue; +- +- if (!strncmp(prefix, offset_start, plen)) { +- struct mapent *np = NULL; +- char pe[PATH_MAX + 1]; +- +- /* "/" doesn't count for root offset */ +- if (plen == 1) +- pstart = &offset_start[plen - 1]; +- else +- pstart = &offset_start[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- continue; +- +- /* get next offset */ +- pend = pstart; +- while (*pend++) { +- size_t nest_pt_offset; +- +- if (*pend != '/') +- continue; +- +- nest_pt_offset = start + pend - pstart; +- if (plen > 1) +- nest_pt_offset += plen; +- strcpy(pe, this->key); +- pe[nest_pt_offset] = '\0'; +- +- np = cache_lookup_distinct(this->mc, pe); +- if (np) +- break; +- } +- if (np) +- continue; +- len = pend - pstart - 1; +- strncpy(offset, pstart, len); +- offset[len] ='\0'; +- break; +- } +- } +- +- /* Seek to next offset */ +- while (next != head) { +- char *offset_start, *pstart; +- +- this = list_entry(next, struct mapent, multi_list); +- +- offset_start = &this->key[start]; +- if (strlen(offset_start) <= plen + len) +- break; +- +- /* "/" doesn't count for root offset */ +- if (plen == 1) +- pstart = &offset_start[plen - 1]; +- else +- pstart = &offset_start[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- break; +- +- /* new offset */ +- if (!*(pstart + len + 1)) +- break; +- +- /* compare offset */ +- if (pstart[len] != '/' || +- strlen(pstart) != len || +- strncmp(offset, pstart, len)) +- break; +- +- *pos = next; +- next = next->next; +- } +- +- return *offset ? offset : NULL; +-} +- +diff --git a/lib/mounts.c b/lib/mounts.c +index 6ca7eff1..c120d2a8 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2853,21 +2853,6 @@ static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me + tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL); + } + +-static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) +-{ +- if (!list_empty(&me->multi_list)) { +- struct list_head *head = &me->multi_list; +- struct list_head *p; +- +- list_for_each(p, head) { +- struct mapent *this; +- +- this = list_entry(p, struct mapent, multi_list); +- set_mount_catatonic(ap, this, this->ioctlfd); +- } +- } +-} +- + void set_indirect_mount_tree_catatonic(struct autofs_point *ap) + { + struct master_mapent *entry = ap->entry; +@@ -3034,299 +3019,3 @@ done: + out: + return rv; + } +- +-static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe) +-{ +- int mounted = 0; +- int ret; +- +- debug(ap->logopt, "mount offset %s", oe->key); +- +- ret = mount_autofs_offset(ap, oe); +- 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); +- /* +- * Ok, so we shouldn't modify the mapent but +- * mount requests are blocked at a point above +- * this and expire only uses the mapent key or +- * holds the cache write lock. +- */ +- free(oe->mapent); +- oe->mapent = NULL; +- } +- } +- +- return mounted; +-} +- +-static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe) +-{ +- char *dir, *path; +- unsigned int split; +- int ret; +- +- if (ap->type == LKP_DIRECT) +- return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev); +- +- dir = strdup(oe->key); +- +- if (ap->flags & MOUNT_FLAG_GHOST) +- split = ap->len + strlen(MM_ROOT(oe)->key) + 1; +- else +- split = ap->len; +- +- dir[split] = '\0'; +- path = &dir[split + 1]; +- +- if (chdir(dir) == -1) { +- error(ap->logopt, "failed to chdir to %s", dir); +- free(dir); +- return -1; +- } +- +- ret = rmdir_path(ap, path, ap->dev); +- +- free(dir); +- +- if (chdir("/") == -1) +- error(ap->logopt, "failed to chdir to /"); +- +- return ret; +-} +- +-static int do_umount_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, int start); +- +-static int do_umount_multi_triggers(struct autofs_point *ap, +- struct mapent *me, const char *root, +- int start, const char *base) +-{ +- char path[PATH_MAX + 1]; +- char *offset; +- struct mapent *oe; +- struct list_head *mm_root, *pos; +- const char o_root[] = "/"; +- const char *mm_base; +- int left; +- unsigned int root_len; +- unsigned int mm_base_len; +- +- left = 0; +- +- mm_root = &me->multi->multi_list; +- +- if (!base) +- mm_base = o_root; +- else +- mm_base = base; +- +- pos = NULL; +- offset = path; +- root_len = start; +- mm_base_len = strlen(mm_base); +- +- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (mm_base_len > 1) +- key_len += mm_base_len; +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(key, root); +- if (mm_base_len > 1) +- strcat(key, mm_base); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- /* root offset is a special case */ +- if (!oe || (strlen(oe->key) - start) == 1) +- continue; +- +- left += do_umount_offset(ap, oe, root, start); +- } +- +- return left; +-} +- +-static int do_umount_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, int start) +-{ +- char *oe_base; +- int left = 0; +- +- /* +- * Check for and umount subtree offsets resulting from +- * nonstrict mount fail. +- */ +- oe_base = oe->key + start; +- left += do_umount_multi_triggers(ap, oe, root, start, oe_base); +- +- /* +- * 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(oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key) && +- is_mounted(oe->key, MNTS_REAL)) { +- debug(ap->logopt, +- "offset %s has active mount, invalidate", +- oe->key); +- /* +- * Ok, so we shouldn't modify the mapent but +- * mount requests are blocked at a point above +- * this and expire only uses the mapent key or +- * holds the cache write lock. +- */ +- if (oe->mapent) { +- free(oe->mapent); +- oe->mapent = NULL; +- } +- return ++left; +- } +- } +- +- 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)) +- return left; +- +- /* +- * 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_offset(ap, oe); +- if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe); +- if (ret) +- left++; +- /* But we did origianlly create this */ +- oe->flags |= MOUNT_FLAG_DIR_CREATED; +- } +- } +- return left; +-} +- +-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, +- const char *root, unsigned int start, const char *base) +-{ +- char path[PATH_MAX + 1]; +- char *offset = path; +- struct mapent *oe; +- struct list_head *pos = NULL; +- unsigned int root_len = strlen(root); +- int mounted; +- +- mounted = 0; +- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos); +- while (offset) { +- char key[PATH_MAX + 1]; +- int key_len = root_len + strlen(offset); +- +- if (key_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- goto cont; +- } +- +- /* The root offset is always mounted seperately so the +- * offset path will always be root + offset. +- */ +- strcpy(key, root); +- strcat(key, offset); +- +- oe = cache_lookup_distinct(me->mc, key); +- if (!oe || !oe->mapent) +- goto cont; +- if (oe->age != MM_ROOT(me)->age) { +- /* Best effort */ +- do_umount_offset(ap, oe, root, start); +- goto cont; +- } +- +- mounted += do_mount_autofs_offset(ap, oe); +- +- /* +- * 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(oe->key, MNTS_REAL)) +- mount_multi_triggers(ap, oe, key, key_len, base); +- } +-cont: +- offset = cache_get_offset(base, +- offset, start, &me->multi_list, &pos); +- } +- +- return mounted; +-} +- +-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base) +-{ +- int left, start; +- +- start = strlen(root); +- +- left = do_umount_multi_triggers(ap, me, root, start, base); +- +- if (!left && IS_MM_ROOT(me)) { +- /* +- * Special case. +- * If we can't umount the root container then we can't +- * delete the offsets from the cache and we need to put +- * the offset triggers back. +- */ +- if (is_mounted(root, MNTS_REAL)) { +- info(ap->logopt, "unmounting dir = %s", root); +- if (umount_ent(ap, root) && +- is_mounted(root, MNTS_REAL)) { +- if (mount_multi_triggers(ap, me, root, start, "/") < 0) +- warn(ap->logopt, +- "failed to remount offset triggers"); +- return ++left; +- } +- } +- +- /* check for mounted mount entry and remove it if found */ +- mnts_remove_mount(root, MNTS_MOUNTED); +- } +- +- return left; +-} +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index d6ef48b8..ef74eda9 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1074,62 +1074,6 @@ next: + return (p - ent); + } + +-static void cleanup_multi_triggers(struct autofs_point *ap, +- struct mapent *me, const char *root, int start, +- const char *base) +-{ +- char path[PATH_MAX + 1]; +- char offset[PATH_MAX + 1]; +- char *poffset = offset; +- struct mapent *oe; +- struct list_head *mm_root, *pos; +- const char o_root[] = "/"; +- const char *mm_base; +- unsigned int root_len; +- unsigned int mm_base_len; +- +- mm_root = &me->multi->multi_list; +- +- if (!base) +- mm_base = o_root; +- else +- mm_base = base; +- +- pos = NULL; +- root_len = strlen(root); +- mm_base_len = strlen(mm_base); +- +- /* Make sure "none" of the offsets have an active mount. */ +- while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) { +- unsigned int path_len = root_len + strlen(poffset); +- +- if (mm_base_len > 1) +- path_len += mm_base_len; +- +- if (path_len > PATH_MAX) { +- warn(ap->logopt, "path loo long"); +- continue; +- } +- +- strcpy(path, root); +- if (mm_base_len > 1) +- strcat(path, mm_base); +- strcat(path, poffset); +- +- oe = cache_lookup_distinct(me->mc, path); +- /* root offset is a special case */ +- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) +- continue; +- +- if (umount(path)) { +- error(ap->logopt, "error recovering from mount fail"); +- error(ap->logopt, "cannot umount offset %s", path); +- } +- } +- +- return; +-} +- + static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + const char *name, char *loc, char *options, void *ctxt) + { diff --git a/SOURCES/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch b/SOURCES/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch new file mode 100644 index 0000000..44cdc66 --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts() + +From: Ian Kent + +Coverity: missing_lock: Accessing "entry->current" without holding lock + "master_mapent.current_mutex". + +This is initialization not clearing current source. But the field has +already been initialized in the master_new_mapent() call. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c7bc0c39..f95b1aa6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -58,6 +58,7 @@ + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. ++- remove redundant assignment in master_add_amd_mount_section_mounts(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master.c b/daemon/master.c +index 30d7cf98..84743f80 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -996,7 +996,6 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag + source->master_line = 0; + + entry->age = age; +- entry->current = NULL; + + master_add_mapent(master, entry); + next: diff --git a/SOURCES/autofs-5.1.7-remove-redundant-if-check.patch b/SOURCES/autofs-5.1.7-remove-redundant-if-check.patch new file mode 100644 index 0000000..86948ea --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-redundant-if-check.patch @@ -0,0 +1,40 @@ +autofs-5.1.7 - remove redundant if check + +From: Ian Kent + +Coverity: identical code in if condition branches. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 5 +---- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 62a918a9..2186cbe3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -51,6 +51,7 @@ + - remove mounts_mutex. + - remove unused variable from get_exports(). + - add missing free in handle_mounts(). ++- remove redundant if check. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index 3f4f5704..a33f9f91 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + + 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, me->key, timeout, str_offset); +- else +- notify_mount_result(ap, me->key, timeout, str_offset); ++ notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + + debug(ap->logopt, "mounted trigger %s", me->key); diff --git a/SOURCES/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch b/SOURCES/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch new file mode 100644 index 0000000..849d481 --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch @@ -0,0 +1,74 @@ +autofs-5.1.7 - remove redundant local var from sun_mount() + +From: Ian Kent + +The local variable mountpoint in sun_mount() is set directly from a +passed in parameter and never changed and the source isn't changed +either, so use the variable directly. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 13 ++++--------- + 2 files changed, 5 insertions(+), 9 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 76fccf70..444ade5b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -42,6 +42,7 @@ + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. + - remove obsolete functions. ++- remove redundant local var from sun_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index ef74eda9..437869b5 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -530,7 +530,6 @@ static int sun_mount(struct autofs_point *ap, const char *root, + int nonstrict = 1; + int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY; + int rv, cur_state; +- char *mountpoint; + char *what; + char *type; + +@@ -624,9 +623,6 @@ static int sun_mount(struct autofs_point *ap, const char *root, + } + } + +- mountpoint = alloca(namelen + 1); +- sprintf(mountpoint, "%.*s", namelen, name); +- + type = ap->entry->maps->type; + if (type && !strcmp(type, "hosts")) { + if (options && *options != '\0') { +@@ -698,9 +694,9 @@ static int sun_mount(struct autofs_point *ap, const char *root, + debug(ap->logopt, MODPREFIX + "mounting root %s, mountpoint %s, " + "what %s, fstype %s, options %s", +- root, mountpoint, what, fstype, options); ++ root, name, what, fstype, options); + +- rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint), ++ rv = mount_nfs->mount_mount(ap, root, name, namelen, + what, fstype, options, mount_nfs->context); + } else { + if (!loclen) +@@ -720,11 +716,10 @@ static int sun_mount(struct autofs_point *ap, const char *root, + debug(ap->logopt, MODPREFIX + "mounting root %s, mountpoint %s, " + "what %s, fstype %s, options %s", +- root, mountpoint, what, fstype, options); ++ root, name, what, fstype, options); + + /* Generic mount routine */ +- rv = do_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype, +- options); ++ rv = do_mount(ap, root, name, namelen, what, fstype, options); + } + pthread_setcancelstate(cur_state, NULL); + diff --git a/SOURCES/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch b/SOURCES/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch new file mode 100644 index 0000000..9e7420d --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch @@ -0,0 +1,182 @@ +autofs-5.1.7 - remove redundant variables from mount_autofs_offset() + +From: Ian Kent + +The path to be mounted is the key in the passed in mapent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 42 +++++++++++++++++++----------------------- + include/automount.h | 2 +- + lib/mounts.c | 2 +- + 4 files changed, 22 insertions(+), 25 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c4ebb52f..45be4783 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ + - fix is mounted check on non existent path. + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). ++- remove redundant variables from mount_autofs_offset(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/direct.c b/daemon/direct.c +index 9fe4903a..c41c680f 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -611,7 +611,7 @@ force_umount: + return rv; + } + +-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset) ++int mount_autofs_offset(struct autofs_point *ap, struct mapent *me) + { + const char *str_offset = mount_type_str(t_offset); + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -623,7 +623,6 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + const char *hosts_map_name = "-hosts"; + const char *map_name = hosts_map_name; + const char *type; +- char mountpoint[PATH_MAX]; + struct mnt_list *mnt; + + if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) { +@@ -681,11 +680,8 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + return MOUNT_OFFSET_OK; + } + +- strcpy(mountpoint, root); +- strcat(mountpoint, offset); +- + /* In case the directory doesn't exist, try to mkdir it */ +- if (mkdir_path(mountpoint, mp_mode) < 0) { ++ if (mkdir_path(me->key, mp_mode) < 0) { + if (errno == EEXIST) { + /* + * If the mount point directory is a real mount +@@ -694,7 +690,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + * the kernel NFS client. + */ + if (me->multi != me && +- is_mounted(mountpoint, MNTS_REAL)) ++ is_mounted(me->key, MNTS_REAL)) + return MOUNT_OFFSET_IGNORE; + + /* +@@ -714,13 +710,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + debug(ap->logopt, + "can't create mount directory: %s, %s", +- mountpoint, estr); ++ me->key, estr); + return MOUNT_OFFSET_FAIL; + } else { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + crit(ap->logopt, + "failed to create mount directory: %s, %s", +- mountpoint, estr); ++ me->key, estr); + return MOUNT_OFFSET_FAIL; + } + } else { +@@ -730,56 +726,56 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char * + + debug(ap->logopt, + "calling mount -t autofs " SLOPPY " -o %s automount %s", +- mp->options, mountpoint); ++ mp->options, me->key); + + type = ap->entry->maps->type; + if (!type || strcmp(ap->entry->maps->type, "hosts")) + map_name = me->mc->map->argv[0]; + +- ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options); ++ ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options); + if (ret) { + crit(ap->logopt, + "failed to mount offset trigger %s at %s", +- me->key, mountpoint); ++ me->key, me->key); + goto out_err; + } + +- ret = stat(mountpoint, &st); ++ ret = stat(me->key, &st); + if (ret == -1) { + error(ap->logopt, +- "failed to stat direct mount trigger %s", mountpoint); ++ "failed to stat direct mount trigger %s", me->key); + goto out_umount; + } + +- ops->open(ap->logopt, &ioctlfd, st.st_dev, mountpoint); ++ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); + if (ioctlfd < 0) { +- crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint); ++ crit(ap->logopt, "failed to create ioctl fd for %s", me->key); + goto out_umount; + } + + 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, timeout, str_offset); ++ notify_mount_result(ap, me->key, timeout, str_offset); + else + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); + +- mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET); ++ mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET); + if (!mnt) + error(ap->logopt, + "failed to add offset mount %s to mounted list", +- mountpoint); ++ me->key); + +- debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint); ++ debug(ap->logopt, "mounted trigger %s", me->key); + + return MOUNT_OFFSET_OK; + + out_umount: +- umount(mountpoint); ++ umount(me->key); + out_err: +- if (stat(mountpoint, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED) +- rmdir_path(ap, mountpoint, st.st_dev); ++ if (stat(me->key, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED) ++ rmdir_path(ap, me->key, st.st_dev); + + return MOUNT_OFFSET_FAIL; + } +diff --git a/include/automount.h b/include/automount.h +index 730be19a..09d84f05 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -596,7 +596,7 @@ 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 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); ++int mount_autofs_offset(struct autofs_point *ap, struct mapent *me); + void submount_signal_parent(struct autofs_point *ap, unsigned int success); + void close_mount_fds(struct autofs_point *ap); + int umount_autofs_indirect(struct autofs_point *ap, const char *root); +diff --git a/lib/mounts.c b/lib/mounts.c +index fe931b20..12d22023 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2481,7 +2481,7 @@ static int do_mount_autofs_offset(struct autofs_point *ap, + + debug(ap->logopt, "mount offset %s at %s", oe->key, root); + +- ret = mount_autofs_offset(ap, oe, root, offset); ++ ret = mount_autofs_offset(ap, oe); + if (ret >= MOUNT_OFFSET_OK) + mounted++; + else { diff --git a/SOURCES/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch b/SOURCES/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch new file mode 100644 index 0000000..1f86438 --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch @@ -0,0 +1,60 @@ +autofs-5.1.7 - remove unused function master_submount_list_empty() + +From: Ian Kent + +This function is not used anywhere now, remove it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/master.c | 12 ------------ + include/master.h | 1 - + 3 files changed, 1 insertion(+), 13 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 1c9e2a2d..002da042 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -45,6 +45,7 @@ + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). ++- remove unused function master_submount_list_empty(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/master.c b/daemon/master.c +index 022fb9dd..af9cd79f 100644 +--- a/daemon/master.c ++++ b/daemon/master.c +@@ -1119,18 +1119,6 @@ int master_read_master(struct master *master, time_t age) + return 1; + } + +-int master_submount_list_empty(struct autofs_point *ap) +-{ +- int res = 0; +- +- mounts_mutex_lock(ap); +- if (list_empty(&ap->submounts)) +- res = 1; +- mounts_mutex_unlock(ap); +- +- return res; +-} +- + int master_notify_submount(struct autofs_point *ap, const char *path, enum states state) + { + struct mnt_list *this, *sbmnt; +diff --git a/include/master.h b/include/master.h +index 0806b372..2d727943 100644 +--- a/include/master.h ++++ b/include/master.h +@@ -116,7 +116,6 @@ void master_free_mapent_sources(struct master_mapent *, unsigned int); + void master_free_mapent(struct master_mapent *); + struct master *master_new(const char *, unsigned int, unsigned int); + int master_read_master(struct master *, time_t); +-int master_submount_list_empty(struct autofs_point *ap); + int master_notify_submount(struct autofs_point *, const char *path, enum states); + void master_notify_state_change(struct master *, int); + int master_mount_mounts(struct master *, time_t); diff --git a/SOURCES/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch b/SOURCES/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch new file mode 100644 index 0000000..df75fec --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch @@ -0,0 +1,63 @@ +autofs-5.1.7 - remove unused functions cache_dump_multi() and cache_dump_cache() + +From: Ian Kent + +Remove debugging functions cache_dump_multi() and cache_dump_cache() + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 28 ---------------------------- + 2 files changed, 1 insertion(+), 28 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 3ba748d7..60924b3f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -29,6 +29,7 @@ + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. + - add some multi-mount macros. ++- remove unused functions cache_dump_multi() and cache_dump_cache(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/cache.c b/lib/cache.c +index 1d9f5cc7..629c4d0a 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -24,34 +24,6 @@ + + #include "automount.h" + +-void cache_dump_multi(struct list_head *list) +-{ +- struct list_head *p; +- struct mapent *me; +- +- list_for_each(p, list) { +- me = list_entry(p, struct mapent, multi_list); +- logmsg("key=%s", me->key); +- } +-} +- +-void cache_dump_cache(struct mapent_cache *mc) +-{ +- struct mapent *me; +- unsigned int i; +- +- for (i = 0; i < mc->size; i++) { +- me = mc->hash[i]; +- if (me == NULL) +- continue; +- while (me) { +- logmsg("me->key=%s me->multi=%p dev=%ld ino=%ld", +- me->key, me->multi, me->dev, me->ino); +- me = me->next; +- } +- } +-} +- + void cache_readlock(struct mapent_cache *mc) + { + int status; diff --git a/SOURCES/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch b/SOURCES/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch new file mode 100644 index 0000000..5130c4e --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch @@ -0,0 +1,179 @@ +autofs-5.1.7 - remove unused mount offset list lock functions + +From: Ian Kent + +When fixing the locking in parse_mount() it was evident that there was +no real benefit of having an additional lock for the offset list so its +use was eliminated. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 4 --- + lib/cache.c | 70 +-------------------------------------------------- + 3 files changed, 3 insertions(+), 72 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index d25b19c8..c5619d2e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,6 +19,7 @@ + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). ++- remove unused mount offset list lock functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index 09d84f05..69445b92 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -162,7 +162,6 @@ struct stack { + struct mapent { + struct mapent *next; + struct list_head ino_index; +- pthread_rwlock_t multi_rwlock; + struct list_head multi_list; + struct mapent_cache *mc; + struct map_source *source; +@@ -212,9 +211,6 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); + int cache_delete_offset_list(struct mapent_cache *mc, const char *key); + void cache_release(struct map_source *map); + void cache_clean_null_cache(struct mapent_cache *mc); +diff --git a/lib/cache.c b/lib/cache.c +index ce9e9bd2..03d0499a 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -108,58 +108,6 @@ void cache_lock_cleanup(void *arg) + return; + } + +-void cache_multi_readlock(struct mapent *me) +-{ +- int status; +- +- if (!me) +- return; +- +- status = pthread_rwlock_rdlock(&me->multi_rwlock); +- if (status) { +- logmsg("mapent cache multi mutex lock failed"); +- fatal(status); +- } +- return; +-} +- +-void cache_multi_writelock(struct mapent *me) +-{ +- int status; +- +- if (!me) +- return; +- +- status = pthread_rwlock_wrlock(&me->multi_rwlock); +- if (status) { +- logmsg("mapent cache multi mutex lock failed"); +- fatal(status); +- } +- return; +-} +- +-void cache_multi_unlock(struct mapent *me) +-{ +- int status; +- +- if (!me) +- return; +- +- status = pthread_rwlock_unlock(&me->multi_rwlock); +- if (status) { +- logmsg("mapent cache multi mutex unlock failed"); +- fatal(status); +- } +- return; +-} +- +-void cache_multi_lock_cleanup(void *arg) +-{ +- struct mapent *me = (struct mapent *) arg; +- cache_multi_unlock(me); +- return; +-} +- + static inline void ino_index_lock(struct mapent_cache *mc) + { + int status = pthread_mutex_lock(&mc->ino_index_mutex); +@@ -626,7 +574,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + struct mapent *me, *existing = NULL; + char *pkey, *pent; + u_int32_t hashval = hash(key, mc->size); +- int status; + + me = (struct mapent *) malloc(sizeof(struct mapent)); + if (!me) +@@ -665,10 +612,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + me->ino = (ino_t) -1; + me->flags = 0; + +- status = pthread_rwlock_init(&me->multi_rwlock, NULL); +- if (status) +- fatal(status); +- + /* + * We need to add to the end if values exist in order to + * preserve the order in which the map was read on lookup. +@@ -924,7 +867,7 @@ 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 */ ++/* cache write 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); +@@ -956,9 +899,6 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key) + 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); +@@ -976,7 +916,7 @@ int cache_delete(struct mapent_cache *mc, const char *key) + { + struct mapent *me = NULL, *pred; + u_int32_t hashval = hash(key, mc->size); +- int status, ret = CHE_OK; ++ int ret = CHE_OK; + char this[PATH_MAX]; + + strcpy(this, key); +@@ -997,9 +937,6 @@ int cache_delete(struct mapent_cache *mc, const char *key) + goto done; + } + pred->next = me->next; +- status = pthread_rwlock_destroy(&me->multi_rwlock); +- if (status) +- fatal(status); + ino_index_lock(mc); + list_del(&me->ino_index); + ino_index_unlock(mc); +@@ -1029,9 +966,6 @@ int cache_delete(struct mapent_cache *mc, const char *key) + goto done; + } + mc->hash[hashval] = me->next; +- status = pthread_rwlock_destroy(&me->multi_rwlock); +- if (status) +- fatal(status); + ino_index_lock(mc); + list_del(&me->ino_index); + ino_index_unlock(mc); diff --git a/SOURCES/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch b/SOURCES/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch new file mode 100644 index 0000000..dbbecb7 --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch @@ -0,0 +1,66 @@ +autofs-5.1.7 - remove unused parameter form do_mount_autofs_offset() + +From: Ian Kent + +The offset parameter of do_mount_autofs_offset() isn't used. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 10 ++++------ + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 45be4783..3eda995c 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). ++- remove unused parameter form do_mount_autofs_offset(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 12d22023..8e88182f 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2472,9 +2472,7 @@ out: + } + + static int do_mount_autofs_offset(struct autofs_point *ap, +- struct mapent *oe, const char *root, +- char *offset) +- ++ struct mapent *oe, const char *root) + { + int mounted = 0; + int ret; +@@ -2529,7 +2527,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me, + if (!oe || !oe->mapent) + goto cont; + +- mounted += do_mount_autofs_offset(ap, oe, root, offset); ++ mounted += do_mount_autofs_offset(ap, oe, root); + + /* + * If re-constructing a multi-mount it's necessary to walk +@@ -2666,7 +2664,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root, offset); ++ ret = do_mount_autofs_offset(ap, oe, root); + if (ret) + left++; + /* But we did origianlly create this */ +@@ -2847,7 +2845,7 @@ int clean_stale_multi_triggers(struct autofs_point *ap, + */ + ret = rmdir_path_offset(ap, oe); + if (ret == -1 && !stat(oe->key, &st)) { +- ret = do_mount_autofs_offset(ap, oe, root, offset); ++ ret = do_mount_autofs_offset(ap, oe, root); + if (ret) { + left++; + /* But we did origianlly create this */ diff --git a/SOURCES/autofs-5.1.7-remove-unused-variable-from-get_exports.patch b/SOURCES/autofs-5.1.7-remove-unused-variable-from-get_exports.patch new file mode 100644 index 0000000..7427dce --- /dev/null +++ b/SOURCES/autofs-5.1.7-remove-unused-variable-from-get_exports.patch @@ -0,0 +1,32 @@ +autofs-5.1.7 - remove unused variable from get_exports() + +From: Ian Kent + +Fix complier warning about unused variable entry in get_exports(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.1.7.orig/modules/lookup_hosts.c ++++ autofs-5.1.7/modules/lookup_hosts.c +@@ -87,7 +87,6 @@ int lookup_read_master(struct master *ma + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; +- char entry[PATH_MAX + 1]; + char *mapent; + struct exportinfo *exp, *this; + size_t hostlen = strlen(host); +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -49,6 +49,7 @@ + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. + - remove mounts_mutex. ++- remove unused variable from get_exports(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. diff --git a/SOURCES/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch b/SOURCES/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch new file mode 100644 index 0000000..29b9660 --- /dev/null +++ b/SOURCES/autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch @@ -0,0 +1,159 @@ +autofs-5.1.7 - rename path to m_offset in update_offset_entry() + +From: Ian Kent + +Rename local variable from path to m_offset in update_offset_entry() to +make the meaning of this variable clear. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 46 +++++++++++++++++++++++----------------------- + 2 files changed, 24 insertions(+), 23 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e822efec..0e9ca94f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -25,6 +25,7 @@ + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. ++- rename path to m_offset in update_offset_entry(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index a6630a76..34d4441e 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -796,36 +796,36 @@ static int + update_offset_entry(struct autofs_point *ap, + struct mapent_cache *mc, const char *name, + const char *m_root, int m_root_len, +- const char *path, const char *myoptions, ++ const char *m_offset, const char *myoptions, + const char *loc, time_t age) + { + char m_key[PATH_MAX + 1]; + char m_mapent[MAPENT_MAX_LEN + 1]; +- int p_len, m_key_len, m_options_len, m_mapent_len; ++ int o_len, m_key_len, m_options_len, m_mapent_len; + int ret; + + memset(m_mapent, 0, MAPENT_MAX_LEN + 1); + + /* Internal hosts map may have loc == NULL */ +- if (!*path) { ++ if (!*m_offset) { + error(ap->logopt, +- MODPREFIX "syntax error in offset %s -> %s", path, loc); ++ MODPREFIX "syntax error in offset %s -> %s", m_offset, loc); + return CHE_FAIL; + } + +- p_len = strlen(path); ++ o_len = strlen(m_offset); + /* Trailing '/' causes us pain */ +- if (p_len > 1) { +- while (p_len > 1 && path[p_len - 1] == '/') +- p_len--; ++ if (o_len > 1) { ++ while (o_len > 1 && m_offset[o_len - 1] == '/') ++ o_len--; + } +- m_key_len = m_root_len + p_len; ++ m_key_len = m_root_len + o_len; + if (m_key_len > PATH_MAX) { + error(ap->logopt, MODPREFIX "multi mount key too long"); + return CHE_FAIL; + } + strcpy(m_key, m_root); +- strncat(m_key, path, p_len); ++ strncat(m_key, m_offset, o_len); + m_key[m_key_len] = '\0'; + + m_options_len = 0; +@@ -860,15 +860,15 @@ update_offset_entry(struct autofs_point *ap, + + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX +- "syntax error or duplicate offset %s -> %s", path, loc); ++ "syntax error or duplicate offset %s -> %s", m_offset, loc); + ret = CHE_OK; + } else if (ret == CHE_FAIL) + debug(ap->logopt, MODPREFIX +- "failed to update multi-mount offset %s -> %s", path, m_mapent); ++ "failed to update multi-mount offset %s -> %s", m_offset, m_mapent); + else { + ret = CHE_OK; + debug(ap->logopt, MODPREFIX +- "updated multi-mount offset %s -> %s", path, m_mapent); ++ "updated multi-mount offset %s -> %s", m_offset, m_mapent); + } + + return ret; +@@ -1538,22 +1538,22 @@ dont_expand: + + /* It's a multi-mount; deal with it */ + do { +- char *path, *myoptions, *loc; ++ char *m_offset, *myoptions, *loc; + int status; + + if ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/')) { + l = 0; +- path = dequote("/", 1, ap->logopt); ++ m_offset = dequote("/", 1, ap->logopt); + debug(ap->logopt, +- MODPREFIX "dequote(\"/\") -> %s", path); ++ MODPREFIX "dequote(\"/\") -> %s", m_offset); + } else { + l = span_space(p, mapent_len - (p - pmapent)); +- path = sanitize_path(p, l, LKP_MULTI, ap->logopt); ++ m_offset = sanitize_path(p, l, LKP_MULTI, ap->logopt); + debug(ap->logopt, MODPREFIX +- "dequote(\"%.*s\") -> %s", l, p, path); ++ "dequote(\"%.*s\") -> %s", l, p, m_offset); + } + +- if (!path) { ++ if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); + cache_writelock(mc); + cache_delete_offset_list(mc, name); +@@ -1575,7 +1575,7 @@ dont_expand: + cache_writelock(mc); + cache_delete_offset_list(mc, name); + cache_unlock(mc); +- free(path); ++ free(m_offset); + free(options); + free(pmapent); + pthread_setcancelstate(cur_state, NULL); +@@ -1587,14 +1587,14 @@ dont_expand: + + status = update_offset_entry(ap, mc, + name, m_root, m_root_len, +- path, myoptions, loc, age); ++ m_offset, myoptions, loc, age); + + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); + cache_writelock(mc); + cache_delete_offset_list(mc, name); + cache_unlock(mc); +- free(path); ++ free(m_offset); + free(options); + free(pmapent); + free(myoptions); +@@ -1606,7 +1606,7 @@ dont_expand: + + if (loc) + free(loc); +- free(path); ++ free(m_offset); + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + diff --git a/SOURCES/autofs-5.1.7-rename-tree-implementation-functions.patch b/SOURCES/autofs-5.1.7-rename-tree-implementation-functions.patch new file mode 100644 index 0000000..57bbc5f --- /dev/null +++ b/SOURCES/autofs-5.1.7-rename-tree-implementation-functions.patch @@ -0,0 +1,197 @@ +autofs-5.1.7 - rename tree implementation functions + +From: Ian Kent + +Rename the tree struct and functions to make them consistent. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 80 +++++++++++++++++++++++++++++----------------------------- + 2 files changed, 41 insertions(+), 40 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 2a07bd45..1bf20699 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -27,6 +27,7 @@ + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). ++- rename tree implementation functions. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/mounts.c b/lib/mounts.c +index 289500da..f5b905a6 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1225,30 +1225,30 @@ done: + return has_mounted_mounts; + } + +-struct node { ++struct tree_node { + struct mnt_list *mnt; +- struct node *left; +- struct node *right; ++ struct tree_node *left; ++ struct tree_node *right; + }; + +-static struct node *new(struct mnt_list *mnt) ++static struct tree_node *tree_new(struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *n; + +- n = malloc(sizeof(struct node)); ++ n = malloc(sizeof(struct tree_node)); + if (!n) + return NULL; +- memset(n, 0, sizeof(struct node)); ++ memset(n, 0, sizeof(struct tree_node)); + n->mnt = mnt; + + return n; + } + +-static struct node *tree_root(struct mnt_list *mnt) ++static struct tree_node *tree_root(struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *n; + +- n = new(mnt); ++ n = tree_new(mnt); + if (!n) { + error(LOGOPT_ANY, "failed to allcate tree root"); + return NULL; +@@ -1257,37 +1257,37 @@ static struct node *tree_root(struct mnt_list *mnt) + return n; + } + +-static struct node *add_left(struct node *this, struct mnt_list *mnt) ++static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *new; + +- n = new(mnt); +- if (!n) { ++ new = tree_new(mnt); ++ if (!new) { + error(LOGOPT_ANY, "failed to allcate tree node"); + return NULL; + } +- this->left = n; ++ n->left = new; + + return n; + } + +-static struct node *add_right(struct node *this, struct mnt_list *mnt) ++static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt) + { +- struct node *n; ++ struct tree_node *new; + +- n = new(mnt); +- if (!n) { ++ new = tree_new(mnt); ++ if (!new) { + error(LOGOPT_ANY, "failed to allcate tree node"); + return NULL; + } +- this->right = n; ++ n->right = new; + + return n; + } + +-static struct node *add_node(struct node *root, struct mnt_list *mnt) ++static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt) + { +- struct node *p, *q; ++ struct tree_node *p, *q; + unsigned int mp_len; + + mp_len = strlen(mnt->mp); +@@ -1307,43 +1307,43 @@ static struct node *add_node(struct node *root, struct mnt_list *mnt) + error(LOGOPT_ANY, "duplicate entry in mounts list"); + else { + if (mp_len < strlen(p->mnt->mp)) +- return add_left(p, mnt); ++ return tree_add_left(p, mnt); + else +- return add_right(p, mnt); ++ return tree_add_right(p, mnt); + } + + return NULL; + } + +-static void tree_free(struct node *tree) ++static void tree_free(struct tree_node *root) + { +- if (tree->right) +- tree_free(tree->right); +- if (tree->left) +- tree_free(tree->left); +- free(tree); ++ if (root->right) ++ tree_free(root->right); ++ if (root->left) ++ tree_free(root->left); ++ free(root); + } + +-static void traverse(struct node *node, struct list_head *mnts) ++static void tree_traverse(struct tree_node *n, struct list_head *mnts) + { +- if (node->right) +- traverse(node->right, mnts); +- list_add_tail(&node->mnt->expire, mnts); +- if (node->left) +- traverse(node->left, mnts); ++ if (n->right) ++ tree_traverse(n->right, mnts); ++ list_add_tail(&n->mnt->expire, mnts); ++ if (n->left) ++ tree_traverse(n->left, mnts); + } + + void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + { + struct mnt_list *mnt; +- struct node *tree = NULL; ++ struct tree_node *tree = NULL; + + mnts_hash_mutex_lock(); + if (list_empty(&ap->mounts)) + goto done; + + list_for_each_entry(mnt, &ap->mounts, mount) { +- struct node *n; ++ struct tree_node *n; + + if (!(mnt->flags & MNTS_MOUNTED)) + continue; +@@ -1359,7 +1359,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + continue; + } + +- n = add_node(tree, mnt); ++ n = tree_add_node(tree, mnt); + if (!n) { + error(LOGOPT_ANY, "failed to add expire tree node"); + tree_free(tree); +@@ -1367,7 +1367,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap) + } + } + +- traverse(tree, mnts); ++ tree_traverse(tree, mnts); + tree_free(tree); + done: + mnts_hash_mutex_unlock(); diff --git a/SOURCES/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch b/SOURCES/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch new file mode 100644 index 0000000..5f5a518 --- /dev/null +++ b/SOURCES/autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch @@ -0,0 +1,104 @@ +autofs-5.1.7 - set offset parent in update_offset_entry() + +From: Ian Kent + +Avoid the list traversal in cache_set_parents() by setting the +offset parent when updating the offset. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 2 +- + lib/cache.c | 26 +++++++++++--------------- + modules/parse_sun.c | 5 ++++- + 4 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index ee746277..c4ebb52f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. + - simplify cache_get_parent(). ++- set offset parent in update_offset_entry(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/include/automount.h b/include/automount.h +index 2f09e8e7..730be19a 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -208,7 +208,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + int cache_lookup_negative(struct mapent *me, const char *key); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); +-int cache_set_parents(struct mapent *mm); ++int cache_set_offset_parent(struct mapent_cache *mc, const char *offset); + 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); +diff --git a/lib/cache.c b/lib/cache.c +index 53f290cd..ce9e9bd2 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -864,25 +864,21 @@ static struct mapent *get_offset_parent(struct mapent_cache *mc, + return NULL; + } + +-int cache_set_parents(struct mapent *mm) ++int cache_set_offset_parent(struct mapent_cache *mc, const char *offset) + { +- struct list_head *multi_head, *p; +- struct mapent *this; ++ struct mapent *this, *parent; + +- if (!mm->multi) ++ this = cache_lookup_distinct(mc, offset); ++ if (!this) ++ return 0; ++ if (!this->multi) + return 0; + +- multi_head = &mm->multi->multi_list; +- +- list_for_each(p, multi_head) { +- struct mapent *parent; +- this = list_entry(p, struct mapent, multi_list); +- parent = get_offset_parent(mm->mc, this->key); +- if (parent) +- this->parent = parent; +- else +- this->parent = mm->multi; +- } ++ parent = get_offset_parent(mc, offset); ++ if (parent) ++ this->parent = parent; ++ else ++ this->parent = this->multi; + + return 1; + } +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 819d6adc..f42af7b7 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -859,6 +859,10 @@ update_offset_entry(struct autofs_point *ap, const char *name, + } + + ret = cache_update_offset(mc, name, m_key, m_mapent, age); ++ ++ if (!cache_set_offset_parent(mc, m_key)) ++ error(ap->logopt, "failed to set offset parent"); ++ + if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX + "syntax error or duplicate offset %s -> %s", path, loc); +@@ -1613,7 +1617,6 @@ dont_expand: + */ + 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/SOURCES/autofs-5.1.7-simplify-get_parent.patch b/SOURCES/autofs-5.1.7-simplify-get_parent.patch new file mode 100644 index 0000000..85a1306 --- /dev/null +++ b/SOURCES/autofs-5.1.7-simplify-get_parent.patch @@ -0,0 +1,105 @@ +autofs-5.1.7 - simplify cache_get_parent() + +From: Ian Kent + +Eliminate the list traversal from get_parent() and rename it to +get_offset_parent() to better describe it's usage. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/cache.c | 46 ++++++++++++++++++++++++++++------------------ + 2 files changed, 29 insertions(+), 18 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e55fd66a..ee746277 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ + - Fix option for master read wait. + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. ++- simplify cache_get_parent(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/lib/cache.c b/lib/cache.c +index d3b6642b..53f290cd 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -827,47 +827,57 @@ void cache_update_negative(struct mapent_cache *mc, + } + + +-static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos) ++static struct mapent *get_offset_parent(struct mapent_cache *mc, ++ const char *key) + { +- struct list_head *next; +- struct mapent *this, *last; +- int eq; ++ struct mapent *me; ++ char *parent, *tail; ++ int key_len; + +- last = NULL; +- next = *pos ? (*pos)->next : head->next; ++ key_len = strlen(key); + +- list_for_each(next, head) { +- this = list_entry(next, struct mapent, multi_list); ++ /* Check if this is the root offset */ ++ if (key[key_len - 1] == '/') ++ return NULL; ++ ++ parent = strdup(key); ++ tail = &parent[key_len - 1]; + +- if (!strcmp(this->key, key)) ++ while (*tail) { ++ while (*tail != '/') ++ tail--; ++ ++ *tail = 0; ++ ++ tail--; ++ if (tail == parent) + break; + +- eq = strncmp(this->key, key, strlen(this->key)); +- if (eq == 0) { +- *pos = next; +- last = this; +- continue; ++ me = cache_lookup_distinct(mc, parent); ++ if (me) { ++ free(parent); ++ return me; + } + } ++ free(parent); + +- return last; ++ return NULL; + } + + int cache_set_parents(struct mapent *mm) + { +- struct list_head *multi_head, *p, *pos; ++ struct list_head *multi_head, *p; + struct mapent *this; + + if (!mm->multi) + return 0; + +- pos = NULL; + multi_head = &mm->multi->multi_list; + + list_for_each(p, multi_head) { + struct mapent *parent; + this = list_entry(p, struct mapent, multi_list); +- parent = get_parent(this->key, multi_head, &pos); ++ parent = get_offset_parent(mm->mc, this->key); + if (parent) + this->parent = parent; + else diff --git a/SOURCES/autofs-5.1.7-simplify-mount_subtree-mount-check.patch b/SOURCES/autofs-5.1.7-simplify-mount_subtree-mount-check.patch new file mode 100644 index 0000000..01b2071 --- /dev/null +++ b/SOURCES/autofs-5.1.7-simplify-mount_subtree-mount-check.patch @@ -0,0 +1,46 @@ +autofs-5.1.7 - simplify mount_subtree() mount check + +From: Ian Kent + +The check of the return from sun_mount() following the possible mount +of the root offset in mount_subtree() can be simpler. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 10 +--------- + 2 files changed, 2 insertions(+), 9 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b1ce7b69..f5c5641a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -13,6 +13,7 @@ + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). ++- simplify mount_subtree() mount check. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index f4d5125c..1142e8a3 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1203,15 +1203,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + free(ro_loc); + } + +- if (ro && rv == 0) { +- 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); +- return 1; +- } +- } else if (rv <= 0) { ++ if ((ro && rv == 0) || rv <= 0) { + ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); + if (ret == -1) { + error(ap->logopt, MODPREFIX diff --git a/SOURCES/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch b/SOURCES/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch new file mode 100644 index 0000000..4335ed1 --- /dev/null +++ b/SOURCES/autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch @@ -0,0 +1,414 @@ +autofs-5.1.7 - switch to use tree implementation for offsets + +From: Ian Kent + +Change to use the tree mapent implementation for the handling +of offset mounts. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 25 ++---------- + daemon/lookup.c | 2 - + include/automount.h | 8 ++-- + lib/cache.c | 67 --------------------------------- + lib/mounts.c | 4 +- + modules/lookup_program.c | 2 - + modules/parse_sun.c | 94 ++++++++++++---------------------------------- + 8 files changed, 39 insertions(+), 164 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 892f7581..5ac09f77 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -40,6 +40,7 @@ + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. ++- switch to use tree implementation for offsets. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/daemon/automount.c b/daemon/automount.c +index f4608fc9..7833dfae 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -551,29 +551,15 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + left = 0; + + if (me && IS_MM(me)) { +- char root[PATH_MAX + 1]; + char key[PATH_MAX + 1]; + struct mapent *tmp; +- int status; +- char *base; +- +- if (!strchr(MM_ROOT(me)->key, '/')) +- /* Indirect multi-mount root */ +- /* sprintf okay - if it's mounted, it's +- * PATH_MAX or less bytes */ +- sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key); +- else +- strcpy(root, MM_ROOT(me)->key); +- +- if (IS_MM_ROOT(me)) +- base = NULL; +- else +- base = me->key + strlen(root); ++ int ret; + +- left = umount_multi_triggers(ap, me, root, base); +- if (left) { ++ ret = tree_mapent_umount_offsets(me, 1); ++ if (!ret) { + warn(ap->logopt, + "some offset mounts still present under %s", path); ++ left++; + } + + strcpy(key, me->key); +@@ -589,8 +575,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + } + + if (!left && IS_MM_ROOT(me)) { +- status = cache_delete_offset_list(mc, me->key); +- if (status != CHE_OK) { ++ if (!tree_mapent_delete_offsets(mc, me->key)) { + warn(ap->logopt, "couldn't delete offset list"); + left++; + } +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 5116b927..32dbc24d 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap, + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2); ++ m_key = malloc(ap->len + MM_ROOT(me)->len + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); +diff --git a/include/automount.h b/include/automount.h +index f6023e27..a71b8674 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -187,10 +187,10 @@ struct mapent { + ino_t ino; + }; + +-#define IS_MM(me) (me->multi) +-#define IS_MM_ROOT(me) (me->multi == me) +-#define MM_ROOT(me) (me->multi) +-#define MM_PARENT(me) (me->parent) ++#define IS_MM(me) (me->mm_root) ++#define IS_MM_ROOT(me) (me->mm_root == &me->node) ++#define MM_ROOT(me) (MAPENT(me->mm_root)) ++#define MM_PARENT(me) (MAPENT(me->mm_parent)) + + void cache_lock_cleanup(void *arg); + void cache_readlock(struct mapent_cache *mc); +diff --git a/lib/cache.c b/lib/cache.c +index 7c409a56..93b02daf 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -682,14 +682,6 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k + return CHE_FAIL; + } + +- me = cache_lookup_distinct(mc, key); +- if (me) { +- cache_add_ordered_offset(me, &owner->multi_list); +- MM_ROOT(me) = owner; +- goto done; +- } +- ret = CHE_FAIL; +-done: + return ret; + } + +@@ -958,65 +950,6 @@ done: + return ret; + } + +-/* cache must be write locked by caller */ +-int cache_delete_offset_list(struct mapent_cache *mc, const char *key) +-{ +- unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt(); +- struct mapent *me; +- struct mapent *this; +- struct list_head *head, *next; +- int remain = 0; +- int status; +- +- me = cache_lookup_distinct(mc, key); +- if (!me) +- return CHE_FAIL; +- +- /* Not offset list owner */ +- if (!IS_MM_ROOT(me)) +- return CHE_FAIL; +- +- head = &me->multi_list; +- next = head->next; +- while (next != head) { +- this = list_entry(next, struct mapent, multi_list); +- next = next->next; +- if (this->ioctlfd != -1) { +- error(logopt, +- "active offset mount key %s", this->key); +- return CHE_FAIL; +- } +- } +- +- head = &me->multi_list; +- next = head->next; +- while (next != head) { +- this = list_entry(next, struct mapent, multi_list); +- next = next->next; +- list_del_init(&this->multi_list); +- MM_ROOT(this) = NULL; +- debug(logopt, "deleting offset key %s", this->key); +- status = cache_delete(mc, this->key); +- if (status == CHE_FAIL) { +- warn(logopt, +- "failed to delete offset %s", this->key); +- MM_ROOT(this) = me; +- /* TODO: add list back in */ +- remain++; +- } +- } +- +- if (!remain) { +- list_del_init(&me->multi_list); +- MM_ROOT(me) = NULL; +- } +- +- if (remain) +- return CHE_FAIL; +- +- return CHE_OK; +-} +- + void cache_release(struct map_source *map) + { + struct mapent_cache *mc; +diff --git a/lib/mounts.c b/lib/mounts.c +index f7c29475..6ca7eff1 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -2893,7 +2893,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap) + + /* Only need to set offset mounts catatonic */ + if (IS_MM(me) && IS_MM_ROOT(me)) +- set_multi_mount_tree_catatonic(ap, me); ++ set_offset_tree_catatonic(ap, me); + next: + me = cache_enumerate(mc, me); + } +@@ -2913,7 +2913,7 @@ void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) + { + /* Set offset mounts catatonic for this mapent */ + if (IS_MM(me) && IS_MM_ROOT(me)) +- set_multi_mount_tree_catatonic(ap, me); ++ set_offset_tree_catatonic(ap, me); + set_mount_catatonic(ap, me, me->ioctlfd); + } + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 70f27545..6cab52c8 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -658,7 +658,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + me = cache_lookup_distinct(mc, name); + if (me) { + if (IS_MM(me)) +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_delete(mc, name); + } + cache_unlock(mc); +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index b1f64ca0..d6ef48b8 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -854,8 +854,8 @@ update_offset_entry(struct autofs_point *ap, + cache_writelock(mc); + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + +- if (!cache_set_offset_parent(mc, m_key)) +- error(ap->logopt, "failed to set offset parent"); ++ if (!tree_mapent_add_node(mc, name, m_key)) ++ error(ap->logopt, "failed to add offset %s to tree", m_key); + cache_unlock(mc); + + if (ret == CHE_DUPLICATE) { +@@ -1134,10 +1134,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + const char *name, char *loc, char *options, void *ctxt) + { + struct mapent *me; +- struct mapent *ro; +- char *mm_root, *mm_base, *mm_key; +- unsigned int mm_root_len; +- int start, ret = 0, rv; ++ int ret = 0, rv; + + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +@@ -1148,34 +1145,18 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + + rv = 0; + +- mm_key = MM_ROOT(me)->key; +- +- if (*mm_key == '/') { +- mm_root = mm_key; +- start = strlen(mm_key); +- } else { +- start = ap->len + strlen(mm_key) + 1; +- mm_root = alloca(start + 3); +- strcpy(mm_root, ap->path); +- strcat(mm_root, "/"); +- strcat(mm_root, mm_key); +- } +- mm_root_len = strlen(mm_root); +- + if (IS_MM_ROOT(me)) { + char key[PATH_MAX + 1]; ++ struct mapent *ro; ++ size_t len; + +- if (mm_root_len + 1 > PATH_MAX) { ++ len = mount_fullpath(key, PATH_MAX, ap->path, me->key); ++ if (!len) { + warn(ap->logopt, "path loo long"); + return 1; + } +- +- /* name = NULL */ +- /* destination = mm_root */ +- mm_base = "/"; +- +- strcpy(key, mm_root); +- strcat(key, mm_base); ++ key[len] = '/'; ++ key[len + 1] = 0; + + /* Mount root offset if it exists */ + ro = cache_lookup_distinct(me->mc, key); +@@ -1194,7 +1175,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + warn(ap->logopt, + MODPREFIX "failed to parse root offset"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + return 1; + } +@@ -1209,10 +1190,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + free(ro_loc); + } + +- if ((ro && rv == 0) || rv <= 0) { +- ret = mount_multi_triggers(ap, me, mm_root, start, mm_base); +- if (ret == -1) { +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ if (rv <= 0) { ++ ret = tree_mapent_mount_offsets(me, 1); ++ if (!ret) { ++ tree_mapent_cleanup_offsets(me); + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +@@ -1223,39 +1204,14 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + int loclen = strlen(loc); + int namelen = strlen(name); + +- /* name = mm_root + mm_base */ +- /* destination = mm_root + mm_base = name */ +- mm_base = &me->key[start]; +- ++ /* Mounts at nesting points must succeed for subtree ++ * offsets to be mounted. ++ */ + rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt); + if (rv == 0) { +- ret = mount_multi_triggers(ap, me->multi, name, start, mm_base); +- if (ret == -1) { +- cleanup_multi_triggers(ap, me, name, start, mm_base); +- cache_unlock(mc); +- error(ap->logopt, MODPREFIX +- "failed to mount offset triggers"); +- return 1; +- } +- } else if (rv < 0) { +- char mm_root_base[PATH_MAX + 1]; +- unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1; +- +- if (mm_root_base_len > PATH_MAX) { +- cache_unlock(mc); +- warn(ap->logopt, MODPREFIX "path too long"); +- cache_writelock(mc); +- cache_delete_offset_list(mc, name); +- cache_unlock(mc); +- return 1; +- } +- +- strcpy(mm_root_base, mm_root); +- strcat(mm_root_base, mm_base); +- +- ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base); +- if (ret == -1) { +- cleanup_multi_triggers(ap, me, mm_root, start, mm_base); ++ ret = tree_mapent_mount_offsets(me, 1); ++ if (!ret) { ++ tree_mapent_cleanup_offsets(me); + cache_unlock(mc); + error(ap->logopt, MODPREFIX + "failed to mount offset triggers"); +@@ -1265,7 +1221,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc, + } + cache_unlock(mc); + +- /* Mount for base of tree failed */ ++ /* strict mount failed */ + if (rv > 0) + return rv; + +@@ -1506,7 +1462,7 @@ dont_expand: + + /* So we know we're the multi-mount root */ + if (!IS_MM(me)) +- me->multi = me; ++ MAPENT_SET_ROOT(me, tree_mapent_root(me)) + else { + /* + * The amd host mount type assumes the lookup name +@@ -1556,7 +1512,7 @@ dont_expand: + if (!m_offset) { + warn(ap->logopt, MODPREFIX "null path or out of memory"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(options); + free(pmapent); +@@ -1573,7 +1529,7 @@ dont_expand: + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(m_offset); + free(options); +@@ -1592,7 +1548,7 @@ dont_expand: + if (status != CHE_OK) { + warn(ap->logopt, MODPREFIX "error adding multi-mount"); + cache_writelock(mc); +- cache_delete_offset_list(mc, name); ++ tree_mapent_delete_offsets(mc, name); + cache_unlock(mc); + free(m_offset); + free(options); diff --git a/SOURCES/autofs-5.1.7-use-default-stack-size-for-threads.patch b/SOURCES/autofs-5.1.7-use-default-stack-size-for-threads.patch new file mode 100644 index 0000000..c4d15b8 --- /dev/null +++ b/SOURCES/autofs-5.1.7-use-default-stack-size-for-threads.patch @@ -0,0 +1,120 @@ +autofs-5.1.7 - use default stack size for threads + +From: Ian Kent + +autofs uses PTHREAD_STACK_MIN to set the stack size for threads it +creates. + +In two cases it is used to reduce the stack size for long running +service threads while it's used to allocate a larger stack for worker +threads that can have larger memory requirements. + +In recent glibc releases PTHREAD_STACK_MIN is no longer a constant +which can lead to unexpectedly different stack sizes on different +architectures and the autofs assumption it's a constant causes a +compile failure. + +The need to alter the stack size was due to observed stack overflow +which was thought to be due the thread stack being too small for autofs +and glibc alloca(3) usage. + +Quite a bit of that alloca(3) usage has been eliminated from autofs now, +particularly those that might be allocating largish amounts of storage, +and there has been a lot of change in glibc too so using the thread +default stack should be ok. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 29 ----------------------------- + daemon/state.c | 6 +----- + lib/alarm.c | 6 +----- + 4 files changed, 3 insertions(+), 39 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -79,6 +79,7 @@ + - fix nonstrict offset mount fail handling. + - fix concat_options() error handling. + - eliminate some more alloca usage. ++- use default stack size for threads. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/daemon/automount.c ++++ autofs-5.1.7/daemon/automount.c +@@ -84,7 +84,6 @@ static size_t kpkt_len; + /* Attributes for creating detached and joinable threads */ + pthread_attr_t th_attr; + pthread_attr_t th_attr_detached; +-size_t detached_thread_stack_size = PTHREAD_STACK_MIN * 144; + + struct master_readmap_cond mrc = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0}; +@@ -2614,34 +2613,6 @@ int main(int argc, char *argv[]) + if (start_pipefd[1] != -1) { + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); +- } +- release_flag_file(); +- macro_free_global_table(); +- exit(1); +- } +- +-#ifdef _POSIX_THREAD_ATTR_STACKSIZE +- if (pthread_attr_setstacksize( +- &th_attr_detached, detached_thread_stack_size)) { +- logerr("%s: failed to set stack size thread attribute!", +- program); +- if (start_pipefd[1] != -1) { +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); +- } +- release_flag_file(); +- macro_free_global_table(); +- exit(1); +- } +-#endif +- +- if (pthread_attr_getstacksize( +- &th_attr_detached, &detached_thread_stack_size)) { +- logerr("%s: failed to get detached thread stack size!", +- program); +- if (start_pipefd[1] != -1) { +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); + } + release_flag_file(); + macro_free_global_table(); +--- autofs-5.1.7.orig/daemon/state.c ++++ autofs-5.1.7/daemon/state.c +@@ -1177,12 +1177,8 @@ int st_start_handler(void) + status = pthread_attr_init(pattrs); + if (status) + pattrs = NULL; +- else { ++ else + pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED); +-#ifdef _POSIX_THREAD_ATTR_STACKSIZE +- pthread_attr_setstacksize(pattrs, PTHREAD_STACK_MIN*4); +-#endif +- } + + status = pthread_create(&thid, pattrs, st_queue_handler, NULL); + +--- autofs-5.1.7.orig/lib/alarm.c ++++ autofs-5.1.7/lib/alarm.c +@@ -270,12 +270,8 @@ int alarm_start_handler(void) + status = pthread_attr_init(pattrs); + if (status) + pattrs = NULL; +- else { ++ else + pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED); +-#ifdef _POSIX_THREAD_ATTR_STACKSIZE +- pthread_attr_setstacksize(pattrs, PTHREAD_STACK_MIN*4); +-#endif +- } + + status = pthread_condattr_init(&condattrs); + if (status) diff --git a/SOURCES/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch b/SOURCES/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch new file mode 100644 index 0000000..33cba78 --- /dev/null +++ b/SOURCES/autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch @@ -0,0 +1,111 @@ +autofs-5.1.7 - use mapent tree root for tree_mapent_add_node() + +From: Ian Kent + +Since we need to create the offset tree after adding the offset entries +to the mapent cache lookup the root mapent once and use it when calling +tree_mapent_add_node() instread of doing a cache lookup on every node +addition. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/mounts.h | 2 +- + lib/mounts.c | 24 +++++------------------- + modules/parse_sun.c | 11 ++++++++++- + 4 files changed, 17 insertions(+), 21 deletions(-) + +--- autofs-5.1.7.orig/CHANGELOG ++++ autofs-5.1.7/CHANGELOG +@@ -70,6 +70,7 @@ + - fix amd section mounts map reload. + - fix amd hosts mount expire. + - fix offset entries order. ++- use mapent tree root for tree_mapent_add_node(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +--- autofs-5.1.7.orig/include/mounts.h ++++ autofs-5.1.7/include/mounts.h +@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he + void mnts_put_expire_list(struct list_head *mnts); + void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags); + struct tree_node *tree_mapent_root(struct mapent *me); +-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key); ++int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key); + int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key); + void tree_mapent_cleanup_offsets(struct mapent *oe); + int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict); +--- autofs-5.1.7.orig/lib/mounts.c ++++ autofs-5.1.7/lib/mounts.c +@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree + } + + int tree_mapent_add_node(struct mapent_cache *mc, +- const char *root, const char *key) ++ struct tree_node *root, const char *key) + { + unsigned int logopt = mc->ap->logopt; +- struct tree_node *tree, *n; +- struct mapent *base; ++ struct tree_node *n; + struct mapent *parent; + struct mapent *me; + +- base = cache_lookup_distinct(mc, root); +- if (!base) { +- error(logopt, +- "failed to find multi-mount root for key %s", key); +- return 0; +- } +- +- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { +- error(logopt, "key %s is not multi-mount root", root); +- return 0; +- } +- tree = MAPENT_ROOT(base); +- + me = cache_lookup_distinct(mc, key); + if (!me) { + error(logopt, +@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_c + return 0; + } + +- n = tree_add_node(tree, me); ++ n = tree_add_node(root, me); + if (!n) + return 0; + +- MAPENT_SET_ROOT(me, tree) ++ MAPENT_SET_ROOT(me, root) + + /* Set the subtree parent */ + parent = cache_get_offset_parent(mc, key); + if (!parent) +- MAPENT_SET_PARENT(me, tree) ++ MAPENT_SET_PARENT(me, root) + else + MAPENT_SET_PARENT(me, MAPENT_NODE(parent)) + +--- autofs-5.1.7.orig/modules/parse_sun.c ++++ autofs-5.1.7/modules/parse_sun.c +@@ -1536,8 +1536,17 @@ dont_expand: + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); + + cache_writelock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ free(options); ++ free(pmapent); ++ cleanup_offset_entries(ap, mc, &offsets); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } + list_for_each_entry_safe(oe, tmp, &offsets, work) { +- if (!tree_mapent_add_node(mc, name, oe->key)) ++ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key)) + error(ap->logopt, "failed to add offset %s to tree", oe->key); + list_del_init(&oe->work); + } diff --git a/SOURCES/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch b/SOURCES/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch new file mode 100644 index 0000000..d72ba0b --- /dev/null +++ b/SOURCES/autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch @@ -0,0 +1,74 @@ +autofs-5.1.7 - use mount_fullpath() in one spot in parse_mount() + +From: Ian Kent + +mount_fullpath() is meant to be used for this type of path construction +so use it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 34 ++++++++-------------------------- + 2 files changed, 9 insertions(+), 26 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 444ade5b..8494f0dc 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -43,6 +43,7 @@ + - switch to use tree implementation for offsets. + - remove obsolete functions. + - remove redundant local var from sun_mount(). ++- use mount_fullpath() in one spot in parse_mount(). + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 437869b5..d3fc6c7f 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1354,36 +1354,18 @@ dont_expand: + debug(ap->logopt, MODPREFIX "gathered options: %s", options); + + if (check_is_multi(p)) { +- char *m_root = NULL; ++ char m_root[PATH_MAX + 1]; + int m_root_len; + time_t age; + int l; + +- /* If name starts with "/" it's a direct mount */ +- if (*name == '/') { +- m_root_len = name_len; +- m_root = alloca(m_root_len + 1); +- if (!m_root) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- free(options); +- free(pmapent); +- logerr(MODPREFIX "alloca: %s", estr); +- return 1; +- } +- strcpy(m_root, name); +- } else { +- m_root_len = ap->len + name_len + 1; +- m_root = alloca(m_root_len + 1); +- if (!m_root) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- free(options); +- free(pmapent); +- logerr(MODPREFIX "alloca: %s", estr); +- return 1; +- } +- strcpy(m_root, ap->path); +- strcat(m_root, "/"); +- strcat(m_root, name); ++ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name); ++ if (!m_root_len) { ++ error(ap->logopt, ++ MODPREFIX "multi-mount root path too long"); ++ free(options); ++ free(pmapent); ++ return 1; + } + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); diff --git a/SOURCES/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch b/SOURCES/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch new file mode 100644 index 0000000..64ab994 --- /dev/null +++ b/SOURCES/autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch @@ -0,0 +1,76 @@ +autofs-5.1.7 - use snprintf() when constructing hosts mapent + +From: Ian Kent + +Using multiple strcpy() and strcat() functions when constructing the +hosts map offset for each export is much slower than using a single +sprintf() for each. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 26 +++++++++++++------------- + 2 files changed, 14 insertions(+), 13 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 1bd6ac7f..d613e5ca 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. ++- use sprintf() when constructing hosts mapent. + + 25/01/2021 autofs-5.1.7 + - make bind mounts propagation slave by default. +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index e3ee0ab8..c1ebb7f6 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -87,10 +87,12 @@ int lookup_read_master(struct master *master, time_t age, void *context) + static char *get_exports(struct autofs_point *ap, const char *host) + { + char buf[MAX_ERR_BUF]; ++ char entry[PATH_MAX + 1]; + char *mapent; + struct exportinfo *exp, *this; + size_t hostlen = strlen(host); + size_t mapent_len; ++ int len, pos; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + +@@ -114,21 +116,19 @@ static char *get_exports(struct autofs_point *ap, const char *host) + } + *mapent = 0; + ++ pos = 0; + this = exp; +- while (this) { +- if (!*mapent) +- strcpy(mapent, "\""); +- else +- strcat(mapent, " \""); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); +- +- strcat(mapent, " \""); +- strcat(mapent, host); +- strcat(mapent, ":"); +- strcat(mapent, this->dir); +- strcat(mapent, "\""); ++ if (this) { ++ len = sprintf(mapent, "\"%s\" \"%s:%s\"", ++ this->dir, host, this->dir); ++ pos += len; ++ this = this->next; ++ } + ++ while (this) { ++ len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"", ++ this->dir, host, this->dir); ++ pos += len; + this = this->next; + } + rpc_exports_free(exp); diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec new file mode 100644 index 0000000..3757d20 --- /dev/null +++ b/SPECS/autofs.spec @@ -0,0 +1,2518 @@ +# +# $Id: autofs.spec,v 1.11 2003/12/04 15:41:32 raven Exp $ +# +# Use --without systemd in your rpmbuild command or force values to 0 to +# disable them. +%define with_systemd %{?_without_systemd: 0} %{?!_without_systemd: 1} + +# Use --without fedfs in your rpmbuild command or force values to 0 to +# disable them. +%define with_fedfs %{?_without_fedfs: 0} %{?!_without_fedfs: 1} + +Summary: A tool for automatically mounting and unmounting filesystems +Name: autofs +Version: 5.1.7 +Release: 24%{?dist} +Epoch: 1 +License: GPLv2+ +Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz + +# patches 1 and 2 have been applied to the source tar to remove +# lib/mount.x as it has an incompatible license. +Patch1: autofs-5.1.7-add-xdr_exports.patch +Patch2: autofs-5.1.7-remove-mount_x-and-rpcgen-dependencies.patch +Patch3: autofs-5.1.7-dont-use-realloc-in-host-exports-list-processing.patch +Patch4: autofs-5.1.7-use-sprintf-when-constructing-hosts-mapent.patch +Patch5: autofs-5.1.7-fix-mnts_remove_amdmount-uses-wrong-list.patch +Patch6: autofs-5.1.7-Fix-option-for-master_read_wait.patch +Patch7: autofs-5.1.7-eliminate-cache_lookup_offset-usage.patch +Patch8: autofs-5.1.7-fix-is-mounted-check-on-non-existent-path.patch +Patch9: autofs-5.1.7-simplify-get_parent.patch +Patch10: autofs-5.1.7-set-offset-parent-in-update_offset_entry.patch +Patch11: autofs-5.1.7-remove-redundant-variables-from-mount_autofs_offset.patch +Patch12: autofs-5.1.7-remove-unused-parameter-form-do_mount_autofs_offset.patch +Patch13: autofs-5.1.7-refactor-umount_multi_triggers.patch +Patch14: autofs-5.1.7-eliminate-clean_stale_multi_triggers.patch +Patch15: autofs-5.1.7-simplify-mount_subtree-mount-check.patch +Patch16: autofs-5.1.7-fix-mnts_get_expire_list-expire-list-construction.patch +Patch17: autofs-5.1.7-fix-inconsistent-locking-in-umount_subtree_mounts.patch +Patch18: autofs-5.1.7-fix-return-from-umount_subtree_mounts-on-offset-list-delete.patch +Patch19: autofs-5.1.7-pass-mapent_cache-to-update_offset_entry.patch +Patch20: autofs-5.1.7-fix-inconsistent-locking-in-parse_mount.patch +Patch21: autofs-5.1.7-remove-unused-mount-offset-list-lock-functions.patch +Patch22: autofs-5.1.7-eliminate-count_mounts-from-expire_proc_indirect.patch +Patch23: autofs-5.1.7-eliminate-some-strlen-calls-in-offset-handling.patch +Patch24: autofs-5.1.7-dont-add-offset-mounts-to-mounted-mounts-table.patch +Patch25: autofs-5.1.7-reduce-umount-EBUSY-check-delay.patch +Patch26: autofs-5.1.7-cleanup-cache_delete-a-little.patch +Patch27: autofs-5.1.7-rename-path-to-m_offset-in-update_offset_entry.patch +Patch28: autofs-5.1.7-dont-pass-root-to-do_mount_autofs_offset.patch +Patch29: autofs-5.1.7-rename-tree-implementation-functions.patch +Patch30: autofs-5.1.7-add-some-multi-mount-macros.patch +Patch31: autofs-5.1.7-remove-unused-functions-cache_dump_multi-and-cache_dump_cache.patch +Patch32: autofs-5.1.7-add-a-len-field-to-struct-autofs_point.patch +Patch33: autofs-5.1.7-make-tree-implementation-data-independent.patch +Patch34: autofs-5.1.7-add-mapent-tree-implementation.patch +Patch35: autofs-5.1.7-add-tree_mapent_add_node.patch +Patch36: autofs-5.1.7-add-tree_mapent_delete_offsets.patch +Patch37: autofs-5.1.7-add-tree_mapent_traverse_subtree.patch +Patch38: autofs-5.1.7-fix-mount_fullpath.patch +Patch39: autofs-5.1.7-add-tree_mapent_cleanup_offsets.patch +Patch40: autofs-5.1.7-add-set_offset_tree_catatonic.patch +Patch41: autofs-5.1.7-add-mount-and-umount-offsets-functions.patch +Patch42: autofs-5.1.7-switch-to-use-tree-implementation-for-offsets.patch +Patch43: autofs-5.1.7-remove-obsolete-functions.patch +Patch44: autofs-5.1.7-remove-redundant-local-var-from-sun_mount.patch +Patch45: autofs-5.1.7-use-mount_fullpath-in-one-spot-in-parse_mount.patch +Patch46: autofs-5.1.7-pass-root-length-to-mount_fullpath.patch +Patch47: autofs-5.1.7-remove-unused-function-master_submount_list_empty.patch +Patch48: autofs-5.1.7-move-amd-mounts-removal-into-lib_mounts_c.patch +Patch49: autofs-5.1.7-check-for-offset-with-no-mount-location.patch +Patch50: autofs-5.1.7-remove-mounts_mutex.patch +Patch51: autofs-5.1.7-remove-unused-variable-from-get_exports.patch +Patch52: autofs-5.1.7-add-missing-free-in-handle_mounts.patch +Patch53: autofs-5.1.7-remove-redundant-if-check.patch +Patch54: autofs-5.1.7-fix-possible-memory-leak-in-master_parse.patch +Patch55: autofs-5.1.7-fix-possible-memory-leak-in-mnts_add_amdmount.patch +Patch56: autofs-5.1.7-fix-double-unlock-in-parse_mount.patch +Patch57: autofs-5.1.7-add-length-check-in-umount_subtree_mounts.patch +Patch58: autofs-5.1.7-fix-flag-check-in-umount_multi.patch +Patch59: autofs-5.1.7-dont-try-umount-after-stat-ENOENT-fail.patch +Patch60: autofs-5.1.7-remove-redundant-assignment-in-master_add_amd_mount_section_mounts.patch +Patch61: autofs-5.1.7-fix-dead-code-in-mnts_add_mount.patch +Patch62: autofs-5.1.7-fix-arg-not-used-in-print.patch +Patch63: autofs-5.1.7-fix-missing-lock-release-in-mount_subtree.patch +Patch64: autofs-5.1.7-fix-double-free-in-parse_mapent.patch +Patch65: autofs-5.1.7-refactor-lookup_prune_one_cache-a-bit.patch +Patch66: autofs-5.1.7-cater-for-empty-mounts-list-in-mnts_get_expire_list.patch +Patch67: autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch +Patch68: autofs-5.1.7-fix-dangling-symlink-creation-if-nis-support-is-not-available.patch +Patch69: autofs-5.1.7-fix-amd-section-mounts-map-reload.patch +Patch70: autofs-5.1.7-fix-amd-hosts-mount-expire.patch + +Patch71: autofs-5.1.7-fix-offset-entries-order.patch +Patch72: autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch +Patch73: autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch +Patch74: autofs-5.1.7-fix-hosts-map-offset-order.patch +Patch75: autofs-5.1.7-fix-direct-mount-deadlock.patch +Patch76: autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch +Patch77: autofs-5.1.7-add-missing-description-of-null-map-option.patch +Patch78: autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch +Patch79: autofs-5.1.7-fix-concat_options-error-handling.patch +Patch80: autofs-5.1.7-eliminate-some-more-alloca-usage.patch +Patch81: autofs-5.1.7-use-default-stack-size-for-threads.patch + +%if %{with_systemd} +BuildRequires: systemd-units +BuildRequires: systemd-devel +%endif +BuildRequires: gcc +BuildRequires: autoconf, openldap-devel, bison, flex, libxml2-devel +BuildRequires: cyrus-sasl-devel, openssl-devel module-init-tools util-linux +BuildRequires: e2fsprogs libtirpc-devel libsss_autofs +BuildRequires: rpcgen pkgconfig krb5-devel +BuildRequires: make +Conflicts: cyrus-sasl-lib < 2.1.23-9 +Requires: bash coreutils sed gawk grep module-init-tools /bin/ps +%if %{with_systemd} +Requires(post): systemd-sysv +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +%else +Requires(post): /sbin/chkconfig +Requires(preun): /sbin/service +Requires(postun): /sbin/service +Requires(postun): /sbin/chkconfig +%endif +Summary(de): autofs daemon +Summary(fr): démon autofs +Summary(tr): autofs sunucu süreci +Summary(sv): autofs-daemon + +%description +autofs is a daemon which automatically mounts filesystems when you use +them, and unmounts them later when you are not using them. This can +include network filesystems, CD-ROMs, floppies, and so forth. + +%description -l de +autofs ist ein Dämon, der Dateisysteme automatisch montiert, wenn sie +benutzt werden, und sie später bei Nichtbenutzung wieder demontiert. +Dies kann Netz-Dateisysteme, CD-ROMs, Disketten und ähnliches einschließen. + +%description -l fr +autofs est un démon qui monte automatiquement les systèmes de fichiers +lorsqu'on les utilise et les démonte lorsqu'on ne les utilise plus. Cela +inclus les systèmes de fichiers réseau, les CD-ROMs, les disquettes, etc. + +%description -l tr +autofs, kullanýlan dosya sistemlerini gerek olunca kendiliðinden baðlar +ve kullanýmlarý sona erince yine kendiliðinden çözer. Bu iþlem, að dosya +sistemleri, CD-ROM'lar ve disketler üzerinde yapýlabilir. + +%description -l sv +autofs är en daemon som mountar filsystem när de använda, och senare +unmountar dem när de har varit oanvända en bestämd tid. Detta kan +inkludera nätfilsystem, CD-ROM, floppydiskar, och så vidare. + +%prep +%setup -q -n %{name}-%{version} +echo %{version}-%{release} > .version +%if %{with_systemd} + %define unitdir %{?_unitdir:/usr/lib/systemd/system} + %define systemd_configure_arg --with-systemd +%endif +%if %{with_fedfs} + %define fedfs_configure_arg --enable-fedfs +%endif +# patches 1 and 2 have been applied to the source tar to remove +# lib/mount.x as it has an incompatible license. +#%patch1 -p1 +#%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 +%patch34 -p1 +%patch35 -p1 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 +%patch52 -p1 +%patch53 -p1 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 + +%build +LDFLAGS=-Wl,-z,now +%configure \ + --disable-mount-locking \ + --enable-ignore-busy \ + --enable-force-shutdown \ + --without-hesiod \ + --with-libtirpc \ + %{?systemd_configure_arg:} \ + %{?fedfs_configure_arg:} + +make initdir=%{_initrddir} DONTSTRIP=1 + +%install +%if %{with_systemd} +install -d -m 755 $RPM_BUILD_ROOT%{unitdir} +%else +mkdir -p -m755 $RPM_BUILD_ROOT%{_initrddir} +%endif +mkdir -p -m755 $RPM_BUILD_ROOT%{_sbindir} +mkdir -p -m755 $RPM_BUILD_ROOT%{_libdir}/autofs +mkdir -p -m755 $RPM_BUILD_ROOT%{_mandir}/{man5,man8} +mkdir -p -m755 $RPM_BUILD_ROOT/etc/sysconfig +mkdir -p -m755 $RPM_BUILD_ROOT/etc/auto.master.d + +make install mandir=%{_mandir} initdir=%{_initrddir} systemddir=%{unitdir} INSTALLROOT=$RPM_BUILD_ROOT +echo make -C redhat +make -C redhat +install -m 755 -d $RPM_BUILD_ROOT/misc +%if %{with_systemd} +# Configure can get this wrong when the unit files appear under /lib and /usr/lib +find $RPM_BUILD_ROOT -type f -name autofs.service -exec rm -f {} \; +install -m 644 redhat/autofs.service $RPM_BUILD_ROOT%{unitdir}/autofs.service +%define init_file_name %{unitdir}/autofs.service +%else +install -m 755 redhat/autofs.init $RPM_BUILD_ROOT%{_initrddir}/autofs +%define init_file_name /etc/rc.d/init.d/autofs +%endif +install -m 644 redhat/autofs.conf $RPM_BUILD_ROOT/etc/autofs.conf +install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + +install -m 644 samples/auto.master $RPM_BUILD_ROOT/etc/auto.master +install -m 644 samples/auto.misc $RPM_BUILD_ROOT/etc/auto.misc +install -m 755 samples/auto.net $RPM_BUILD_ROOT/etc/auto.net +install -m 755 samples/auto.smb $RPM_BUILD_ROOT/etc/auto.smb +install -m 600 samples/autofs_ldap_auth.conf $RPM_BUILD_ROOT/etc/autofs_ldap_auth.conf + +%post +%if %{with_systemd} +%systemd_post %{name}.service +%else +if [ $1 -eq 1 ]; then + %{_sbindir}/sbin/chkconfig --add autofs +fi +%endif + +%preun +%if %{with_systemd} +%systemd_preun %{name}.service +%else +if [ $1 -eq 0 ] ; then + %{_sbindir}/service autofs stop > /dev/null 2>&1 || : + %{_sbindir}/chkconfig --del autofs +fi +%endif + +%postun +%if %{with_systemd} +%systemd_postun_with_restart %{name}.service +%else +if [ $1 -ge 1 ] ; then + %{_sbindir}/sbin/service autofs condrestart > /dev/null 2>&1 || : +fi +%endif + +%triggerun -- %{name} < 5.0.6-5 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply %{name} +# to migrate them to systemd targets +%{_bindir}/systemd-sysv-convert --save %{name} >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +%{_sbindir}/chkconfig --del %{name} >/dev/null 2>&1 || : +%{_bindir}/systemctl try-restart %{name}.service >/dev/null 2>&1 || : + +%files +%doc CREDITS INSTALL COPY* README* samples/ldap* samples/autofs.schema +%config %{init_file_name} +%config(noreplace,missingok) /etc/auto.master +%config(noreplace) /etc/autofs.conf +%config(noreplace,missingok) /etc/auto.misc +%config(noreplace,missingok) /etc/auto.net +%config(noreplace,missingok) /etc/auto.smb +%config(noreplace) /etc/sysconfig/autofs +%config(noreplace) /etc/autofs_ldap_auth.conf +%{_sbindir}/automount +%if %{with_fedfs} +%{_sbindir}/mount.fedfs +%{_sbindir}/fedfs-map-nfs4 +%endif +%dir %{_libdir}/autofs +%{_libdir}/libautofs.so +%{_libdir}/autofs/ +%{_mandir}/*/* +%dir /etc/auto.master.d + +%changelog +* Mon Aug 09 2021 Mohan Boddu +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Mon Aug 02 2021 Ian Kent - 1:5.1.7-23 +- bz1984813 - autofs: FTBFS due to dynamic PTHREAD_STACK_MIN (glibc 2.34 related) + - fix potential memory leak in "eliminate some more alloca usage" patch. + - remove unused parameter from add_path() in "eliminate some more alloca usage" patch. +- Related: rhbz#1984813 + +* Fri Jul 30 2021 Ian Kent - 1:5.1.7-22 +- bz1984813 - autofs: FTBFS due to dynamic PTHREAD_STACK_MIN (glibc 2.34 related) + - eliminate some more alloca usage. + - use default stack size for threads. +- Resolves: rhbz#1984813 + +* Fri Jul 02 2021 Ian Kent - 1:5.1.7-21 +- bz1938682 - review of important potential issues detected by static analyzers + in autofs-5.1.7-2.el9 + - correct patch, fix concat_options() error handling. +- Related: rhbz#1938682 + +* Wed Jun 30 2021 Ian Kent - 1:5.1.7-20 +- bz1938682 - review of important potential issues detected by static analyzers + in autofs-5.1.7-2.el9 + - fix concat_options() error handling. +- Resolves: rhbz#1938682 + +* Wed Jun 23 2021 Ian Kent - 1:5.1.7-19 +- bz1951393 - add gating.yaml for CI testing + - add gating.yaml. +- Resolves: rhbz#1951393 + +* Tue Jun 22 2021 Mohan Boddu +- Rebuilt for RHEL 9 BETA for openssl 3.0 + Related: rhbz#1971065 + +* Tue Jun 22 2021 Ian Kent - 1:5.1.7-17 +- bz1973892 - /net mount being not cleanly mounted and unmounted + - correct patch, fix nonstrict offset mount fail handling. +- Related: rhbz#1973892 + +* Mon Jun 14 2021 Ian Kent - 1:5.1.7-16 +- bz1965870 - autofs: regression in offset ordering + - fix offset entries order. + - use mapent tree root for tree_mapent_add_node(). + - eliminate redundant cache lookup in tree_mapent_add_node(). + - fix hosts map offset order. + - fix direct mount deadlock. +- bz1965863 - A recent Coverity change can cause an infinit loop on map reload + - fix lookup_prune_one_cache() refactoring change. +- bz1966380 - auto.master manpage doesn't mention -null or other built-in maps + - add missing desciption of null map option. +- Resolves: rhbz#1965870 rhbz#1965863 rhbz#1966380 + +* Tue May 11 2021 Ian Kent - 1:5.1.7-15 + - bz1942371 - Drop nis support from autofs + - fix dangling symlink creation if nis support is not available + (add missing patch). + - bz1958489 - autofs amd mounts present in the configuration get + umounted on reload + - fix amd section mounts map reload. + - bz1958486 - autofs amd type host mounts fail for certain host names + - fix amd hosts mount expire. +- Related: rhbz#1942371 +- Resolves: rhbz#1958489 rhbz#1958486 + +* Tue Apr 20 2021 Ian Kent - 1:5.1.7-14 + - bz1951344 - the autofs distribution tar has a file with an incompatible + license. + - apply first two patches to distribution tar to eliminate + use of the file with the rejected license. + - update spec file to use the new sources and not apply the + first two patches (that have beeny applied to the source tar). +- Resolves: rhbz#1951344 + +* Mon Apr 19 2021 Ian Kent - 1:5.1.7-13 + - bz1942371 - Drop nis support from autofs + - fix dandling symlink creation if nis support is not available. + - remove BuildRequires libnsl2-devel. + - fix incorrect changelog revision. +- Resolves: rhbz#1942371 + +* Tue Apr 13 2021 Ian Kent - 1:5.1.7-12 + - bz1948956 - Using -hosts option does not resolve host from /etc/hosts + and mount failes + - Coverity fixes (arising from RHEL-8 bug 1912106) + - add missing free in handle_mounts(). + - remove redundant if check. + - fix possible memory leak in master_parse(). + - fix possible memory leak in mnts_add_amdmount(). + - fix double unlock in parse_mount(). + - add length check in umount_subtree_mounts(). + - fix flags check in umount_multi(). + - dont try umount after stat() ENOENT fail. + - remove redundant assignment in master_add_amd_mount_section_mounts(). + - fix dead code in mnts_add_mount(). + - fix arg not used in error print. + - fix missing lock release in mount_subtree(). + - fix double free in parse_mapent(). + - refactor lookup_prune_one_cache() a bit. + - cater for empty mounts list in mnts_get_expire_list(). + - add ext_mount_hash_mutex lock helpers. +- Resolves: rhbz#1948956 + +* Thu Apr 15 2021 Mohan Boddu - 1:5.1.7-11 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Mar 16 2021 Ian Kent - 1:5.1.7-10 + - add xdr_exports(). + - remove mount.x and rpcgen dependencies. + - dont use realloc in host exports list processing. + - use sprintf() when constructing hosts mapent. + - fix mnts_remove_amdmount() uses wrong list. + - Fix option for master read wait. + - eliminate cache_lookup_offset() usage. + - fix is mounted check on non existent path. + - simplify cache_get_parent(). + - set offset parent in update_offset_entry(). + - remove redundant variables from mount_autofs_offset(). + - remove unused parameter form do_mount_autofs_offset(). + - refactor umount_multi_triggers(). + - eliminate clean_stale_multi_triggers(). + - simplify mount_subtree() mount check. + - fix mnts_get_expire_list() expire list construction. + - fix inconsistent locking in umount_subtree_mounts(). + - fix return from umount_subtree_mounts() on offset list delete. + - pass mapent_cache to update_offset_entry(). + - fix inconsistent locking in parse_mount(). + - remove unused mount offset list lock functions. + - eliminate count_mounts() from expire_proc_indirect(). + - eliminate some strlen calls in offset handling. + - don't add offset mounts to mounted mounts table. + - reduce umount EBUSY check delay. + - cleanup cache_delete() a little. + - rename path to m_offset in update_offset_entry(). + - don't pass root to do_mount_autofs_offset(). + - rename tree implementation functions. + - add some multi-mount macros. + - remove unused functions cache_dump_multi() and cache_dump_cache(). + - add a len field to struct autofs_point. + - make tree implementation data independent. + - add mapent tree implementation. + - add tree_mapent_add_node(). + - add tree_mapent_delete_offsets(). + - add tree_mapent_traverse_subtree(). + - fix mount_fullpath(). + - add tree_mapent_cleanup_offsets(). + - add set_offset_tree_catatonic(). + - add mount and umount offsets functions. + - switch to use tree implementation for offsets. + - remove obsolete functions. + - remove redundant local var from sun_mount(). + - use mount_fullpath() in one spot in parse_mount(). + - pass root length to mount_fullpath(). + - remove unused function master_submount_li.st_empty(). + - move amd mounts removal into lib/mounts.c. + - check for offset with no mount location. + - remove mounts_mutex. + - remove unused variable from get_exports(). + +* Tue Jan 26 2021 Fedora Release Engineering - 1:5.1.7-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Jan 25 2021 Ian Kent - 1:5.1.7-1 +- Update to upstream release 5.1.7. + +* Mon Aug 31 2020 Ian Kent - 1:5.1.6-11 +- fix configure force shutdown check. + +* Tue Aug 25 2020 Ian Kent - 1:5.1.6-10 +- fix incorrect configure option. + +* Tue Aug 25 2020 Ian Kent - 1:5.1.6-9 +- mount_nfs.c fix local rdma share not mounting. +- fix ldap sasl reconnect problem. +- samples/ldap.schema fix. + +* Mon Jul 27 2020 Fedora Release Engineering - 1:5.1.6-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Jun 17 2020 Ian Kent - 1:5.1.6-7 +- initialize struct addrinfo for getaddrinfo() calls. +- fix quoted string length calc in expandsunent(). +- fix double quoting of ampersand in auto.smb as well. +- fix autofs mount options construction. + +* Mon Jun 01 2020 Ian Kent - 1:5.1.6-4 +- fix changelog message. +- actually commit the patches referred to in the commit. +- adjust revision to allow fixing f32 revision on update. + +* Mon Jun 01 2020 Ian Kent - 1:5.1.6-3 +- make bind mounts propagation slave by default. +- update ldap READMEs and schema definitions. +- fix program map multi-mount lookup after mount fail. +- fix browse dir not re-created on symlink expire. +- fix a regression with map instance lookup. +- correct fsf address. +- fix Makefile targets' directory dependencies. +- remove intr hosts map mount option. +- fix trailing dollar sun entry expansion. +- fix double quoting in auto.smb. + +* Tue Jan 28 2020 Fedora Release Engineering - 1:5.1.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Oct 07 2019 Fedora Release Engineering - 1:5.1.6-1 +- update to upstream 5.1.6 release. + +* Wed Jul 24 2019 Fedora Release Engineering - 1:5.1.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue May 14 2019 Ian Kent - 1:5.1.5-4 +- add BuildRequires: krb5-devel. + +* Tue May 14 2019 Ian Kent - 1:5.1.5-4 +- support strictexpire mount option. +- fix hesiod string check in master_parse(). + +* Thu Jan 31 2019 Fedora Release Engineering - 1:5.1.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Nov 05 2018 Ian Kent - 1:5.1.5-2 +- update spec file to build without hesiod. + +* Mon Nov 05 2018 Ian Kent - 1:5.1.5-1 +- update to upstream 5.1.5 release. + +* Fri Aug 17 2018 Ian Kent - 1:5.1.4-21 +- fix use after free in parse_ldap_config(). + +* Mon Aug 06 2018 Ian Kent - 1:5.1.4-20 +- fix update_negative_cache() map source usage. +- fix program usage message. + +* Thu Jul 12 2018 Fedora Release Engineering - 1:5.1.4-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jul 03 2018 Ian Kent - 1:5.1.4-18 +- add man page note about extra slashes in paths. +- add a number of covarity identified fixes. +- change expire type naming to better reflect usage. +- use defines for expire type. +- make umount_ent() recognise forced umount. +- enable SIGUSR2 handling in rpm spec file. +- fix age setting at startup. + +* Thu May 17 2018 Ian Kent - 1:5.1.4-17 +- fix fd leak in rpc_do_create_client(). + +* Mon Mar 26 2018 Ian Kent - 1:5.1.4-16 +- also add missing "BuildRequires: systemd-devel". + +* Mon Mar 26 2018 Ian Kent - 1:5.1.4-15 +- tiny patch for autofs typo and possible bug. +- add units After line to include statd service. +- use systemd sd_notify() at startup. +- fix NFS version mask usage. +- fix incorrect date in changelog. + +* Tue Mar 06 2018 Ian Kent - 1:5.1.4-14 +- improve hostname lookup error logging. + +* Tue Mar 06 2018 Ian Kent - 1:5.1.4-13 +- fix install permissions of auto.net and auto.smb. +- update change log. + +* Mon Feb 19 2018 Ian Kent - 1:5.1.4-12 +- dont allow trailing slash in master map mount points. +- fix libresolv configure check. +- add fedfs-getsrvinfo.c. +- add mount.fedfs.c. +- add fedfs-map-nfs4.c +- add conditional inclusion of fedfs binaries. +- add an example fedfs master map entry to the installed master map. + +* Fri Feb 09 2018 Igor Gnatenko - 1:5.1.4-11 +- Escape macros in %%changelog + +* Fri Feb 9 2018 Ian Kent - 1:5.1.4-10 +- clean up obsolete spec file directives. + +* Wed Feb 7 2018 Ian Kent - 1:5.1.4-9 +- fix install mode of autofs_ldap_auth.conf. + +* Tue Feb 6 2018 Ian Kent - 1:5.1.4-8 +- add missing BuildRequires. + +* Mon Feb 5 2018 Ian Kent - 1:5.1.4-7 +- add error handling for ext_mount_add(). +- account for recent libnsl changes. +- use_hostname_for_mounts shouldn't prevent selection among replicas. +- fix monotonic_elapse. +- Makefiles.rules: remove 'samples' from SUBDIRS. + +* Thu Feb 1 2018 Ian Kent - 1:5.1.4-6 +- dont use array for path when not necessary. +- fix prefix option handling in expand_entry(). +- fix sublink option not set from defaults. +- fix error return in do_nfs_mount(). + +* Wed Jan 10 2018 Ian Kent - 1:5.1.4-5 +- actually apply fix use after free in do_master_list_reset(). +- fix deadlock in dumpmaps. +- fix rpcgen dependency problem. + +* Fri Dec 22 2017 Ian Kent - 1:5.1.4-4 +- fix use after free in do_master_list_reset(). + +* Wed Dec 20 2017 Ian Kent - 1:5.1.4-3 +- fix email in last two changelog entries. + +* Tue Dec 19 2017 Ian Kent - 1:5.1.4-2 +- fix flag file permission. +- fix directory create permission. + +* Tue Dec 19 2017 Ian Kent - 1:5.1.4-1 +- Update to upstream 5.1.4 release. + +* Tue Nov 07 2017 Igor Gnatenko - 1:5.1.3-5 +- Remove old crufty coreutils requires + +* Wed Aug 02 2017 Fedora Release Engineering - 1:5.1.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1:5.1.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon May 29 2017 Ian Kent - 1:5.1.3-2 +- Fix "Source:" URL and changelog anotations. + +* Mon May 29 2017 Ian Kent - 1:5.1.3-1 +- update to upstream 5.1.3 release. + +* Fri Feb 10 2017 Fedora Release Engineering - 1:5.1.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Jun 15 2016 Fedora Release Engineering - 1:5.1.2-1 +- update to upstream 5.1.2 release. + +* Wed Feb 03 2016 Fedora Release Engineering - 1:5.1.1-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 20 2016 Ian Kent - 1:5.1.1-21 +- add some new upstream memory leak and use after free bug fixes. + +* Wed Jan 20 2016 Ian Kent - 1:5.1.1-20 +- fix incorrect committer changelog entries. +- add current released upstream patches. + +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-7 +- revert fix libtirpc name clash patch (an old 5.0.6 patch). + +* Wed Nov 04 2015 Ian Kent - 1:5.1.1-6 +- remove unnecessary nfs-utils BuildRequires (bz1277669). + +* Mon Nov 02 2015 Ian Kent - 1:5.1.1-5 +- fix fix gcc5 complaints. +- update libtirpc workaround for new soname. + +* Sun Nov 01 2015 Kalev Lember - 1:5.1.1-4 +- Rebuilt for libtirpc soname bump + +* Wed Jun 17 2015 Fedora Release Engineering - 1:5.1.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Jun 12 2015 Ian Kent - 1:5.1.1-2 +- add build requires for gcc. + +* Thu Apr 23 2015 Ian Kent - 1:5.1.1-1 +- Update to autofs-5.1.1. + +* Mon Mar 23 2015 Ian Kent - 1:5.1.0-12 +- fix gcc5 complaints (bz1204685). + +* Mon Mar 23 2015 Peter Robinson 1:5.1.0-11 +- Drop ancient 2.6 kernel patches from docs + +* Wed Jan 21 2015 Ian Kent - 1:5.1.0-10 +- make negative cache update consistent for all lookup modules. +- ensure negative cache isn't updated on remount. +- dont add wildcard to negative cache. +- make service want network-online (bz1071591). + +* Tue Nov 18 2014 Ian Kent - 1:5.1.0-9 +- fix custom autofs.conf not being installed. +- init qdn before use in get_query_dn(). +- fix typo in update_hosts_mounts(). +- fix hosts map update on reload. + + +* Fri Oct 17 2014 Ian Kent - 1:5.1.0-8 +- fix fix master map type check. + +* Wed Oct 15 2014 Ian Kent - 1:5.1.0-7 +- force disable browse mode for amd format maps. +- fix hosts map options check in lookup_amd_instance(). +- fix memory leak in create_client(). +- fix memory leak in get_exports(). +- fix memory leak in get_defaults_entry(). +- fix out of order clearing of options buffer. +- fix reset amd lexer scan buffer. +- ignore multiple commas in options strings. +- fix typo in flagdir configure option. +- clarify multiple mounts description. +- gaurd against incorrect umount return. +- update man page autofs(8) for systemd. +- remove ancient kernel Requires. + +* Fri Aug 15 2014 Fedora Release Engineering - 1:5.1.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Jul 8 2014 Ian Kent - 1:5.1.0-5 +- rename two incorrectly named patches. +- add missing change entry to another patch. + +* Mon Jul 7 2014 Ian Kent - 1:5.1.0-4 +- add mutex call return check in defaults.c. + +* Mon Jul 7 2014 Ian Kent - 1:5.1.0-3 +- fix compile error in defaults.c. +- add serialization to sasl init. +- dont allocate dev_ctl_ops too early. +- fix incorrect round robin host detection. +- fix race accessing qdn in get_query_dn(). +- fix leak in cache_push_mapent(). +- fix config entry read buffer not checked. +- fix FILE pointer check in defaults_read_config(). +- fix memory leak in conf_amd_get_log_options(). +- fix signed comparison in inet_fill_net(). +- fix buffer size checks in get_network_proximity(). +- fix leak in get_network_proximity(). +- fix buffer size checks in merge_options(). +- check amd lex buffer len before copy. +- add return check in ldap check_map_indirect(). +- check host macro is set before use. +- check options length before use in parse_amd.c. +- fix some out of order evaluations in parse_amd.c. +- fix copy and paste error in dup_defaults_entry(). + +* Sat Jun 07 2014 Fedora Release Engineering - 1:5.1.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Thu Jun 5 2014 Ian Kent - 1:5.1.0-1 +- update to upstream release, 5.1.0. + - fix reset flex scan buffer on init. + - fix fix negative status being reset on map read. + - fix out of order amd timestamp lookup. + - fix ldap default schema config. + - fix ldap default master map name config. + - fix map format init in lookup_init(). + - fix incorrect max key length in defaults get_hash(). + - fix xfn sets incorrect lexer state. + - fix old style key lookup. + - fix expire when server not responding. + - fix ldap_uri config update. + - fix typo in conf_load_autofs_defaults(). + - fix hash on confg option add and delete. + - add plus to path match pattern. + - fix multi entry ldap option handling. + - cleanup options in amd_parse.c. + - allow empty value for some map options. + - allow empty value in macro selectors. + +* Sun Apr 13 2014 Ian Kent - 1:5.1.0-0.beta1.1 +- amd lookup update lookup ldap to handle amd keys + - inadvertantly drop from initial series. +- amd lookup update lookup hesiod to handle amd keys + - inadvertantly drop from initial series. +- fix wildcard key lookup. +- check for non existent negative entries in lookup_ghost(). + +* Wed Apr 2 2014 Ian Kent - 1:5.1.0-0.beta1 +- Update to autofs-5.0.1-beta1. + +* Wed Feb 19 2014 Ian Kent - 1:5.0.8-6 +- fix portmap not trying proto v2. + +* Tue Dec 24 2013 Ian Kent - 1:5.0.8-5 +- fix ipv6 link local address handling. +- fix fix ipv6 libtirpc getport. +- get_nfs_info() should query portmapper if port is not given. +- fix rpc_portmap_getport() proto not set. + +* Mon Nov 25 2013 Ian Kent - 1:5.0.8-4 +- allow --with-systemd to take a path arg. +- fix WITH_LIBTIRPC function name. +- fix ipv6 libtirpc getport (bz1033918). + +* Thu Nov 7 2013 Ian Kent - 1:5.0.8-3 +- fix undefined authtype_requires_creds err if ldap enabled but without sasl. +- fix master map type check. +- fix task manager not getting signaled. + +* Mon Oct 21 2013 Ian Kent - 1:5.0.8-2 +- remove now unused patch files (bz1020242). + +* Mon Oct 21 2013 Ian Kent - 1:5.0.8-1 +- update to upstream version 5.0.8 (bz1020242). + +* Sat Aug 03 2013 Fedora Release Engineering - 1:5.0.7-29 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sat Jul 13 2013 Ian Kent - 1:5.0.7-28 +- add after sssd dependency to unit file (bz984089). + +* Sat Jul 13 2013 Ian Kent - 1:5.0.7-27 +- fix a couple of compiler warnings. + +* Fri Jul 12 2013 Ian Kent - 1:5.0.7-26 +- link with full reloc options. + +* Fri Jul 12 2013 Ian Kent - 1:5.0.7-25 +- fix default path used for unitdir. +- fix changelog inconsistent dates. + +* Wed Jul 10 2013 Ian Kent - 1:5.0.7-24 +- check for protocol option. +- use ulimit max open files if greater than internal maximum. + +* Fri Jun 28 2013 Ian Kent - 1:5.0.7-23 +- fix add null check in parse_server_string() (bz979155). + +* Wed Jun 19 2013 Ian Kent - 1:5.0.7-22 +- misc man page fixes (bz948517). + +* Wed Jun 12 2013 Ian Kent - 1:5.0.7-21 +- fix probe each nfs version in turn for singleton mounts (bz973537). + +* Tue Jun 11 2013 Ian Kent - 1:5.0.7-20 +- fix master map mount options matching. +- fix master map bogus keywork match. +- fix fix map entry duplicate offset detection. +- add a number of fixes based on a Covarity report. + +* Mon May 27 2013 Ian Kent - 1:5.0.7-19 +- dont probe rdma mounts. + +* Fri May 24 2013 Ian Kent - 1:5.0.7-17 +- fix interface address null check. + +* Mon May 13 2013 Ian Kent - 1:5.0.7-16 +- make dump maps check for duplicate indirect mounts (bz961312). +- document allowed map sources in auto.master(5) (bz961312). +- add enable sloppy mount option to configure. + +* Sun Apr 28 2013 Ian Kent - 1:5.0.7-14 +- fix syncronize of handle_mounts() shutdown. +- fix submount tree not all expiring. + +* Tue Mar 26 2013 Ian Kent - 1:5.0.7-13 +- fix some automount(8) typos (bz664178). + +* Tue Mar 12 2013 Ian Kent - 1:5.0.7-12 +- dont fail on master map self include. +- fix wildcard multi map regression. +- fix file descriptor leak when reloading the daemon. +- depricate nosymlink pseudo option. +- add symlink pseudo option. +- update kernel include files. +- fix requires in spec file. +- fix libtirpc build option. +- fix systemd unidir in spec file. +- document browse option in man page. +- fix automounter support on parisc. + +* Wed Feb 13 2013 Fedora Release Engineering - 1:5.0.7-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Jan 21 2013 Ian Kent - 1:5.0.7-10 +- fix submount offset delete. +- fix init script status return. +- fix use get_proximity() without libtirpc. +- don't use dirent d_type to filter out files in scandir(). +- don't schedule new alarms after readmap. +- use numeric protocol ids instead of protoent structs. +- lib/defaults.c: use WITH_LDAP conditional around LDAP types. +- make yellow pages support optional. +- modules/replicated.c: use sin6_addr.s6_addr32. +- workaround missing GNU versionsort extension. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-9 +- fix nobind man page description. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-8 +- fix map entry duplicate offset detection. +- Allow nsswitch.conf to not contain "automount:" lines. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-7 +- use spec file systemd unit file location. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-6 +- fix recursive mount deadlock. +- increase file map read buffer size. +- handle new location of systemd. + +* Tue Oct 16 2012 Ian Kent - 1:5.0.7-5 +- configure: allow cross compilation update. +- fix date in changelog entry. + +* Mon Oct 15 2012 Ian Kent - 1:5.0.7-4 +- include usage in usage message. +- dont wait forever to restart. +- add option description to man page. +- fix null map entry order handling. +- make description of default MOUNT_WAIT setting clear. +- configure.in: allow cross compilation. +- README: update mailing list subscription info. +- allow non root user to check status. + +* Mon Sep 10 2012 Ian Kent - 1:5.0.7-3 +- fix nobind sun escaped map entries. +- fix use cache entry after free mistake. +- fix ipv6 proximity calculation. +- fix parse buffer initialization. +- fix typo in automount(8). + +* Mon Aug 27 2012 Ian Kent - 1:5.0.7-2 +- update systemd scriplet macros (bz850040). + +* Wed Jul 25 2012 Ian Kent - 1:5.0.7-1 +- Update to upstream version 5.0.7. + +* Wed Jul 25 2012 Ian Kent - 1:5.0.6-24 +- fix changelog message commit dates. + +* Wed Jul 18 2012 Fedora Release Engineering - 1:5.0.6-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jul 16 2012 Ian Kent - 1:5.0.6-21 +- fix systemd argument passing. +- fix get_nfs_info() can incorrectly fail. +- fix offset directory removal. + +* Tue Jul 3 2012 Ian Kent - 1:5.0.6-21 +- fix fix LDAP result leaks on error paths. +- 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. +- 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. +- make autofs wait longer for shutdown. +- fix sss map age not updated. +- fix remount deadlock. +- fix umount recovery of busy direct mount. +- fix offset mount point directory removal. +- remove move mount code and configure option. +- fix remount of multi mount. +- fix devce ioctl alloc path check. +- refactor hosts lookup module. +- remove cache update from parse_mount(). +- add function to delete offset cache entry. +- allow update of multi mount offset entries. +- add hup signal handling to hosts map. + +* Tue May 22 2012 Ian Kent - 1:5.0.6-19 +- fix libtirpc name clash (bz821847). + +* Tue May 22 2012 Ian Kent - 1:5.0.6-18 +- update patch fix initialization in rpc create_client() (bz821847). + +* Wed May 16 2012 Ian Kent - 1:5.0.6-17 +- fix initialization in rpc create_client() (bz821847). + +* Tue May 1 2012 Ian Kent - 1:5.0.6-16 +- add libsss_autofs as a build dependency. + +* Tue May 1 2012 Ian Kent - 1:5.0.6-15 +- fix typo in libtirpc file name. +- fix rework error return handling in rpc code. +- allow MOUNT_WAIT to override probe. +- improve UDP RPC timeout handling. +- fix segfault in get_query_dn(). +- use strtok_r() in linux_version_code(). +- fix sss wildcard match. +- fix dlopen() error handling in sss module. +- fix configure string length tests for sss library. + +* Wed Feb 29 2012 Ian Kent - 1:5.0.6-14 +- fix function to check mount.nfs version. + +* Sun Feb 26 2012 Ian Kent - 1:5.0.6-13 +- fix error in %%post scriplet. + +* Fri Feb 24 2012 Ian Kent - 1:5.0.6-12 +- ignore duplicate exports in auto.net. +- add kernel verion check function. +- add function to check mount.nfs version. +- reinstate singleton mount probe. +- rework error return handling in rpc code. +- catch EHOSTUNREACH and bail out early. +- systemd support fixes. +- fix segmentation fault in do_remount_indirect(). + +* Thu Feb 9 2012 Ian Kent - 1:5.0.6-11 +- fix fuzz in CHANGELOG hunk when applying patch26. + +* Tue Feb 7 2012 Ian Kent - 1:5.0.6-10 +- fix rpc build error. +- add sss lookup module. +- teach automount about sss source. + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-9 +- add correct patch for "fix improve mount location error reporting". +- add correct patch for "fix fix wait for master source mutex". + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-8 +- fix fix wait for master source mutex. +- fix improve mount location error reporting (bz783496). + +* Thu Jan 12 2012 Fedora Release Engineering - 1:5.0.6-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Dec 9 2011 Ian Kent - 1:5.0.6-6 +- remove empty command line arguments (passed by systemd). + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-5 +- fix ipv6 name lookup check. +- fix ipv6 rpc calls. +- fix ipv6 configure check. +- add piddir to configure. +- add systemd unit support. +- fix MNT_DETACH define. + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-4 +- fix lsb service name in init script 2 (bz712504). + +* Tue Nov 8 2011 Ian Kent - 1:5.0.6-3 +- improve mount location error reporting. +- fix paged query more results check. +- fix dumpmaps not reading maps. +- fix result null check in read_one_map(). +- Fix LDAP result leaks on error paths. +- code analysis fixes 1. +- fix not bind mounting local filesystem. +- update dir map-type patch for changed patch order. +- fix wait for master source mutex. +- fix submount shutdown race +- fix fix map source check in file lookup. +- add disable move mount configure option. + +* Wed Jul 6 2011 Ian Kent - 1:5.0.6-2 +- add missing spec file entries for dir-type change (bz719208). + +* Mon Jul 4 2011 Ian Kent - 1:5.0.6-1 +- update source to 5.0.6. +- fix ipv6 name for lookup fix. +- add dir map-type patch. + +* Tue Jun 14 2011 Ian Kent - 1:5.0.5-38 +- fix lsb service name in init script (bz692963). + +* Fri Mar 18 2011 Ian Kent - 1:5.0.5-37 +- replace GPLv3 code with GPLv2 equivalent. + +* Thu Mar 03 2011 Ian Kent - 1:5.0.5-36 +- use weight only for server selection. +- fix isspace() wild card substition. +- auto adjust ldap page size. +- fix prune cache valid check. +- fix mountd vers retry. +- fix expire race. +- add lsb force-reload and try-restart. + +* Mon Feb 07 2011 Fedora Release Engineering - 1:5.0.5-35 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Nov 23 2010 Ian Kent - 1:5.0.5-34.fc15 +- revert wait for master map to be available at start. + +* Mon Nov 22 2010 Ian Kent - 1:5.0.5-33.fc15 +- fix wait for master map to be available at start. + +* Mon Nov 8 2010 Ian Kent - 1:5.0.5-32.fc15 +- always read file maps mount lookup map read fix. +- fix direct map not updating on reread. +- add external bind method. +- fix add simple bind auth. +- add option to dump configured automount maps. +- wait for master map to be available at start. + +* Fri Aug 27 2010 Ian Kent - 1:5.0.5-31.fc15 +- fix status privilege error (bz627605). + +* Wed Aug 18 2010 Ian Kent - 1:5.0.5-30.fc15 +- fix restart not working (bz624694). + +* Wed Aug 11 2010 Ian Kent - 1:5.0.5-29 +- remove ERR_remove_state() openssl call. + +* Tue Aug 10 2010 Ian Kent - 1:5.0.5-28 +- remove extra read master map call. +- remove extra cache create call in master_add_map_source(). +- fix error handing in do_mount_indirect(). +- expire thread use pending mutex. +- explicity link against the Kerberos library. +- remove some log message duplication for verbose logging. + +* Mon May 24 2010 Ian Kent - 1:5.0.5-27.fc14 +- fix master map source server unavailable handling. +- add autofs_ldap_auth.conf man page. +- fix random selection for host on different network. +- make redhat init script more lsb compliant. +- don't hold lock for simple mounts. +- fix remount locking. +- fix wildcard map entry match. +- fix parse_sun() module init. +- dont check null cache on expire. +- fix null cache race. +- fix cache_init() on source re-read. +- fix mapent becomes negative during lookup. +- check each dc server individually. +- fix negative cache included map lookup. +- remove state machine timed wait. + +* Fri Apr 30 2010 Ian Kent - 1:5.0.5-26.fc14 +- remove URL tag as there is not official autofs wiki (bz529804). + +* Wed Apr 7 2010 Ian Kent - 1:5.0.5-25.fc14 +- make nfs4 default for replicated selection configuration (bz579949). +- add simple bind authentication option (bz579951). + +* Fri Mar 26 2010 Ian Kent - 1:5.0.5-24.fc14 +- fix add locality as valid ldap master map attribute (bz575863). + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- fix get query dn failure. +- fix ampersand escape in auto.smb. +- add locality as valid ldap master map attribute. + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- add Conflicts to ensure we get fixed cyrus-sasl-lib for rev 21 change. + +* Tue Feb 23 2010 Ian Kent - 1:5.0.5-21 +- add missing sasl mutex callbacks. + +* Thu Feb 11 2010 Ian Kent - 1:5.0.5-19 +- fix segfault upon reconnect cannot find valid base dn. + +* Mon Feb 1 2010 Ian Kent - 1:5.0.5-17 +- dont connect at ldap lookup module init. +- fix random selection option. +- fix disable timeout. +- fix strdup() return value check. + +* Tue Dec 8 2009 Ian Kent - 1:5.0.5-16 +- fix memory leak on reload (bz545137). + +* Fri Dec 4 2009 Ian Kent - 1:5.0.5-14 +- fix rpc fail on large export list (bz543023). + +* Mon Nov 30 2009 Ian Kent - 1:5.0.5-12 +- check for path mount location in generic module. +- dont fail mount on access fail. + +* Tue Nov 24 2009 Ian Kent - 1:5.0.5-10 +- fix pidof init script usage. + +* Mon Nov 23 2009 Ian Kent - 1:5.0.5-8 +- fix timeout in connect_nb(). + +* Mon Nov 16 2009 Ian Kent - 1:5.0.5-6 +- don't use master_lex_destroy() to clear parse buffer. +- make documentation for set-log-priority clearer. + +* Tue Nov 10 2009 Ian Kent - 1:5.0.5-5 +- fix ext4 "preen" fsck at mount. + +* Mon Nov 9 2009 Ian Kent - 1:5.0.5-4 +- fix stale initialization for file map instance patch was not applied. + +* Tue Nov 3 2009 Ian Kent - 1:5.0.5-3 +- fix stale initialization for file map instance. + +* Tue Oct 6 2009 Ian Kent - 1:5.0.5-2 +- fix included map read fail handling. +- refactor ldap sasl authentication bind to eliminate extra connect + causing some servers to reject the request. +- add mount wait parameter to allow timeout of mount requests to + unresponsive servers. +- special case cifs escape handling. +- fix libxml2 workaround configure. +- more code analysis corrections (and fix a typo in an init script). +- fix backwards #ifndef INET6. + +* Fri Sep 4 2009 Ian Kent - 1:5.0.5-1 +- update source to latest upstream version. + - this is essentially a consolidation of the patches already in this rpm. +- add dist tag to match latest RHEL-5 package tag format. + +* Thu Sep 3 2009 Ian Kent - 1:5.0.4-39 +- fix libxml2 non-thread-safe calls. +- fix direct map cache locking. +- fix patch "dont umount existing direct mount on reread" deadlock. + +* Fri Jul 24 2009 Fedora Release Engineering - 1:5.0.4-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Jul 17 2009 Ian Kent - 1:5.0.4-34 +- fix typo in patch to allow dumping core. + +* Wed Jul 15 2009 Ian Kent - 1:5.0.4-32 +- fix an RPC fd leak. +- don't block signals we expect to dump core. +- fix pthread push order in expire_proc_direct(). + +* Fri Jun 12 2009 Ian Kent - 1:5.0.4-30 +- fix incorrect dclist free. +- srv lookup handle endianness. +- fix bug introduced by library reload changes which causes autofs to + not release mount thread resources when using submounts. +- fix notify mount message path. +- try harder to work out if we created mount point at remount. +- fix double free in do_sasl_bind(). +- manual umount recovery fixes. +- fix map type info parse error. + +* Mon May 18 2009 Ian Kent - 1:5.0.4-28 +- use intr option as hosts mount default. +- sync kernel includes with upstream kernel. +- dont umount existing direct mount on master re-read. +- fix incorrect shutdown introduced by library relaod fixes. +- improve manual umount recovery. +- dont fail on ipv6 address when adding host. +- always read file maps multi map fix. +- always read file maps key lookup fixes. +- add support for LDAP_URI="ldap:///" SRV RR lookup. + +* Thu Apr 16 2009 Ian Kent - 1:5.0.4-26 +- fix lsb init script header. +- fix memory leak reading ldap master map. +- fix st_remove_tasks() locking. +- reset flex scanner when setting buffer. +- zero s_magic is valid. + +* Mon Mar 30 2009 Ian Kent - 1:5.0.4-24 +- clear rpc client on lookup fail. + +* Fri Mar 20 2009 Ian Kent - 1:5.0.4-23 +- fix call restorecon when misc device file doesn't exist. + +* Wed Mar 18 2009 Ian Kent - 1:5.0.4-22 +- use misc device ioctl interface by default, if available. + +* Tue Mar 17 2009 Ian Kent - 1:5.0.4-21 +- fix file map lookup when reading included or nsswitch sources. + - a regression introduced by file map lookup optimisation in rev 9. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-20 +- add LSB init script parameter block. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-19 +- another easy alloca replacements fix. + +* Thu Mar 12 2009 Ian Kent - 1:5.0.4-18 +- fix return start status on fail. +- fix double free in expire_proc(). + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-17 +- fix bad token declaration in master map parser. + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-16 +- correct mkdir command in %%install section, bz481132. + +* Tue Feb 24 2009 Ian Kent - 1:5.0.4-15 +- fix array out of bounds accesses and cleanup couple of other alloca() calls. +- Undo mistake in copy order for submount path introduced by rev 11 patch. +- add check for alternate libxml2 library for libxml2 tsd workaround. +- add check for alternate libtirpc library for libtirpc tsd workaround. +- cleanup configure defines for libtirpc. +- add WITH_LIBTIRPC to -V status report. +- add libtirpc-devel to BuildRequires. +- add nfs mount protocol default configuration option. + +* Mon Feb 23 2009 Fedora Release Engineering - 1:5.0.4-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Ian Kent - 5.0.4-10 +- fix mntent.h not included before use of setmntent_r(). + +* Mon Feb 16 2009 Ian Kent - 5.0.4-9 +- fix hosts map use after free. +- fix uri list locking (again). +- check for stale SASL credentials upon connect fail. +- add "forcestart" and "forcerestart" init script options to allow + use of 5.0.3 strartup behavior if required. +- always read entire file map into cache to speed lookups. +- make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. +- make some easy alloca replacements. +- update to configure libtirpc if present. +- update to provide ipv6 name and address support. +- update to provide ipv6 address parsing. + +* Thu Feb 5 2009 Ian Kent - 5.0.4-8 +- rename program map parsing bug fix patch. +- use CLOEXEC flag functionality for setmntent also, if present. + +* Wed Jan 21 2009 Jeff Moyer - 5.0.4-6 +- fix a bug in the program map parsing routine + +* Thu Jan 15 2009 Ian Kent - 5.0.4-5 +- fix negative caching of non-existent keys. +- fix ldap library detection in configure. +- use CLOEXEC flag functionality if present. +- fix select(2) fd limit. +- make hash table scale to thousands of entries. + +* Wed Dec 3 2008 Ian Kent - 5.0.4-4 +- fix nested submount expire deadlock. + +* Wed Nov 19 2008 Ian Kent - 5.0.4-3 +- fix libxml2 version check for deciding whether to use workaround. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-2 +- Fix tag confusion. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-1 +- Upstream source version 5.0.4. + +* Tue Nov 11 2008 Ian Kent - 5.0.3-32 +- correct buffer length setting in autofs-5.0.3-fix-ifc-buff-size-fix.patch. + +* Sun Nov 2 2008 Ian Kent - 5.0.3-30 +- fix segv during library re-open. +- fix incorrect pthreads condition handling for expire requests. +- fix master map lexer eval order. +- fix bad alloca usage. + +* Thu Oct 23 2008 Ian Kent - 5.0.3-28 +- don't close file handle for rootless direct mounti-mount at mount. +- wait submount expire thread completion when expire successful. +- add inadvertantly ommitted server list locking in LDAP module. + +* Fri Oct 10 2008 Ian Kent - 5.0.3-26 +- add map-type-in-map-name fix patch to sync with upstream and RHEL. +- don't readmap on HUP for new mount. +- add NIS_PARTIAL to map entry not found check and fix use after free bug. + +* Fri Sep 26 2008 Ian Kent - 5.0.3-25 +- fix fd leak at multi-mount non-fatal mount fail. +- fix incorrect multi-mount mountpoint calcualtion. + +* Fri Sep 19 2008 Ian Kent - 5.0.3-23 +- add upstream bug fixes + - bug fix for mtab check. + - bug fix for zero length nis key. + - update for ifc buffer handling. + - bug fix for kernel automount handling. +- warning: I found a bunch of patches that were present but not + being applied. + +* Mon Aug 25 2008 Ian Kent - 5.0.3-21 +- add upstream bug fix patches + - add command line option to override is running check. + - don't use proc fs for is running check. + - fix fail on included browse map not found. + - fix incorrect multi source messages. + - clear stale flag on map read. + - fix proximity other rpc ping timeout. + - refactor mount request vars code. + - make handle_mounts startup condition distinct. + - fix submount shutdown handling. + - try not to block on expire. + - add configuration paramter UMOUNT_WAIT. + - fix multi mount race. + - fix nfs4 colon escape handling. + - check replicated list after probe. + - add replicated server selection debug logging. + - update replicated server selection documentation. + - use /dev/urandom instead of /dev/random. + - check for mtab pointing to /proc/mounts. + - fix interface config buffer size. + - fix percent hack heap corruption. + +* Mon Jul 14 2008 Tom "spot" Callaway - 5.0.3-19 +- change conflicts to requires +- fix license tag + +* Mon Jun 30 2008 Ian Kent - 5.0.3-18 +- don't abuse the ap->ghost field on NFS mount. +- multi-map doesn't pickup NIS updates automatically. +- eliminate redundant DNS name lookups. +- mount thread create condition handling fix. +- allow directory create on NFS root. +- check direct mount path length. +- fix incorrect in check in get user info. +- fix a couple of memory leaks. + +* Wed May 14 2008 Ian Kent - 5.0.3-16 +- update patches, documentation and comments only change. +- rename patch and add to CVS. + +* Mon May 12 2008 Ian Kent - 5.0.3-14 +- check for nohide mounts (bz 442618). +- ignore nsswitch sources that aren't supported (bz 445880). + +* Thu Apr 17 2008 Ian Kent - 5.0.3-13 +- fix typo in patch for incorrect pthreads condition handling patch. + +* Mon Apr 14 2008 Ian Kent - 5.0.3-12 +- fix incorrect pthreads condition handling for mount requests. + +* Tue Apr 1 2008 Ian Kent - 5.0.3-11 +- and another try at fixing lexer matching map type in map name. + +* Sun Mar 30 2008 Ian Kent - 5.0.3-10 +- another try a fixing lexer matching map type in map name. + +* Wed Mar 26 2008 Ian Kent - 5.0.3-9 +- fix lexer ambiguity in match when map type name is included in map name. + +* Mon Mar 24 2008 Ian Kent - 5.0.3-8 +- revert miscellaneous device node related patches. +- add missing check for zero length NIS key. +- fix incorrect match of map type name when included in map name. +- update rev 7 sasl callbacks patch. + +* Thu Mar 20 2008 Ian Kent - 5.0.3-7 +- add patch to initialize sasl callbacks unconditionally on autofs + LDAP lookup library load. + +* Mon Feb 25 2008 Ian Kent - 5.0.3-6 +- fix expire calling kernel more often than needed. +- fix unlink of mount tree incorrectly causing autofs mount fail. +- add miscellaneous device node interface library. +- use miscellaneous device node, if available, for active restart. +- device node and active restart fixes. +- update is_mounted to use device node ioctl, if available. + +* Fri Feb 1 2008 Ian Kent - 5.0.3-5 +- another fix for don't fail on empty master map. + +* Fri Jan 25 2008 Ian Kent - 5.0.3-4 +- correction to the correction for handling of LDAP base dns with spaces. +- avoid using UDP for probing NFSv4 mount requests. +- use libldap instead of libldap_r. + +* Mon Jan 21 2008 Ian Kent - 5.0.3-3 +- catch "-xfn" map type and issue "no supported" message. +- another correction for handling of LDAP base dns with spaces. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-2 +- correct configure test for ldap page control functions. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-1 +- update source to version 5.0.3. + +* Fri Dec 21 2007 Ian Kent - 5.0.2-25 +- Bug 426401: CVE-2007-6285 autofs default doesn't set nodev in /net [rawhide] + - use mount option "nodev" for "-hosts" map unless "dev" is explicily specified. + +* Tue Dec 18 2007 Ian Kent - 5.0.2-23 +- Bug 397591 SELinux is preventing /sbin/rpc.statd (rpcd_t) "search" to (sysctl_fs_t). + - prevent fork between fd open and setting of FD_CLOEXEC. + +* Thu Dec 13 2007 Ian Kent - 5.0.2-21 +- Bug 421371: CVE-2007-5964 autofs defaults don't restrict suid in /net [rawhide] + - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified. + +* Thu Dec 6 2007 Jeremy Katz - 1:5.0.2-19 +- rebuild for new ldap + +* Tue Nov 20 2007 Ian Kent - 5.0.2-18 +- fix schema selection in LDAP schema discovery. +- check for "*" when looking up wildcard in LDAP. +- fix couple of edge case parse fails of timeout option. +- add SEARCH_BASE configuration option. +- add random selection as a master map entry option. +- re-read config on HUP signal. +- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options. +- fix deadlock in submount mount module. +- fix lack of ferror() checking when reading files. +- fix typo in autofs(5) man page. +- fix map entry expansion when undefined macro is present. +- remove unused export validation code. +- add dynamic logging (adapted from v4 patch from Jeff Moyer). +- fix recursive loopback mounts (Matthias Koenig). +- add map re-load to verbose logging. +- fix handling of LDAP base dns with spaces. +- handle MTAB_NOTUPDATED status return from mount. +- when default master map, auto.master, is used also check for auto_master. +- update negative mount timeout handling. +- fix large group handling (Ryan Thomas). +- fix for dynamic logging breaking non-sasl build (Guillaume Rousse). +- eliminate NULL proc ping for singleton host or local mounts. + +* Mon Sep 24 2007 Ian Kent - 5.0.2-16 +- add descriptive comments to config about LDAP schema discovery. +- work around segfault at exit caused by libxml2. +- fix foreground logging (also fixes shutdown needing extra signal bug). + +* Wed Sep 5 2007 Ian Kent - 5.0.2-15 +- fix LDAP schema discovery. + +* Tue Aug 28 2007 Ian Kent - 5.0.2-14 +- update patch to prevent failure on empty master map. +- if there's no "automount" entry in nsswitch.conf use "files" source. +- add LDAP schema discovery if no schema is configured. + +* Wed Aug 22 2007 Ian Kent - 5.0.2-13 +- fix "nosymlink" option handling and add desription to man page. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-12 +- change random multiple server selection option name to be consistent + with upstream naming. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-11 +- don't fail on empty master map. +- add support for the "%%" hack for case insensitive attribute schemas. + +* Mon Jul 30 2007 Ian Kent - 5.0.2-10 +- mark map instances stale so they aren't "cleaned" during updates. +- fix large file compile time option. + +* Fri Jul 27 2007 Ian Kent - 5.0.2-9 +- fix version passed to get_supported_ver_and_cost (bz 249574). + +* Tue Jul 24 2007 Ian Kent - 5.0.2-8 +- fix parse confusion between attribute and attribute value. + +* Fri Jul 20 2007 Ian Kent - 5.0.2-7 +- fix handling of quoted slash alone (bz 248943). + +* Wed Jul 18 2007 Ian Kent - 5.0.2-6 +- fix wait time resolution in alarm and state queue handlers (bz 247711). + +* Mon Jul 16 2007 Ian Kent - 5.0.2-5 +- fix mount point directory creation for bind mounts. +- add quoting for exports gathered by hosts map. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-4 +- update multi map nsswitch patch. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-3 +- add missing "multi" map support. +- add multi map nsswitch lookup. + +* Wed Jun 20 2007 Ian Kent - 5.0.2-2 +- include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). +- correct initialization of local var in parse_server_string. + +* Mon Jun 18 2007 Ian Kent - 5.0.2-1 +- Update to upstream release 5.0.2. + +* Tue Jun 12 2007 Ian Kent - 5.0.1-16 +- add ldaps support. + - note: it's no longer possible to have multiple hosts in an ldap map spec. + - note: to do this you need to rely on the ldap client config. + +* Thu Jun 7 2007 Ian Kent - 5.0.1-14 +- fix deadlock in alarm manager module. + +* Sun Jun 3 2007 Ian Kent - 5.0.1-12 +- correct mistake in logic test in wildcard lookup. + +* Mon May 7 2007 Ian Kent - 5.0.1-10 +- fix master map lexer to admit "." in macro values. + +* Tue Apr 17 2007 Ian Kent - 5.0.1-9 +- upstream fix for filesystem is local check. +- disable exports access control check (bz 203277). +- fix patch to add command option for set a global mount options (bz 214684). + +* Mon Apr 16 2007 Ian Kent - 5.0.1-8 +- add configuration variable to control appending of global options (bz 214684). +- add command option to set a global mount options string (bz 214684). + +* Tue Apr 3 2007 Ian Kent - 5.0.1-7 +- fix "null" domain netgroup match for "-hosts" map. + +* Thu Mar 29 2007 Ian Kent - 5.0.1-6 +- fix directory creation for browse mounts. +- fix wildcard map handling and improve nsswitch source map update. + +* Fri Mar 16 2007 Ian Kent - 5.0.1-5 +- drop "DEFAULT_" prefix from configuration names. +- add option to select replicated server at random (instead of + ping response time) (bz 227604). +- fix incorrect cast in directory cleanup routines (bz 231864). + +* Thu Mar 8 2007 Ian Kent - 5.0.1-4 +- fixed numeric export match (bz 231188). + +* Thu Mar 1 2007 Ian Kent - 5.0.1-3 +- change file map lexer to allow white-space only blank lines (bz 229434). + +* Fri Feb 23 2007 Ian Kent - 5.0.1-2 +- update "@network" matching patch. + +* Thu Feb 22 2007 Ian Kent - 5.0.1-1 +- update to release tar. +- fix return check for getpwuid_r and getgrgid_r. +- patch to give up trying to update exports list while host is mounted. +- fix to "@network" matching. +- patch to check for fstab update and retry if not updated. + +* Tue Feb 20 2007 Ian Kent - 5.0.1-0.rc3.24 +- add "condrestart" to init script (bz 228860). +- add "@network" and .domain.name export check. +- fix display map name in mount entry for "-hosts" map. + +* Fri Feb 16 2007 Ian Kent - 5.0.1-0.rc3.22 +- fix localhost replicated mounts not working (bz 208757). + +* Wed Feb 14 2007 Ian Kent - 5.0.1-0.rc3.20 +- correct return status from do_mkdir (bz 223480). + +* Sat Feb 10 2007 Ian Kent - 5.0.1-0.rc3.18 +- update the "task done race" patch to fix a deadlock. +- added URL tag. +- removed obsoletes autofs-ldap. +- replaced init directory paths with %%{_initrddir} macro. + +* Fri Feb 9 2007 Ian Kent - 5.0.1-0.rc3.17 +- make use of spaces and tabs in spec file consistent. +- escape embedded macro text in %%changelog. +- eliminate redundant %%version and %%release. +- remove redundant conditional check from %%clean. +- remove redundant exit from %%preun. +- correct %%defattr spec. +- remove empty %%doc and redundant %%dir misc lines. +- combine program module spec lines into simpler one line form. + +* Tue Feb 6 2007 Ian Kent - 5.0.1-0.rc3.15 +- fix race when setting task done (bz 227268). + +* Mon Jan 29 2007 Ian Kent - 5.0.1-0.rc3.13 +- make double quote handing consistent (at least as much as we can). +- fix handling of trailing white space in wildcard lookup (forward port bz 199720). +- check fqdn of each interface when matching export access list (bz 213700). + +* Thu Jan 18 2007 Ian Kent - 5.0.1-0.rc3.11 +- correct check for busy offset mounts before offset umount (bz 222872). + +* Wed Jan 17 2007 Ian Kent - 5.0.1-0.rc3.9 +- fix another expire regression introduced in the "mitigate manual umount" + patch (bz 222872). + +* Mon Jan 15 2007 Ian Kent - 5.0.1-0.rc3.7 +- ignore "winbind" if it appears in "automount" nsswitch.conf (bz 214632). + +* Wed Jan 10 2007 Ian Kent - 5.0.1-0.rc3.5 +- remove fullstop from Summary tag. +- change Buildroot to recommended form. +- replace Prereq with Requires. + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.3 +- remove redundant rpath link option (prep for move to Extras). + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.1 +- consolidate to rc3. +- fix typo in Fix typo in var when removing temp directory (bz 221847). + +* Wed Dec 27 2006 Ian Kent - 5.0.1-0.rc2.41 +- fix nonstrict multi-mount handling (bz 219383). +- correct detection of duplicate indirect mount entries (bz 220799). + +* Thu Dec 14 2006 Ian Kent - 5.0.1-0.rc2.38 +- update master map tokenizer to admit "slasify-colons" option. +- update location validation to accept "_" (bz 219445). +- set close-on-exec flag on open sockets (bz 215757). + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.35 +- update "replace-tempnam" patch to create temp files in sane location. + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.34 +- change mount "device" from "automount" to the map name. +- check for buffer overflow in mount_afs.c. +- replace tempnam with mkdtemp. + +* Sun Dec 10 2006 Ian Kent - 5.0.1-0.rc2.33 +- expand export access checks to include missing syntax options. +- make "-hosts" module try to be sensitive to exports list changes. + +* Thu Dec 7 2006 Ian Kent - 5.0.1-0.rc2.32 +- remove ability to use multiple indirect mount entries in master + map (bz 218616). + +* Wed Dec 6 2006 Ian Kent - 5.0.1-0.rc2.29 +- alter nfs4 host probing to not use portmap lookup and add options + check for "port=" parameter (bz 208757). +- correct semantics of "-null" map handling (bzs 214800, 208091). + +* Sat Nov 25 2006 Ian Kent - 5.0.1-0.rc2.26 +- fix parsing of bad mount mount point in master map (bz 215620). +- fix use after free memory access in cache.c and lookup_yp.c (bz 208091). +- eliminate use of pthread_kill to detect task completion (bz 208091). + +* Sun Nov 12 2006 Ian Kent - 5.0.1-0.rc2.23 +- fix tokenizer to distinguish between global option and dn string (bz 214684). +- fix incorrect return from spawn. + +* Wed Nov 8 2006 Ian Kent - 5.0.1-0.rc2.21 +- mitigate manual umount of automounts where possible. +- fix multiply recursive bind mounts. +- check kernel module version and require 5.00 or above. +- fix expire regression introduced in the "mitigate manual umount" patch. +- still more on multiply recursive bind mounts. + +* Mon Oct 30 2006 Ian Kent - 5.0.1-0.rc2.20 +- Update patch for changed semantics of mkdir in recent kernels. +- fix macro table locking (bz 208091). +- fix nsswitch parser locking (bz 208091). +- allow only one master map read task at a time. +- fix misc memory leaks. + +* Wed Oct 25 2006 Ian Kent - 5.0.1-0.rc2.19 +- deal with changed semantics of mkdir in recent kernels. + +* Fri Oct 20 2006 Ian Kent - 5.0.1-0.rc2.16 +- fix get_query_dn not looking in subtree for LDAP search (missed + econd occurance). +- allow additional common LDAP attributes in map dn. +- Resolves: rhbz#205997 + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.13 +- fix parsing of numeric host names in LDAP map specs (bz 205997). + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.12 +- fix "-fstype=nfs4" server probing (part 2 of bz 208757). +- set close-on-exec flag on open files where possible (bz 207678). + +* Fri Oct 13 2006 Ian Kent - 5.0.1-0.rc2.11 +- fix file handle leak in nsswitch parser (bz 207678). +- fix memory leak in mount and expire request processing (bz 207678). +- add additional check to prevent running of cancelled tasks. +- fix potential file handle leakage in rpc_subs.c for some failure + cases (bz 207678). +- fix file handle leak in included map lookup (bz 207678). + +* Sat Oct 7 2006 Ian Kent - 5.0.1-0.rc2.10 +- fix get_query_dn not looking in subtree for LDAP search. +- allow syntax "--timeout " for backward compatibility + (bz 193948). +- make masked_match independent of hostname for exports comparison + (bz 209638). + +* Thu Oct 5 2006 Ian Kent - 5.0.1-0.rc2.9 +- fix "-fstype=nfs4" handling (bz 208757). + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.8 +- review and fix master map options update for map reload. + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.7 +- make default installed master map for /net use "-hosts" instead + of auto.net. +- fix included map recursive map key lookup. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.6 +- remove unused option UNDERSCORETODOT from default config files. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.5 +- fix LDAP lookup delete cache entry only if entry doesn't exist. +- add missing socket close in replicated host check (Jeff Moyer). + +* Wed Sep 20 2006 Ian Kent - 5.0.1-0.rc2.4 +- fix cache entrys not being cleaned up on submount expire. + +* Sun Sep 17 2006 Ian Kent - 5.0.1-0.rc2.3 +- fix include check full patch for file map of same name. + +* Wed Sep 13 2006 Ian Kent - 5.0.1-0.rc2.2 +- fix handling of autofs specific mount options (bz 199777). + +* Fri Sep 1 2006 Ian Kent - 5.0.1-0.rc2.1 +- consolidate to rc2. +- fix colon escape handling. +- fix recusively referenced bind automounts. +- update kernel patches. + +* Fri Aug 25 2006 Ian Kent - 5.0.1-0.rc1.17 +- fix task cancelation at shutdown (more) +- fix concurrent mount and expire race with nested submounts. + +* Sun Aug 20 2006 Ian Kent - 5.0.1-0.rc1.16 +- fix included map lookup. +- fix directory cleanup on expire. +- fix task cancelation at shutdown. +- fix included map wild card key lookup. + +* Wed Aug 16 2006 Ian Kent - 5.0.1-0.rc1.15 +- expire individual submounts. +- add ino_index locking. +- fix nested submount expiring away when pwd is base of submount. +- more expire re-work to cope better with shutdown following cthon tests. +- allow hostname to start with numeric when validating. + +* Mon Aug 7 2006 Ian Kent - 5.0.1-0.rc1.14 +- remove SIGCHLD handler because it is no longer needed and was + causing expire problems. +- alter expire locking of multi-mounts to lock sub-tree instead of + entire tree. +- review verbose message feedback and update. +- correction for expire of multi-mounts. +- spelling corrections to release notes (Jeff Moyer). +- add back sloppy mount option, removed for Connectathon testing. +- disable mtab locking again. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.13 +- tidy up directory cleanup and add validation check to rmdir_path. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.12 +- enable mtab locking until I can resolve the race with it. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.11 +- cthon fix expire of wildcard and program mounts broken by recent + patches. + +* Thu Aug 3 2006 Ian Kent - 5.0.1-0.rc1.10 +- cthon corrections for shutdown patch below and fix shutdown expire. + +* Wed Aug 2 2006 Ian Kent - 5.0.1-0.rc1.9 +- cthon fix some shutdown races. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.8 +- Fix compile error. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.7 +- cthon fix expire of various forms of nested mounts. + +* Mon Jul 24 2006 Ian Kent - 5.0.1-0.rc1.6 +- cthon more parser corrections and attempt to fix multi-mounts + with various combinations of submounts (still not right). + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.5 +- Add conflicts kernel < 2.6.17. +- Fix submount operation broken by connectathon updates. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.4 +- Correction to host name validation test for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.3 +- More code cleanup and corrections for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.2 +- Code cleanup and fixes for connectathon tests. + +* Thu Jul 13 2006 Ian Kent - 5.0.1-0.rc1.1 +- Update version label to avoid package update problems. + +* Thu Jul 13 2006 Ian Kent - 5.0.0_beta6-8 +- add cacheing of negative lookups to reduce unneeded map + lookups (bz 197746 part 2). + +* Wed Jul 12 2006 Jesse Keating - 1:5.0.0_beta6-7.1 +- rebuild + +* Tue Jul 11 2006 Ian Kent - 5.0.0_beta6-7 +- correct directory cleanup in mount modules. +- merge key and wildcard LDAP query for lookups (bz 197746). + +* Sat Jul 8 2006 Ian Kent - 5.0.0_beta6-6 +- correct test for libhesiod. + +* Fri Jul 7 2006 Ian Kent - 5.0.0_beta6-5 +- correct auto.net installed as auto.smb. +- update LDAP auth - add autodectect option. + +* Wed Jul 5 2006 Ian Kent - 5.0.0_beta6-4 +- correct shutdown log message print. +- correct auth init test when no credentials required. + +* Tue Jul 4 2006 Ian Kent - 5.0.0_beta6-3 +- correct test for existence of auth config file. + +* Mon Jul 3 2006 Ian Kent - 5.0.0_beta6-2 +- merge LDAP authentication update for GSSAPI (Jeff Moyer). +- update default auth config to add options documenetation (Jeff Moyer). +- workaround segfaults at exit after using GSSAPI library. +- fix not checking return in init_ldap_connection (jeff Moyer). + +* Thu Jun 29 2006 Ian Kent - 5.0.0_beta6-1 +- consolidate to beta6, including: + - mode change update for config file. + - correction to get_query_dn fix from beta5-4. + +* Wed Jun 28 2006 Ian Kent - 5.0.0_beta5-6 +- cleanup defaults_read_config (Jeff Moyer). + +* Tue Jun 27 2006 Ian Kent - 5.0.0_beta5-5 +- allow global macro defines to override system macros. +- correct spelling error in default config files missed by + previous update. +- misc correctness and a memory leak fix. + +* Mon Jun 26 2006 Ian Kent - 5.0.0_beta5-4 +- correct spelling error in default config. +- fix default auth config not being installed. +- change LDAP query method as my test db was incorrect. +- change ldap defaults code to handle missing auth config. +- fix mistake in parsing old style LDAP specs. +- update LDAP so that new query method also works for old syntax. + +* Fri Jun 23 2006 Ian Kent - 5.0.0_beta5-3 +- lookup_init cleanup and fix missed memory leak. +- use nis map order to check if update is needed. +- fix couple of memory leaks in lookup_yp.c. +- fix pasre error in replicated server module. + +* Wed Jun 21 2006 Ian Kent - 5.0.0_beta5-2 +- Add openssl-devel to the BuildRequires, as it is needed for the LDAP + authentication bitsi also. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta5-1 +- promote to beta5. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta4-14 +- fix directory cleanup at exit. + +* Mon Jun 19 2006 Ian Kent - 5.0.0_beta4-13 +- Change LDAP message severity from crit to degug (bz# 183893). +- Corrections to INSTALL and README.v5.release. +- Add patch to fix segv on overlength map keys in file maps (Jeff Moter). +- Add patch to restrict scanning of /proc to pid directories only (Jeff Moyer). + +* Thu Jun 15 2006 Jeff Moyer - 5.0.0_beta4-12 +- Change BuildPrereq to BuildRequires as per the package guidelines. +- Add libxml2-devel to the BuildRequires, as it is needed for the LDAP + authentication bits. + +* Wed Jun 14 2006 Ian Kent - 5.0.0_beta4-11 +- add export access list matching to "hosts" lookup module (bz # 193585). + +* Tue Jun 13 2006 Jeff Moyer - 5.0.0_beta4-10 +- Add a BuildPrereq for cyrus-sasl-devel + +* Tue Jun 13 2006 Ian Kent - 5.0.0_beta4-9 +- move autofs4 module loading back to init script (part bz # 194061). + +* Mon Jun 12 2006 Ian Kent - 5.0.0_beta4-8 +- fix handling of master map entry update (bz # 193718). +- fix program map handling of invalid multi-mount offsets. + +* Sat Jun 10 2006 Ian Kent - 5.0.0_beta4-7 +- fix context init error (introduced by memory leak patch). + +* Fri Jun 9 2006 Ian Kent - 5.0.0_beta4-6 +- add free for working var in get_default_logging. +- add inialisation for kver in autofs_point struct. +- fix sources list corruption in check_update_map_sources. +- fix memory leak in walk_tree. +- fix memory leak in rpc_portmap_getport and rpc_ping_proto. +- fix memory leak in initialisation of lookup modules. + +* Thu Jun 8 2006 Ian Kent - 5.0.0_beta4-5 +- misc fixes for things found while investigating map re-read problem. + +* Wed Jun 7 2006 Ian Kent - 5.0.0_beta4-4 +- check base of offset mount tree is not a mount before umounting + its offsets. +- fix replicated mount parse for case where last name in list + fails lookup. +- correct indirect mount expire broken by the wildcard lookup fix. +- fix up multi-mount handling when wildcard map entry present. + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-3 +- correct config names in default.c (jpro@bas.ac.uk). + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-2 +- re-instate v4 directory cleanup (bz# 193832 again). +- backout master map lookup changes made to beta3. +- change default master map from /etc/auto.master to auto.master + so that we always use nsswitch to locate master map. +- change default installed master map to include "+auto.master" + to pickup NIS master map (all bz# 193831 again). + +* Fri Jun 2 2006 Ian Kent - 5.0.0_beta4-1 +- update to beta4. +- should address at least bzs 193798, 193770, 193831 and + possibly 193832. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-6 +- add back test for nested mount in program map lookup. + - I must have commented this out for a reason. I guess we'll + find out soon enough. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-5 +- fix handling of autofs filesystem mount fail on init. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-4 +- updated hesiod patch. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-3 +- update hesiod module (Jeff Moyer). + - add mutex to protect against overlapping mount requests. + - update return from mount request to give more sensible NSS_* + values. + +* Fri May 26 2006 Jeff Moyer - 1:5.0.0_beta3-2 +- Fix the install permissions for auto.master and auto.misc. + +* Thu May 25 2006 Ian Kent - 5.0.0_beta3-1 +- update source to version 5.0.0_beta3. +- add patch to remove extra debug print. +- add patch to + - fix memory alloc error in nis lookup module. + - add "_" to "." mapname translation to nis lookup module. +- add patch to add owner pid to mount list struct. +- add patch to disable NFSv4 when probing hosts (at least foe now). +- add patch to fix white space handling in replicated server selection code. +- add patch to prevent striping of debug info macro patch (Jeff Moyer). +- add patch to add sanity checks on rmdir_path and unlink (Jeff Moyer). +- add patch to fix e2fsck error code check (Jeff Moyer). + +* Tue May 16 2006 Ian Kent - 1:4.1.4-23 +- add patch to ignore the "bg" and "fg" mount options as they + aren't relevant for autofs mounts (bz #184386). + +* Tue May 2 2006 Ian Kent - 1:4.1.4-20 +- add patch to use "cifs" instead of smbfs and escape speces + in share names (bz #163999, #187732). + +* Tue Apr 11 2006 Ian Kent - 1:4.1.4-18 +- Add patch to allow customization of arguments to the + autofs-ldap-auto-master program (bz #187525). +- Add patch to escap "#" characters in exports from auto.net + program mount (bz#178304). + +* Fri Feb 10 2006 Jesse Keating - 1:4.1.4-16.2.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 1:4.1.4-16.2.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Feb 1 2006 Ian Kent - 1:4.1.4-16.2 +- Add more general patch to translate "_" to "." in map names. (bz #147765) + +* Wed Jan 25 2006 Ian Kent - 1:4.1.4-16.1 +- Add patch to use LDAP_DEPRICATED compile option. (bz #173833) + +* Tue Jan 17 2006 Ian Kent - 1:4.1.4-16 +- Replace check-is-multi with more general multi-parse-fix. +- Add fix for premature return when waiting for lock file. +- Update copyright declaration for reentrant-syslog source. +- Add patch for configure option to disable locking during mount. + But don't disable locking by default. +- Add ability to handle automount schema used in Sun directory server. +- Quell compiler warning about getsockopt parameter. +- Quell compiler warning about yp_order parameter. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Nov 17 2005 Jeff Moyer - 1:4.1.4-14 +- Removed the /misc entry from the default auto.master. auto.misc has + an entry for the cdrom device, and the preferred method of mounting the + cd is via udev/hal. + +* Mon Nov 7 2005 Jeff Moyer - 1:4.1.4-13 +- Changed to sort -k 1, since that should be the same as +0. + +* Thu Nov 3 2005 Jeff Moyer - 1:4.1.4-12 +- The sort command no longer accepts options of the form "+0". This broke + auto.net, so the option was removed. Fixes bz #172111. + +* Wed Oct 26 2005 - 1:4.1.4-11 +- Check the return code of is_local_addr in get_best_mount. (bz #169523) + +* Wed Oct 26 2005 - 1:4.1.4-10 +- Fix some bugs in the parser +- allow -net instead of /etc/auto.net +- Fix a buffer overflow with large key lengths +- Don't allow autofs to unlink files, only to remove directories +- change to the upstream reentrant syslog patch from the band-aid deferred + syslog patch. +- Get rid of the init script patch that hard-coded the release to redhat. + This should be handled properly by all red hat distros. + +* Wed May 4 2005 Jeff Moyer - 1:4.1.4-8 +- Add in the deferred syslog patch. This fixes a hung automounter issue + related to unsafe calls to syslog in signal handler context. + +* Tue May 3 2005 Jeff Moyer - 1:4.1.4-7 +- I reversed the checking for multimount entries, breaking those configs! + This update puts the code back the way it was before I broke it. + +* Tue Apr 26 2005 Jeff Moyer - 1:4.1.4-6 +- Fix a race between mounting a share and updating the cache in the parent + process. If the mount completed first, the parent would not expire the + stale entry, leaving it first on the list. This causes map updates to not + be recognized (well, worse, they are recognized after the first expire, but + not subsequent ones). Fixes a regression, bug #137026 (rhel3 bug). + +* Fri Apr 15 2005 Chris Feist - 1:4.1.4-5 +- Fixed regression with -browse not taking effect. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-4 +- Finish up with the merge breakage. +- Temporary fix for the multimount detection code. It seems half-baked. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-3 +- Fix up the one-auto-master patch. My "improvements" had side-effects. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-2 +- Import 4.1.4 and merge. + +* Mon Apr 4 2005 Jeff Moyer - 1:4.1.3-123 +- Add in an error case that was omitted in the multi-over patch. +- Update our auto.net to reflect the changes that went into 4.1.4_beta2. + This fixes a problem seen by at least one customer where a malformed entry + appeared first in the multimount list, thus causing the entire multimount + to be ignored. This new auto.net places that entry at the end, purely by + luck, but it fixes the problem in this one case. + +* Thu Mar 31 2005 Jeff Moyer - 1:4.1.3-119 +- Merge in the multi-over patch. This resolves an issue whereby multimounts + (such as those used for /net) could be processed in the wrong order, + resulting in directories not showing up in a multimount tree. The fix + is to process these directories in order, shortest to longer path. + +* Wed Mar 23 2005 Chris Feist - 1:4.1.3-115 +- Fixed regression causing any entries after a wildcard in an + indirect map to be ignored. (bz #151668). +- Fixed regression which caused local hosts to be mount instead + of --bind local directories. (bz #146887) + +* Thu Mar 17 2005 Chris Feist - 1:4.1.3-111 +- Fixed one off bug in the submount-variable-propagation patch. + (bz #143074) +- Fixed a bug in the init script which wouldn't find the -browse + option if it was preceded by another option. (fz #113494) + +* Mon Feb 28 2005 Chris Feist - 1:4.1.3-100 +- When using ldap if auto.master doesn't exist we now check for auto_master. + Addresses bz #130079 +- When using an auto.smb map we now remove the leading ':' from the path which + caused mount to fail in the past. Addresses bz #147492 +- Autofs now checks /etc/nsswitch.conf to determine in what order files & nis + are checked when looking up autofs submount maps which don't specify a + maptype. Addresses IT #57612. + +* Mon Feb 14 2005 Jeff Moyer - 1:4.1.3-99 +- Change Copyright to License in the spec file so it will build. + +* Fri Feb 11 2005 Jeff Moyer - 1:4.1.3-98 +- Program maps can repeat the last character of output. Fix this. + Addresses bz #138606 +- Return first entry when there are duplicate keys in a map. Addresses + bz #140108. +- Propagate custom map variables to submounts. Fixes bz #143074. +- Create a sysconfig variable to control whether we source only one master + map (the way sun does), or source all maps found (which is the default for + backwards compatibility). Addresses bz #143126. +- Revised version of the get_best_mount patch. (#146887) cfeist@redhat.com + The previous patch introduced a regression. Non-replicated mounts would + not have the white space stripped from the entry and the mount would fail. +- Handle comment characters in the middle of the automount line in + /etc/nsswitch.conf. Addresses bz #127457. + +* Wed Feb 2 2005 Chris Feist - 1:4.1.3-94 +- Stop automount from pinging hosts if there is only one host (#146887) + +* Wed Feb 2 2005 Jeff Moyer - 1:4.1.3-90 +- Fix potential double free in cache_release. This bug showed up in a + multi-map setup. Two calls to cache_release would result in a SIGSEGV, + and the automount process would never exit. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-82 +- Fixed documentation so users know that any local mounts override + any other weighted mount. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-80 +- Added a variable to determine if we created the directory or not + so we don't accidently remove a directory that we didn't create when + we stop autofs. (bz #134399) + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-76 +- Fix the large program map patch. + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-75 +- Fix some merging breakages that caused the package not to build. + +* Thu Jan 6 2005 - 1:4.1.3-74 +- Add in the map expiry patch +- Bring in other patches that have been committed to other branches. This + version should now contain all fixes we have to date +- Merge conflicts due to map expiry changes + +* Fri Nov 19 2004 Jeff Moyer - 1:4.1.3-57 +- Pass a socket into clntudp_bufcreate so that we don't use up additional + reserved ports. This patch, along with the socket leak fix, addresses + bz #128966. + +* Wed Nov 17 2004 - 1:4.1.3-56 +- Somehow the -browse patch either didn't get committed or got reverted. + Fixed. + +* Tue Nov 16 2004 Jeff Moyer - 1:4.1.3-55 +- Fix program maps so that they can have gt 4k characters. (Neil Horman) + Addresses bz #138994. +- Add a space after the colon here "Starting automounter:" in init script. + Fixes bz #138513. + +* Mon Nov 15 2004 Jeff Moyer - 1:4.1.3-53 +- Make autofs understand -[no]browse. Addresses fz #113494. + +* Thu Nov 11 2004 Jeff Moyer - 1:4.1.3-48 +- Fix the umount loop device function in the init script. + +* Wed Oct 27 2004 Chris Feist - 1:4.1.3-34 +- Added a patch to fix the automounter failing on ldap maps + when it couldn't get the whole map. (ie. when the search + limit was lower than the number of results) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-32 +- Fixed the use of +ypmapname so the maps included with +ypmapname + are used in the correct order. (In the past the '+' entries + were always processed after local entries.) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-31 +- Fixed the duplicate map detection code to detect if maps try + to mount on top of existing maps. + +* Wed Oct 20 2004 Chris Feist - 1:4.1.3-29 +- Fixed a problem with backwards compatability. Specifying local + maps without '/etc/' prepended to them now works. (bz #136038) + +* Fri Oct 15 2004 Chris Feist - 1:4.1.3-28 +- Fixed a bug which caused directories to never be unmounted. (bz #134403) + +* Thu Oct 14 2004 Chris Feist - 1:4.1.3-27 +- Fixed an error in the init script which caused duplicate entries to be + displayed when asking for autofs status. + +* Fri Oct 1 2004 Jeff Moyer - 1:4.1.3-22 +- Comment out map expiry (and related) patch for an FC3 build. + +* Thu Sep 23 2004 Jeff Moyer - 1:4.1.3-21 +- Make local options apply to all maps in a multi-map entry. + +* Tue Sep 21 2004 Jeff Moyer - 1:4.1.3-20 +- Merged my and Ian's socket leak fixes into one, smaller patch. Only + partially addresses bz #128966. +- Fix some more echo lines for internationalization. bz #77820 +- Revert the only one auto.master patch until we implement the +auto_master + syntax. Temporarily addresses bz #133055. + +* Thu Sep 2 2004 Jeff Moyer - 1:4.1.3-18 +- Umount loopback filesystems under automount points when stopping the + automounter. +- Uncomment the map expiry patch. +- change a close to an fclose in lookup_file.c + +* Tue Aug 31 2004 Jeff Moyer - 1:4.1.3-17 +- Add patch to support parsing nsswitch.conf to determine map sources. +- Disable this patch, and Ian's map expiry patch for a FC build. + +* Tue Aug 24 2004 Jeff Moyer - 1:4.1.3-16 +- Version 3 of Ian's map expiry changes. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-15 +- Fix a socket leak in the rpc_subs, causing mounts to fail since we are + running out of port space fairly quickly. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-14 +- New map expiry patch from Ian. +- Fix a couple signal races. No known problem reports of these, but they + are holes, none-the-less. + +* Tue Aug 10 2004 Jeff Moyer - 1:4.1.3-13 +- Only read one auto.master map (instead of concatenating all found sources). +- Uncomment Ian's experimental mount expiry patch. + +* Fri Aug 6 2004 Jeff Moyer - 1:4.1.3-12 +- Add a sysconfig entry to disable direct map support, and set this to + 1 by default. +- Disable the beta map expiry logic so I can build into a stable distro. +- Add defaults for all of the sysconfig variables to the init script so + we don't trip over user errors (i.e. deleting /etc/sysconfig/autofs). + +* Wed Aug 4 2004 Jeff Moyer - 1:4.1.3-11 +- Add beta map expiry code for wider testing. (Ian Kent) +- Fix check for ghosting option. I forgot to check for it in DAEMONOPTIONS. +- Remove STRIPDASH from /etc/sysconfig/autofs + +* Mon Jul 12 2004 Jeff Moyer - 1:4.1.3-10 +- Add bad chdir patch from Ian Kent. +- Add a typo fix for the mtab lock file. +- Nuke the stripdash patch. It didn't solve a problem. + +* Tue Jun 22 2004 Jeff Moyer - 1:4.1.3-9 +- Bump revison for inclusion in RHEL 3. + +* Mon Jun 21 2004 Jeff Moyer - 1:4.1.3-8 +- Change icmp ping to an rpc ping. (Ian Kent) +- Fix i18n patch + o Remove the extra \" from one echo line. + o Use echo -e if we are going to do a \n in the echo string. + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107463 + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107461 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Sat Jun 5 2004 Jeff Moyer - 1:4.1.3-4 +- Perform an icmp ping request before rpc_pings, since the rpc clnt_create + function has a builtin default timeout of 60 seconds. This could result + in a long delay when a server in a replicated mount setup is down. +- For non-replicated server entries, ping a host before attempting to mount. + (Ian Kent) +- Change to %%configure. +- Put version-release into .version to allow for automount --version to + print exact info. +- Nuke my get-best-mount patch which always uses the long timeout. This + should no longer be needed. +- Put name into changelog entries to make them consistent. Add e:n-v-r + into Florian's entry. +- Stop autofs before uninstalling + +* Sat Jun 05 2004 Florian La Roche - 1:4.1.3-3 +- add a preun script to remove autofs + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-2 +- Incorporate patch from Ian which fixes an infinite loop seen by those + running older versions of the kernel patches (triggered by non-strict mounts + being the default). + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-1 +- Update to upstream 4.1.3. + +* Thu May 6 2004 Jeff Moyer - 1:4.1.2-6 +- The lookup_yp module only dealt with YPERR_KEY, all other errors were + treated as success. As a result, if the ypdomain was not bound, the + subprocess that starts mounts would SIGSEGV. This is now fixed. +- Option parsing in the init script was not precise enough, sometimes matching + filesystem options to one of --ghost, --timeout, --verbose, or --debug. + The option-parsing patch addresses this issue by making the regexp's much + more precise. +- Ian has rolled a third version of the replicated mount fixes. + +* Tue May 4 2004 Jeff Moyer - 1:4.1.2-5 +- Ian has a new fix for replicated server and multi-mounts. Updated the + patch for testing. Still beta. (Ian Kent) + +* Mon May 3 2004 Jeff Moyer - 1:4.1.2-4 +- Fix broken multi-mounts. test patch. (Ian Kent) + +* Tue Apr 20 2004 Jeff Moyer - 1:4.1.2-3 +- Fix a call to spawnl which forgot to specify a lock file. (nphilipp) + +* Wed Apr 14 2004 - 1:4.1.2-2 +- Pass --libdir= to ./configure so we get this right on 64 bit platforms that + support backwards compat. + +* Wed Apr 14 2004 Jeff Moyer - 1:4.1.2-1 +- Change hard-coded paths in the spec file to the %%{_xxx} variety. +- Update to upstream 4.1.2. +- Add a STRIPDASH option to /etc/sysconfig/autofs which allows for + compatibility with the Sun automounter options specification syntax in + auto.master. See /etc/sysconfig/autofs for more information. Addresses + bug 113950. + +* Tue Apr 6 2004 Jeff Moyer - 1:4.1.1-6 +- Add the /etc/sysconfig/autofs file, and supporting infrastructure in + the init script. +- Add support for UNDERSCORE_TO_DOT for those who want it. +- We no longer own /net. Move it to the filesystem package. + +* Tue Mar 30 2004 Jeff Moyer - 1:4.1.1-5 +- Clarify documentation on direct maps. +- Send automount daemons a HUP signal during reload. This tells them to + re-read maps (otherwise they use a cached version. Patch from the autofs + maintainer. + +* Mon Mar 22 2004 Jeff Moyer - 1:4.1.1-4 +- Fix init script to print out failures where appropriate. +- Build the automount daemon as a PIE. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-3 +- Fix bug in get_best_mount, whereby if there is only one option, we + choose nothing. This is primarily due to the fact that we pass 0 in to + the get_best_mount function for the long timeout parameter. So, we + timeout trying to contact our first and only server, and never retry. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-2 +- Prevent startup if a mountpoint is already mounted. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-1 +- Update to 4.1.1, as it fixes problems with wildcards that people are + seeing quite a bit. + +* Wed Mar 17 2004 Jeff Moyer - 1:4.1.0-8 +- Fix ldap init code to parse server name and options correctly. + +* Tue Mar 16 2004 Jeff Moyer - 1:4.1.0-7 +- Moved the freeing of ap.path to cleanup_exit, as we would otherwise + reference an already-freed variable. + +* Mon Mar 15 2004 Jeff Moyer - 1:4.1.0-6 +- add %%config(noreplace) for auto.* config files. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-5 +- make the init script only recognize redhat systems. Nalin seems to remember + some arcane build system error that can be caused if we don't do this. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-4 +- comment out /net and /misc from the default auto.master. /net is important + since in a default shipping install, we can neatly co-exist with amd. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-3 +- Ported forward Red Hat's patches from 3.1.7 that were not already present + in 4.1.0. +- Moving autofs from version 3.1.7 to 4.1.0 + +* Mon Sep 29 2003 Ian Kent +- Added work around for O(1) patch oddity. + +* Sat Aug 16 2003 Ian Kent +- Fixed tree mounts. +- Corrected transciption error in autofs4-2.4.18 kernel module + +* Sun Aug 10 2003 Ian Kent +- Checked and merged most of the RedHat v3 patches +- Fixed kernel module handling wu-ftpd login problem (again) + +* Thu Aug 7 2003 Ian Kent +- Removed ineffective lock stuff +- Added -n to bind mount to prevent mtab update error +- Added retry to autofs umount to clean matb after fail +- Redirected messages from above to debug log and added info message +- Fixed autofs4 module reentrancy, pwd and chroot handling + +* Wed Jul 30 2003 Ian Kent +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Fixed autofs directory removal on failure of autofs mount +- Fixed lock file wait function overlapping calls to (u)mount + +* Sun Jul 27 2003 Ian Kent +- Implemented LDAP direct map handling for nisMap and automountMap schema +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Added locking to fix overlapping internal calls to (u)mount +- Added wait for mtab~ to improve tolerance of overlapping external calls to (u)mount +- Fixed ghosted directory removal after failed mount attempt + +* Wed May 28 2003 Ian Kent +- Cleaned up an restructured my added code +- Corrected ghosting problem with 2.4.19 and above +- Added autofs4 ghosting patch for 2.4.19 and above +- Implemented HUP signal to force update of ghosted maps + +* Sat Mar 23 2002 Ian Kent +- Add patch to implement directory ghosting and direct mounts +- Add patch to for autofs4 module to support ghosting + +* Wed Jan 17 2001 Nalin Dahyabhai +- use -fPIC instead of -fpic for modules and honor other RPM_OPT_FLAGS + +* Tue Feb 29 2000 Nalin Dahyabhai +- enable hesiod support over libbind + +* Fri Aug 13 1999 Cristian Gafton +- add patch from rth to avoid an infinite loop