diff --git a/autofs-5.1.7-clear-per-mount-timeout-if-not-set.patch b/autofs-5.1.7-clear-per-mount-timeout-if-not-set.patch new file mode 100644 index 0000000..a821819 --- /dev/null +++ b/autofs-5.1.7-clear-per-mount-timeout-if-not-set.patch @@ -0,0 +1,72 @@ +autofs-5.1.7 - clear per-mount timeout if not set + +From: Ian Kent + +If the per-mount timeout isn't set in the amd map entry clear it so +that updates that remove the setting are seen. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 8 +++++++- + modules/parse_amd.c | 12 ++++++++---- + 3 files changed, 16 insertions(+), 5 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -176,6 +176,7 @@ + - fix remount_active_mount() not remounting symlinks. + - log when setting amd per-mount timeout. + - update per-mount expire timeout on readmap. ++- clear per-mount timeout if not set. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2696,8 +2696,14 @@ void update_mounted_mounts_timeout(struc + goto next; + + /* No per-mount timeout set? */ +- if (!(mnt->amd_flags & AMD_MOUNT_OPT_MASK)) ++ if (!(mnt->amd_flags & AMD_MOUNT_OPT_MASK)) { ++ /* Per-mount timeout setting isn't present, reset to ++ * be sure updates are seen. ++ */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, de[n]->d_name, -1); + goto next; ++ } + + /* The default in autofs is to always expire mounts according to + * a timeout set in the autofs mount super block information +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1720,10 +1720,16 @@ static int amd_mount(struct autofs_point + } + + if (!ret) { +- struct ioctl_ops *ops; ++ struct ioctl_ops *ops = get_ioctl_ops(); + +- if (!(per_mnt_flags & AMD_MOUNT_OPT_MASK)) ++ if (!(per_mnt_flags & AMD_MOUNT_OPT_MASK)) { ++ /* Per-mount timeout setting isn't present, reset to ++ * be sure updates are seen. ++ */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, name, -1); + goto done; ++ } + + /* The mount succeeded, make sure there's no path component + * seperator in "name" as it must be the last component of +@@ -1734,8 +1740,6 @@ static int amd_mount(struct autofs_point + goto done; + } + +- ops = get_ioctl_ops(); +- + /* The default in autofs is to always expire mounts according to + * a timeout set in the autofs mount super block information + * structure. But amd allows for differing expire timeouts on a diff --git a/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch b/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch new file mode 100644 index 0000000..10f8227 --- /dev/null +++ b/autofs-5.1.9-add-some-unimplemented-amd-map-options.patch @@ -0,0 +1,221 @@ +commit 6cbb6e9a3b8b223babf723e0f56cdd7b7eb90455 +Author: Ian Kent +Date: Mon Jul 8 11:04:11 2024 +0800 + + autofs-5.1.9 - add some unimplemented amd map options + + Add handling for amd per-mount options "utimeout", "unmount" and "nounmount" + if the kernel supports it. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + include/mounts.h | 2 ++ + include/parse_amd.h | 6 ++++++ + lib/mounts.c | 4 ++++ + modules/amd_parse.y | 38 +++++++++++++++++++++++++++++++------- + modules/parse_amd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 94 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -171,6 +171,7 @@ + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. ++- add some unimplemented amd map options. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -113,6 +113,8 @@ struct mnt_list { + char *amd_pref; + char *amd_type; + char *amd_opts; ++ unsigned long amd_flags; ++ unsigned int amd_utimeout; + unsigned int amd_cache_opts; + struct list_head amdmount; + +--- autofs-5.1.4.orig/include/parse_amd.h ++++ autofs-5.1.4/include/parse_amd.h +@@ -33,6 +33,11 @@ + #define AMD_MOUNT_TYPE_PROGRAM 0x00004000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + ++#define AMD_MOUNT_OPT_UNMOUNT 0x00010000 ++#define AMD_MOUNT_OPT_NOUNMOUNT 0x00020000 ++#define AMD_MOUNT_OPT_UTIMEOUT 0x00040000 ++#define AMD_MOUNT_OPT_MASK 0x00ff0000 ++ + #define AMD_DEFAULTS_MERGE 0x0001 + #define AMD_DEFAULTS_RESET 0x0002 + #define AMD_DEFAULTS_MASK 0x00ff +@@ -49,6 +54,7 @@ + struct amd_entry { + char *path; + unsigned long flags; ++ unsigned int utimeout; + unsigned int cache_opts; + unsigned int entry_flags; + char *type; +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -1212,6 +1212,8 @@ struct mnt_list *mnts_add_amdmount(struc + this->amd_pref = pref; + this->amd_type = type; + this->amd_opts = opts; ++ this->amd_flags = entry->flags; ++ this->amd_utimeout = entry->utimeout; + this->amd_cache_opts = entry->cache_opts; + this->flags |= MNTS_AMD_MOUNT; + if (list_empty(&this->amdmount)) +@@ -1256,6 +1258,8 @@ static void __mnts_remove_amdmount(const + free(this->amd_opts); + this->amd_opts = NULL; + } ++ this->amd_flags = AMD_MOUNT_OPT_UNMOUNT; ++ this->amd_utimeout = -1; + this->amd_cache_opts = 0; + __mnts_put_mount(this); + } +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -647,8 +647,7 @@ static int match_mnt_option(char *option + { + int ret = 0; + +- if (!strcmp(option, "fullybrowsable") || +- !strcmp(option, "nounmount")) { ++ if (!strcmp(option, "fullybrowsable")) { + sprintf(msg_buf, "option %s is not currently " + "implemented, ignored", option); + amd_info(msg_buf); +@@ -660,15 +659,37 @@ static int match_mnt_option(char *option + sprintf(msg_buf, "option %s is not used by " + "autofs, ignored", option); + amd_info(msg_buf); ++ } else if (!strcmp(option, "umount")) { ++ entry.flags &= ~AMD_MOUNT_OPT_NOUNMOUNT; ++ entry.flags |= AMD_MOUNT_OPT_UNMOUNT; ++ } else if (!strcmp(option, "nounmount")) { ++ if (entry.flags & AMD_MOUNT_TYPE_AUTO) ++ prepend_opt(opts, "timeout=0"); ++ else { ++ entry.flags &= ~AMD_MOUNT_OPT_UNMOUNT; ++ entry.flags |= AMD_MOUNT_OPT_NOUNMOUNT; ++ entry.utimeout = 0; ++ } + } else if (!strncmp(option, "utimeout=", 9)) { ++ /* ++ * amd type "auto" mounts map to autofs fstype=autofs ++ * mounts so a distinct autofs mount is present at the ++ * the root so there's no need for special handling, ++ * just pass the timeout= autofs option. ++ */ + if (entry.flags & AMD_MOUNT_TYPE_AUTO) + prepend_opt(options, ++option); + else { +- sprintf(msg_buf, "umount timeout can't be " +- "used for other than type " +- "\"auto\" with autofs, " +- "ignored"); +- amd_info(msg_buf); ++ if (strchr(option, '=')) { ++ unsigned long tout; ++ int ret; ++ ++ ret = sscanf(option, "utimeout=%lu", &tout); ++ if (ret) { ++ entry.flags |= AMD_MOUNT_OPT_UTIMEOUT; ++ entry.utimeout = tout; ++ } ++ } + } + } else + ret = 1; +@@ -791,6 +812,8 @@ static void local_init_vars(void) + { + memset(&entry, 0, sizeof(entry)); + entry.cache_opts = AMD_CACHE_OPTION_NONE; ++ entry.flags = AMD_MOUNT_OPT_UNMOUNT; ++ entry.utimeout = -1; + memset(opts, 0, sizeof(opts)); + } + +@@ -900,6 +923,7 @@ static int add_location(void) + new->path = entry.path; + } + new->flags = entry.flags; ++ new->utimeout = entry.utimeout; + new->cache_opts = entry.cache_opts; + new->entry_flags = entry.entry_flags; + new->type = entry.type; +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1647,6 +1647,7 @@ static int amd_mount(struct autofs_point + struct parse_context *ctxt) + { + unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK; ++ unsigned long per_mnt_flags = entry->flags & AMD_MOUNT_OPT_MASK; + int ret = 1; + + switch (fstype) { +@@ -1718,6 +1719,55 @@ static int amd_mount(struct autofs_point + break; + } + ++ if (!ret) { ++ struct ioctl_ops *ops; ++ ++ if (!(per_mnt_flags & AMD_MOUNT_OPT_MASK)) ++ goto done; ++ ++ /* The mount succeeded, make sure there's no path component ++ * seperator in "name" as it must be the last component of ++ * the mount point alone for the per-mount options. ++ */ ++ if (strchr(name, '/')) { ++ warn(ap->logopt, "path component seperator not valid here"); ++ goto done; ++ } ++ ++ ops = get_ioctl_ops(); ++ ++ /* The default in autofs is to always expire mounts according to ++ * a timeout set in the autofs mount super block information ++ * structure. But amd allows for differing expire timeouts on a ++ * per-mount basis. It also has (context sensitive) options "unmount" ++ * to say expire this mount and "nounmount" to say don't expire this ++ * mount. In amd mounts these options are set by default according ++ * to whether a mount should expire or not, for example a cd mount ++ * is set "nounmount". Setting defaults like this is not used in the ++ * autofs amd implementation because there's only one, little used, ++ * removable file system available. ++ * ++ * But the "nounmount" and "utimeout" options can be useful. ++ */ ++ if (per_mnt_flags & AMD_MOUNT_OPT_NOUNMOUNT) { ++ if (entry->utimeout) ++ warn(ap->logopt, ++ "non-zero timeout set, possible conflicting options"); ++ ++ /* "nounmount" option, don't expire this mount. */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, name, 0); ++ } else if (per_mnt_flags & AMD_MOUNT_OPT_UTIMEOUT) { ++ if (!entry->utimeout) ++ warn(ap->logopt, ++ "zero timeout set, possible conflicting options"); ++ ++ /* "utimeout" option, expire this mount according to a timeout. */ ++ if (ops) ++ ops->timeout(ap->logopt, ap->ioctlfd, name, entry->utimeout); ++ } ++ } ++done: + return ret; + } + diff --git a/autofs-5.1.9-fix-amd-cache-options-not-copied.patch b/autofs-5.1.9-fix-amd-cache-options-not-copied.patch new file mode 100644 index 0000000..5faea4e --- /dev/null +++ b/autofs-5.1.9-fix-amd-cache-options-not-copied.patch @@ -0,0 +1,36 @@ +commit abf2030556dfe694dc19ed2d73f84f7e5046b660 +Author: Ian Kent +Date: Thu Jul 11 13:56:15 2024 +0800 + + autofs-5.1.9 - fix amd cache options not copied + + The cache options set when parsing the amd map entry are not copied to + the list entry that gets processed by the caller. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + modules/amd_parse.y | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -167,6 +167,7 @@ + - fix always recreate credential cache. + - fix missing unlock in sasl_do_kinit_ext_cc(). + - handle sss special case getautomntbyname() error. ++- fix amd cache options not copied. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -888,6 +888,7 @@ static int add_location(void) + new->path = entry.path; + } + new->flags = entry.flags; ++ new->cache_opts = entry.cache_opts; + new->type = entry.type; + new->map_type = entry.map_type; + new->pref = entry.pref; diff --git a/autofs-5.1.9-fix-incorrect-flags-update-in-update_with_defaults.patch b/autofs-5.1.9-fix-incorrect-flags-update-in-update_with_defaults.patch new file mode 100644 index 0000000..26e0e5e --- /dev/null +++ b/autofs-5.1.9-fix-incorrect-flags-update-in-update_with_defaults.patch @@ -0,0 +1,41 @@ +autofs-5.1.9 - fix incorrect flags update in update_with_defaults() + +From: Ian Kent + +After adding support for some additional am-utils map entry options at +least one of them, "nounmount", and probably others don't work in some +cases. + +This is because some of them are is implemented using a flag in the map +entry which was incorrectly being cleared during updating the entry with +current defaults. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -177,6 +177,7 @@ + - log when setting amd per-mount timeout. + - update per-mount expire timeout on readmap. + - clear per-mount timeout if not set. ++- fix incorrect flags update in update_with_defaults(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -654,7 +654,9 @@ static void update_with_defaults(struct + if (deftype != AMD_MOUNT_TYPE_NONE) + entry->flags |= (defaults->flags & AMD_MOUNT_TYPE_MASK); + else { +- entry->flags = AMD_MOUNT_TYPE_NFS; ++ unsigned long per_mnt_flags = entry->flags & AMD_MOUNT_OPT_MASK; ++ ++ entry->flags = AMD_MOUNT_TYPE_NFS | per_mnt_flags; + tmp = strdup("nfs"); + if (tmp) + entry->type = tmp; diff --git a/autofs-5.1.9-fix-lookup-search-type-in-umount_subtree_mounts.patch b/autofs-5.1.9-fix-lookup-search-type-in-umount_subtree_mounts.patch new file mode 100644 index 0000000..8fd03e2 --- /dev/null +++ b/autofs-5.1.9-fix-lookup-search-type-in-umount_subtree_mounts.patch @@ -0,0 +1,34 @@ +autofs-5.1.9 - fix lookup search type in umount_subtree_mounts() + +From: Ian Kent + +The lookup type used in umount_subtree_mounts() should be LKP_DISTINCT +because we're looking for existing cache entries. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -172,6 +172,7 @@ + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. + - add some unimplemented amd map options. ++- fix lookup search type in umount_subtree_mounts(). + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/automount.c ++++ autofs-5.1.4/daemon/automount.c +@@ -544,7 +544,7 @@ static int umount_subtree_mounts(struct + if (ind_key) + ind_key++; + +- me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); ++ me = lookup_source_mapent(ap, ind_key, LKP_DISTINCT); + } + + if (me) { diff --git a/autofs-5.1.9-fix-remount_active_mount-not-remounting-symlinks.patch b/autofs-5.1.9-fix-remount_active_mount-not-remounting-symlinks.patch new file mode 100644 index 0000000..296e0e7 --- /dev/null +++ b/autofs-5.1.9-fix-remount_active_mount-not-remounting-symlinks.patch @@ -0,0 +1,53 @@ +autofs-5.1.9 - fix remount_active_mount() not remounting symlinks + +From: Ian Kent + +In remount_active_mount() there's a check if the path has an active +mount (ie. covered). This is meant to check if the mount is a direct +mount with an active mount to decide if the file descriptor needs to +be retained or not. + +But this check gets it worng if the path is an indirect mount that +contains symlinks and causes them to not be properly expired after +the re-mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 12 +++++------- + 2 files changed, 6 insertions(+), 7 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -173,6 +173,7 @@ + - refactor amd mount options handling. + - add some unimplemented amd map options. + - fix lookup search type in umount_subtree_mounts(). ++- fix remount_active_mount() not remounting symlinks. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2819,16 +2819,14 @@ static int remount_active_mount(struct a + ops->close(ap->logopt, fd); + return REMOUNT_FAIL; + } +- if (!mounted) { ++ if (!mounted && type != t_indirect) { + /* + * If we're an indirect mount we pass back the fd. +- * But if were a direct or offset mount with no active +- * mount we don't retain an open file descriptor. ++ * But if we're a direct or offset mount with no active ++ * mount we don't retain the open file descriptor. + */ +- if (type != t_indirect) { +- ops->close(ap->logopt, fd); +- *ioctlfd = -1; +- } ++ ops->close(ap->logopt, fd); ++ *ioctlfd = -1; + } else { + /* + * What can I do if we can't remount the existing diff --git a/autofs-5.1.9-log-when-setting-amd-per-mount-timeout.patch b/autofs-5.1.9-log-when-setting-amd-per-mount-timeout.patch new file mode 100644 index 0000000..35f690e --- /dev/null +++ b/autofs-5.1.9-log-when-setting-amd-per-mount-timeout.patch @@ -0,0 +1,51 @@ +autofs-5.1.9 - log when setting amd per-mount timeout + +From: Ian Kent + +Log action when setting amd per-mount expire timeout. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_amd.c | 12 ++++++++++-- + 2 files changed, 11 insertions(+), 2 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -174,6 +174,7 @@ + - add some unimplemented amd map options. + - fix lookup search type in umount_subtree_mounts(). + - fix remount_active_mount() not remounting symlinks. ++- log when setting amd per-mount timeout. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1755,16 +1755,24 @@ static int amd_mount(struct autofs_point + "non-zero timeout set, possible conflicting options"); + + /* "nounmount" option, don't expire this mount. */ +- if (ops) ++ if (ops) { ++ info(ap->logopt, ++ "set amd per-mount expire timeout to 0 for %s", ++ name); + ops->timeout(ap->logopt, ap->ioctlfd, name, 0); ++ } + } else if (per_mnt_flags & AMD_MOUNT_OPT_UTIMEOUT) { + if (!entry->utimeout) + warn(ap->logopt, + "zero timeout set, possible conflicting options"); + + /* "utimeout" option, expire this mount according to a timeout. */ +- if (ops) ++ if (ops) { ++ info(ap->logopt, ++ "set amd per-dentry expire timeout to %d for %s", ++ entry->utimeout, name); + ops->timeout(ap->logopt, ap->ioctlfd, name, entry->utimeout); ++ } + } + } + done: diff --git a/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch b/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch new file mode 100644 index 0000000..75597a2 --- /dev/null +++ b/autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch @@ -0,0 +1,193 @@ +commit 6fdfbcd65fd845e968a68cbdf475a6dd0ee0ee66 +Author: Ian Kent +Date: Tue Jul 9 16:18:19 2024 +0800 + + autofs-5.1.9 - make ioctl ops ->timeout() handle per-dentry expire + + Update the ioctl ops ->timeout() function to handle setting of per-dentry + expire timeout if the kernel supports it. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++--- + daemon/indirect.c | 2 +- + daemon/state.c | 4 ++-- + include/dev-ioctl-lib.h | 2 +- + lib/dev-ioctl-lib.c | 42 +++++++++++++++++++++++++++++++----------- + lib/mounts.c | 4 ++-- + 7 files changed, 41 insertions(+), 20 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -169,6 +169,7 @@ + - handle sss special case getautomntbyname() error. + - fix amd cache options not copied. + - seperate amd mount and entry flags. ++- make iocl ops ->timeout() handle per-dentry expire. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/direct.c ++++ autofs-5.1.4/daemon/direct.c +@@ -328,7 +328,7 @@ int do_mount_autofs_direct(struct autofs + return 0; + } + +- ops->timeout(ap->logopt, ioctlfd, tout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, tout); + + if (save_ioctlfd == -1) + ops->close(ap->logopt, ioctlfd); +@@ -423,7 +423,7 @@ int do_mount_autofs_direct(struct autofs + goto out_umount; + } + +- ops->timeout(ap->logopt, ioctlfd, timeout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, timeout); + notify_mount_result(ap, me->key, timeout, str_direct); + cache_set_ino_index(me->mc, me); + ops->close(ap->logopt, ioctlfd); +@@ -777,7 +777,7 @@ int mount_autofs_offset(struct autofs_po + if (ioctlfd < 0) + goto out_umount; + +- ops->timeout(ap->logopt, ioctlfd, timeout); ++ ops->timeout(ap->logopt, ioctlfd, NULL, timeout); + cache_set_ino_index(me->mc, me); + notify_mount_result(ap, me->key, timeout, str_offset); + ops->close(ap->logopt, ioctlfd); +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -136,7 +136,7 @@ static int do_mount_autofs_indirect(stru + goto out_umount; + } + +- ops->timeout(ap->logopt, ap->ioctlfd, timeout); ++ ops->timeout(ap->logopt, ap->ioctlfd, NULL, timeout); + notify_mount_result(ap, ap->path, timeout, str_indirect); + + return 0; +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -394,7 +394,7 @@ static int do_readmap_mount(struct autof + cache_unlock(vmc); + /* Set timeout and calculate the expire run frequency */ + timeout = get_exp_timeout(ap, map); +- ops->timeout(ap->logopt, valid->ioctlfd, timeout); ++ ops->timeout(ap->logopt, valid->ioctlfd, NULL, timeout); + if (timeout) { + runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + if (ap->exp_runfreq) +@@ -455,7 +455,7 @@ static void *do_readmap(void *arg) + struct ioctl_ops *ops = get_ioctl_ops(); + time_t timeout = get_exp_timeout(ap, ap->entry->maps); + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; +- ops->timeout(ap->logopt, ap->ioctlfd, timeout); ++ ops->timeout(ap->logopt, ap->ioctlfd, NULL, timeout); + lookup_prune_cache(ap, now); + status = lookup_ghost(ap); + } else { +--- autofs-5.1.4.orig/include/dev-ioctl-lib.h ++++ autofs-5.1.4/include/dev-ioctl-lib.h +@@ -45,7 +45,7 @@ struct ioctl_ops { + int (*send_fail)(unsigned int, int, unsigned int, int); + int (*setpipefd)(unsigned int, int, int); + int (*catatonic)(unsigned int, int); +- int (*timeout)(unsigned int, int, time_t); ++ int (*timeout)(unsigned int, int, const char *, time_t); + int (*requester)(unsigned int, int, const char *, uid_t *, gid_t *); + int (*expire)(unsigned int, int, const char *, unsigned int); + int (*askumount)(unsigned int, int, unsigned int *); +--- autofs-5.1.4.orig/lib/dev-ioctl-lib.c ++++ autofs-5.1.4/lib/dev-ioctl-lib.c +@@ -55,7 +55,7 @@ static int dev_ioctl_send_ready(unsigned + static int dev_ioctl_send_fail(unsigned int, int, unsigned int, int); + static int dev_ioctl_setpipefd(unsigned int, int, int); + static int dev_ioctl_catatonic(unsigned int, int); +-static int dev_ioctl_timeout(unsigned int, int, time_t); ++static int dev_ioctl_timeout(unsigned int, int, const char *, time_t); + static int dev_ioctl_requester(unsigned int, int, const char *, uid_t *, gid_t *); + static int dev_ioctl_expire(unsigned int, int, const char *, unsigned int); + static int dev_ioctl_askumount(unsigned int, int, unsigned int *); +@@ -69,7 +69,7 @@ static int ioctl_close(unsigned int, int + static int ioctl_send_ready(unsigned int, int, unsigned int); + static int ioctl_send_fail(unsigned int, int, unsigned int, int); + static int ioctl_catatonic(unsigned int, int); +-static int ioctl_timeout(unsigned int, int, time_t); ++static int ioctl_timeout(unsigned int, int, const char *, time_t); + static int ioctl_expire(unsigned int, int, const char *, unsigned int); + static int ioctl_askumount(unsigned int, int, unsigned int *); + +@@ -579,21 +579,41 @@ static int ioctl_catatonic(unsigned int + } + + /* Set the autofs mount timeout */ +-static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout) ++static int dev_ioctl_timeout(unsigned int logopt, int ioctlfd, const char *mp, time_t timeout) + { +- struct autofs_dev_ioctl param; +- +- init_autofs_dev_ioctl(¶m); +- param.ioctlfd = ioctlfd; +- param.timeout.timeout = timeout; ++ if (!mp) { ++ struct autofs_dev_ioctl param; + +- if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -1) +- return -1; ++ init_autofs_dev_ioctl(¶m); ++ param.ioctlfd = ioctlfd; ++ param.timeout.timeout = timeout; ++ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) == -1) ++ return -1; ++ } else { ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); ++ struct autofs_dev_ioctl *param; ++ ++ if (kver_major < 5 || ++ (kver_major == 5 && kver_minor < 6)) { ++ error(logopt, "per-mount expire timeout not supported by kernel."); ++ return -1; ++ } + ++ param = alloc_dev_ioctl_path(ioctlfd, mp); ++ if (!param) ++ return -1; ++ param->timeout.timeout = timeout; ++ if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_TIMEOUT, param) == -1) { ++ free_dev_ioctl_path(param); ++ return -1; ++ } ++ free_dev_ioctl_path(param); ++ } + return 0; + } + +-static int ioctl_timeout(unsigned int logopt, int ioctlfd, time_t timeout) ++static int ioctl_timeout(unsigned int logopt, int ioctlfd, const char *mp, time_t timeout) + { + time_t tout = timeout; + return ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &tout); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2759,7 +2759,7 @@ static int remount_active_mount(struct a + /* Re-reading the map, set timeout and return */ + if (ap->state == ST_READMAP) { + debug(ap->logopt, "already mounted, update timeout"); +- ops->timeout(ap->logopt, fd, timeout); ++ ops->timeout(ap->logopt, fd, NULL, timeout); + ops->close(ap->logopt, fd); + return REMOUNT_READ_MAP; + } +@@ -2781,7 +2781,7 @@ static int remount_active_mount(struct a + ops->close(ap->logopt, fd); + return REMOUNT_OPEN_FAIL; + } +- ops->timeout(ap->logopt, fd, timeout); ++ ops->timeout(ap->logopt, fd, NULL, timeout); + if (fstat(fd, &st) == -1) { + error(ap->logopt, + "failed to stat %s mount %s", str_type, path); diff --git a/autofs-5.1.9-refactor-amd-mount-options-handling.patch b/autofs-5.1.9-refactor-amd-mount-options-handling.patch new file mode 100644 index 0000000..760038d --- /dev/null +++ b/autofs-5.1.9-refactor-amd-mount-options-handling.patch @@ -0,0 +1,121 @@ +commit b48aab92dd3f47411a8ccd67ff4370cbfee64581 +Author: Ian Kent +Date: Thu Jul 11 13:35:04 2024 +0800 + + autofs-5.1.9 - refactor amd mount options handling + + Refactor handling of entry options opts, addopts, remopts. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + modules/amd_parse.y | 66 ++++++++++++++++++++++++++++++---------------------- + 2 files changed, 40 insertions(+), 27 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -170,6 +170,7 @@ + - fix amd cache options not copied. + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. ++- refactor amd mount options handling. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -60,6 +60,7 @@ static int match_map_option_fs_type(char + static int match_map_option_map_type(char *map_option, char *type); + static int match_map_option_cache_option(char *type); + static int match_mnt_option_options(char *mnt_option, char *options); ++static int match_mnt_option(char *option, char *options); + + static struct amd_entry entry; + static struct list_head *entries; +@@ -437,40 +438,18 @@ option_assignment: MAP_OPTION OPTION_ASS + + options: OPTION + { +- if (!strcmp($1, "fullybrowsable") || +- !strcmp($1, "nounmount")) { +- sprintf(msg_buf, "option %s is not currently " +- "implemented, ignored", $1); +- amd_info(msg_buf); +- } else if (!strncmp($1, "ping=", 5) || +- !strncmp($1, "retry=", 6) || +- !strcmp($1, "public") || +- !strcmp($1, "softlookup") || +- !strcmp($1, "xlatecookie")) { +- sprintf(msg_buf, "option %s is not used by " +- "autofs, ignored", $1); +- amd_info(msg_buf); +- } else if (!strncmp($1, "utimeout=", 9)) { +- if (entry.flags & AMD_MOUNT_TYPE_AUTO) { +- char *opt = $1; +- prepend_opt(opts, ++opt); +- } else { +- sprintf(msg_buf, "umount timeout can't be " +- "used for other than type " +- "\"auto\" with autofs, " +- "ignored"); +- amd_info(msg_buf); +- } +- } else ++ if (match_mnt_option($1, opts)) + prepend_opt(opts, $1); + } + | OPTION COMMA options + { +- prepend_opt(opts, $1); ++ if (match_mnt_option($1, opts)) ++ prepend_opt(opts, $1); + } + | OPTION COMMA + { +- prepend_opt(opts, $1); ++ if (match_mnt_option($1, opts)) ++ prepend_opt(opts, $1); + } + ; + +@@ -664,6 +643,39 @@ static int match_mnt_option_options(char + return 1; + } + ++static int match_mnt_option(char *option, char *options) ++{ ++ int ret = 0; ++ ++ if (!strcmp(option, "fullybrowsable") || ++ !strcmp(option, "nounmount")) { ++ sprintf(msg_buf, "option %s is not currently " ++ "implemented, ignored", option); ++ amd_info(msg_buf); ++ } else if (!strncmp(option, "ping=", 5) || ++ !strncmp(option, "retry=", 6) || ++ !strcmp(option, "public") || ++ !strcmp(option, "softlookup") || ++ !strcmp(option, "xlatecookie")) { ++ sprintf(msg_buf, "option %s is not used by " ++ "autofs, ignored", option); ++ amd_info(msg_buf); ++ } else if (!strncmp(option, "utimeout=", 9)) { ++ if (entry.flags & AMD_MOUNT_TYPE_AUTO) ++ prepend_opt(options, ++option); ++ else { ++ sprintf(msg_buf, "umount timeout can't be " ++ "used for other than type " ++ "\"auto\" with autofs, " ++ "ignored"); ++ amd_info(msg_buf); ++ } ++ } else ++ ret = 1; ++ ++ return ret; ++} ++ + static void prepend_opt(char *dest, char *opt) + { + char new[MAX_OPTS_LEN]; diff --git a/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch b/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch new file mode 100644 index 0000000..45d7d9c --- /dev/null +++ b/autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch @@ -0,0 +1,133 @@ +commit a2002247e16ef60efe049e04119a9c92694cbfe1 +Author: Ian Kent +Date: Tue Jul 9 14:59:40 2024 +0800 + + autofs-5.1.9 - seperate amd mount and entry flags + + We are running out of flags for amd mounts, seperate the mount flags + from the defaults and entry flags and add a new amd entry flags field. + + Signed-off-by: Ian Kent + +--- + CHANGELOG | 1 + + include/parse_amd.h | 11 ++++++----- + modules/amd_parse.y | 7 ++++--- + modules/parse_amd.c | 10 +++++----- + 4 files changed, 16 insertions(+), 13 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -168,6 +168,7 @@ + - fix missing unlock in sasl_do_kinit_ext_cc(). + - handle sss special case getautomntbyname() error. + - fix amd cache options not copied. ++- seperate amd mount and entry flags. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/include/parse_amd.h ++++ autofs-5.1.4/include/parse_amd.h +@@ -33,12 +33,12 @@ + #define AMD_MOUNT_TYPE_PROGRAM 0x00004000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + +-#define AMD_ENTRY_CUT 0x00010000 +-#define AMD_ENTRY_MASK 0x00ff0000 ++#define AMD_DEFAULTS_MERGE 0x0001 ++#define AMD_DEFAULTS_RESET 0x0002 ++#define AMD_DEFAULTS_MASK 0x00ff + +-#define AMD_DEFAULTS_MERGE 0x01000000 +-#define AMD_DEFAULTS_RESET 0x02000000 +-#define AMD_DEFAULTS_MASK 0xff000000 ++#define AMD_ENTRY_CUT 0x0100 ++#define AMD_ENTRY_MASK 0xff00 + + #define AMD_CACHE_OPTION_NONE 0x0000 + #define AMD_CACHE_OPTION_INC 0x0001 +@@ -50,6 +50,7 @@ struct amd_entry { + char *path; + unsigned long flags; + unsigned int cache_opts; ++ unsigned int entry_flags; + char *type; + char *map_type; + char *pref; +--- autofs-5.1.4.orig/modules/amd_parse.y ++++ autofs-5.1.4/modules/amd_parse.y +@@ -155,7 +155,7 @@ location_selection_list: location + } + | location_selection_list SPACE CUT SPACE location + { +- entry.flags |= AMD_ENTRY_CUT; ++ entry.entry_flags |= AMD_ENTRY_CUT; + if (!add_location()) { + amd_msg("failed to allocate new location"); + YYABORT; +@@ -168,11 +168,11 @@ location: location_entry + } + | HYPHEN location_entry + { +- entry.flags |= AMD_DEFAULTS_MERGE; ++ entry.entry_flags |= AMD_DEFAULTS_MERGE; + } + | HYPHEN + { +- entry.flags |= AMD_DEFAULTS_RESET; ++ entry.entry_flags |= AMD_DEFAULTS_RESET; + } + ; + +@@ -889,6 +889,7 @@ static int add_location(void) + } + new->flags = entry.flags; + new->cache_opts = entry.cache_opts; ++ new->entry_flags = entry.entry_flags; + new->type = entry.type; + new->map_type = entry.map_type; + new->pref = entry.pref; +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -2022,13 +2022,13 @@ static struct amd_entry *select_default_ + + p = p->next; + +- if (this->flags & AMD_DEFAULTS_MERGE) { ++ if (this->entry_flags & AMD_DEFAULTS_MERGE) { + if (entry_default) + free_amd_entry(entry_default); + list_del_init(&this->list); + entry_default = this; + continue; +- } else if (this->flags & AMD_DEFAULTS_RESET) { ++ } else if (this->entry_flags & AMD_DEFAULTS_RESET) { + struct amd_entry *new; + new = dup_defaults_entry(defaults_entry); + if (new) { +@@ -2259,14 +2259,14 @@ int parse_mount(struct autofs_point *ap, + struct amd_entry *this = list_entry(p, struct amd_entry, list); + p = p->next; + +- if (this->flags & AMD_DEFAULTS_MERGE) { ++ if (this->entry_flags & AMD_DEFAULTS_MERGE) { + free_amd_entry(cur_defaults); + list_del_init(&this->list); + cur_defaults = this; + update_with_defaults(defaults_entry, cur_defaults, sv); + debug(ap->logopt, "merged /defaults entry with defaults"); + continue; +- } else if (this->flags & AMD_DEFAULTS_RESET) { ++ } else if (this->entry_flags & AMD_DEFAULTS_RESET) { + struct amd_entry *nd, *new; + struct substvar *nsv = NULL; + +@@ -2291,7 +2291,7 @@ int parse_mount(struct autofs_point *ap, + debug(ap->logopt, "expand defaults entry"); + sv = expand_entry(ap, cur_defaults, flags, sv); + +- if (this->flags & AMD_ENTRY_CUT && at_least_one) { ++ if (this->entry_flags & AMD_ENTRY_CUT && at_least_one) { + info(ap->logopt, MODPREFIX + "at least one entry tried before cut selector, " + "not continuing"); diff --git a/autofs-5.1.9-skip-expire-check-for-amd-nounmount-mounts.patch b/autofs-5.1.9-skip-expire-check-for-amd-nounmount-mounts.patch new file mode 100644 index 0000000..9c78257 --- /dev/null +++ b/autofs-5.1.9-skip-expire-check-for-amd-nounmount-mounts.patch @@ -0,0 +1,36 @@ +autofs-5.1.9 - skip expire check for amd nounmount mounts + +From: Ian Kent + +There's no need to check amd mounts with the "nounmount" option set. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/indirect.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -178,6 +178,7 @@ + - update per-mount expire timeout on readmap. + - clear per-mount timeout if not set. + - fix incorrect flags update in update_with_defaults(). ++- skip expire check for amd nounmount mounts. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/indirect.c ++++ autofs-5.1.4/daemon/indirect.c +@@ -377,6 +377,11 @@ void *expire_proc_indirect(void *arg) + char *ind_key; + int ret; + ++ /* No need to check "nounmount" amd mounts */ ++ if (mnt->flags & MNTS_AMD_MOUNT && ++ mnt->amd_flags & AMD_MOUNT_OPT_NOUNMOUNT) ++ continue; ++ + if (mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET)) { + /* + * If we have submounts check if this path lives below diff --git a/autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch b/autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch new file mode 100644 index 0000000..fca7abf --- /dev/null +++ b/autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch @@ -0,0 +1,225 @@ +autofs-5.1.9 - update per-mount expire timeout on readmap + +From: Ian Kent + +Ensure read map requests are propagated to child submounts and update +the amd per-mount timeout. + +Also update the logging text to remove the use of the word dentry as +it might not make sense to users. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/master.c | 2 + daemon/state.c | 1 + include/master.h | 1 + include/mounts.h | 1 + lib/mounts.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + modules/parse_amd.c | 6 +- + 7 files changed, 130 insertions(+), 4 deletions(-) + +--- autofs-5.1.4.orig/CHANGELOG ++++ autofs-5.1.4/CHANGELOG +@@ -175,6 +175,7 @@ + - fix lookup search type in umount_subtree_mounts(). + - fix remount_active_mount() not remounting symlinks. + - log when setting amd per-mount timeout. ++- update per-mount expire timeout on readmap. + + xx/xx/2018 autofs-5.1.5 + - fix flag file permission. +--- autofs-5.1.4.orig/daemon/master.c ++++ autofs-5.1.4/daemon/master.c +@@ -1378,7 +1378,7 @@ static int master_do_mount(struct master + return 1; + } + +-static void check_update_map_sources(struct master_mapent *entry, int readall) ++void check_update_map_sources(struct master_mapent *entry, int readall) + { + struct map_source *source, *last; + struct autofs_point *ap; +--- autofs-5.1.4.orig/daemon/state.c ++++ autofs-5.1.4/daemon/state.c +@@ -456,6 +456,7 @@ static void *do_readmap(void *arg) + time_t timeout = get_exp_timeout(ap, ap->entry->maps); + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + ops->timeout(ap->logopt, ap->ioctlfd, NULL, timeout); ++ update_mounted_mounts_timeout(ap, ap->path); + lookup_prune_cache(ap, now); + status = lookup_ghost(ap); + } else { +--- autofs-5.1.4.orig/include/master.h ++++ autofs-5.1.4/include/master.h +@@ -115,6 +115,7 @@ struct master *master_new(const char *, + int master_read_master(struct master *, time_t); + int master_notify_submount(struct autofs_point *, const char *path, enum states); + void master_notify_state_change(struct master *, int); ++void check_update_map_sources(struct master_mapent *, int); + int master_mount_mounts(struct master *, time_t); + int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); +--- autofs-5.1.4.orig/include/mounts.h ++++ autofs-5.1.4/include/mounts.h +@@ -197,6 +197,7 @@ const char *mount_type_str(unsigned int) + void set_exp_timeout(struct autofs_point *ap, struct map_source *source, time_t timeout); + time_t get_exp_timeout(struct autofs_point *ap, struct map_source *source); + void notify_mount_result(struct autofs_point *, const char *, time_t, const char *); ++void update_mounted_mounts_timeout(struct autofs_point *, const char *); + int try_remount(struct autofs_point *, struct mapent *, unsigned int); + void set_indirect_mount_tree_catatonic(struct autofs_point *); + void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); +--- autofs-5.1.4.orig/lib/mounts.c ++++ autofs-5.1.4/lib/mounts.c +@@ -2622,6 +2622,128 @@ void notify_mount_result(struct autofs_p + return; + } + ++void update_mounted_mounts_timeout(struct autofs_point *ap, const char *path) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ struct dirent **de; ++ char buf[PATH_MAX + 1]; ++ int n, size; ++ ++ n = scandir(path, &de, 0, alphasort); ++ if (n < 0) ++ return; ++ ++ size = sizeof(buf); ++ ++ while (n--) { ++ unsigned int mounted = 0; ++ struct mnt_list *mnt; ++ int ret; ++ ++ if (strcmp(de[n]->d_name, ".") == 0 || ++ strcmp(de[n]->d_name, "..") == 0) { ++ free(de[n]); ++ continue; ++ } ++ ++ ret = cat_path(buf, size, path, de[n]->d_name); ++ if (!ret) { ++ do { ++ free(de[n]); ++ } while (n--); ++ free(de); ++ return; ++ } ++ ++ ops->ismountpoint(ap->logopt, -1, buf, &mounted); ++ if (!mounted) { ++ struct dirent **de2; ++ int i, j; ++ ++ i = j = scandir(buf, &de2, 0, alphasort); ++ if (i < 0) { ++ free(de[n]); ++ continue; ++ } ++ while (i--) ++ free(de2[i]); ++ free(de2); ++ if (j <= 2) { ++ free(de[n]); ++ continue; ++ } ++ } ++ ++ /* For submounts we need to propogate the read map ++ * request. ++ */ ++ mnt = mnts_find_submount(buf); ++ if (mnt) { ++ check_update_map_sources(mnt->ap->entry, 1); ++ mnts_put_mount(mnt); ++ } ++ ++ mnt = mnts_find_amdmount(buf); ++ if (!mnt) { ++ free(de[n]); ++ continue; ++ } ++ ++ /* For amd type auto mounts the timeout is the per-mount ++ * timeout. ++ */ ++ if (mnt->amd_flags & AMD_MOUNT_TYPE_AUTO) ++ goto next; ++ ++ /* No per-mount timeout set? */ ++ if (!(mnt->amd_flags & AMD_MOUNT_OPT_MASK)) ++ goto next; ++ ++ /* The default in autofs is to always expire mounts according to ++ * a timeout set in the autofs mount super block information ++ * structure. But amd allows for differing expire timeouts on a ++ * per-mount basis. It also has (context sensitive) options "unmount" ++ * to say expire this mount and "nounmount" to say don't expire this ++ * mount. In amd mounts these options are set by default according ++ * to whether a mount should expire or not, for example a cd mount ++ * is set "nounmount". Setting defaults like this is not used in the ++ * autofs amd implementation because there's only one, little used, ++ * removable file system available. ++ * ++ * But the "nounmount" and "utimeout" options can be useful. ++ */ ++ if (mnt->amd_flags & AMD_MOUNT_OPT_NOUNMOUNT) { ++ if (mnt->amd_utimeout) ++ warn(ap->logopt, ++ "non-zero timeout set, possible conflicting options"); ++ ++ /* "nounmount" option, don't expire this mount. */ ++ if (ops) { ++ info(ap->logopt, ++ "set amd per-mount expire timeout to 0 for %s", ++ buf); ++ ops->timeout(ap->logopt, ap->ioctlfd, de[n]->d_name, 0); ++ } ++ } else if (mnt->amd_flags & AMD_MOUNT_OPT_UTIMEOUT) { ++ if (!mnt->amd_utimeout) ++ warn(ap->logopt, ++ "zero timeout set, possible conflicting options"); ++ ++ /* "utimeout" option, expire this mount according to a timeout. */ ++ if (ops) { ++ info(ap->logopt, ++ "set amd per-mount expire timeout to %d for %s", ++ mnt->amd_utimeout, buf); ++ ops->timeout(ap->logopt, ap->ioctlfd, de[n]->d_name, mnt->amd_utimeout); ++ } ++ } ++next: ++ mnts_put_mount(mnt); ++ free(de[n]); ++ } ++ free(de); ++} ++ + static int do_remount_direct(struct autofs_point *ap, + const unsigned int type, int fd, const char *path) + { +--- autofs-5.1.4.orig/modules/parse_amd.c ++++ autofs-5.1.4/modules/parse_amd.c +@@ -1758,7 +1758,7 @@ static int amd_mount(struct autofs_point + if (ops) { + info(ap->logopt, + "set amd per-mount expire timeout to 0 for %s", +- name); ++ entry->path); + ops->timeout(ap->logopt, ap->ioctlfd, name, 0); + } + } else if (per_mnt_flags & AMD_MOUNT_OPT_UTIMEOUT) { +@@ -1769,8 +1769,8 @@ static int amd_mount(struct autofs_point + /* "utimeout" option, expire this mount according to a timeout. */ + if (ops) { + info(ap->logopt, +- "set amd per-dentry expire timeout to %d for %s", +- entry->utimeout, name); ++ "set amd per-mount expire timeout to %d for %s", ++ entry->utimeout, entry->path); + ops->timeout(ap->logopt, ap->ioctlfd, name, entry->utimeout); + } + } diff --git a/autofs.spec b/autofs.spec index 2e2d114..e03bbc9 100644 --- a/autofs.spec +++ b/autofs.spec @@ -8,7 +8,7 @@ Summary: A tool for automatically mounting and unmounting filesystems Name: autofs Version: 5.1.4 -Release: 114%{?dist}.6 +Release: 114%{?dist}.7 Epoch: 1 License: GPLv2+ Group: System Environment/Daemons @@ -356,6 +356,20 @@ Patch343: autofs-5.1.8-fix-missing-unlock-in-sasl_do_kinit_ext_cc.patch # JIRA: RHEL-127179 Patch344: autofs-5.1.9-handle-sss-special-case-getautomntbyname-error.patch +# JIRA: RHEL-46409 +Patch350: autofs-5.1.9-fix-amd-cache-options-not-copied.patch +Patch351: autofs-5.1.9-seperate-amd-mount-and-entry-flags.patch +Patch352: autofs-5.1.9-make-ioctl-ops-timeout-handle-per-dentry-expire.patch +Patch353: autofs-5.1.9-refactor-amd-mount-options-handling.patch +Patch354: autofs-5.1.9-add-some-unimplemented-amd-map-options.patch +Patch355: autofs-5.1.9-fix-lookup-search-type-in-umount_subtree_mounts.patch +Patch356: autofs-5.1.9-fix-remount_active_mount-not-remounting-symlinks.patch +Patch357: autofs-5.1.9-log-when-setting-amd-per-mount-timeout.patch +Patch358: autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch +Patch359: autofs-5.1.7-clear-per-mount-timeout-if-not-set.patch +Patch360: autofs-5.1.9-fix-incorrect-flags-update-in-update_with_defaults.patch +Patch361: autofs-5.1.9-skip-expire-check-for-amd-nounmount-mounts.patch + %if %{with_systemd} BuildRequires: systemd-units BuildRequires: systemd-devel @@ -749,6 +763,19 @@ echo %{version}-%{release} > .version %patch -P 344 -p1 +%patch -P 350 -p1 +%patch -P 351 -p1 +%patch -P 352 -p1 +%patch -P 353 -p1 +%patch -P 354 -p1 +%patch -P 355 -p1 +%patch -P 356 -p1 +%patch -P 357 -p1 +%patch -P 358 -p1 +%patch -P 359 -p1 +%patch -P 360 -p1 +%patch -P 361 -p1 + %build LDFLAGS=-Wl,-z,now %configure --disable-mount-locking --enable-ignore-busy --with-libtirpc --without-hesiod %{?systemd_configure_arg:} @@ -843,6 +870,22 @@ fi %dir /etc/auto.master.d %changelog +* Fri Jan 30 2026 Ian Kent - 5.1.4-114.el8_10.7 +- RHEL-46409 - RFE: autofs: add handling for AMD 'nounmount' option + - fix amd cache options not copied. + - seperate amd mount and entry flags. + - make iocl ops ->timeout() handle per-dentry expire. + - refactor amd mount options handling. + - add some unimplemented amd map options. + - fix lookup search type in umount_subtree_mounts(). + - fix remount_active_mount() not remounting symlinks. + - log when setting amd per-mount timeout. + - update per-mount expire timeout on readmap. + - clear per-mount timeout if not set. + - fix incorrect flags update in update_with_defaults(). + - skip expire check for amd nounmount mounts. +- Resolves: RHEL-46409 + * Tue Nov 25 2025 Ian Kent - 5.1.4-114.el8_10.6 - RHEL-127179 - sssd autofs fails to get correct EHOSTDOWN if requested incorrect mount after upgrade to sssd-2.9.1-4.el8_9.5.x86_64