- amd option 'nounmount' (and related options) updates and fixes (RHEL-150238).

This commit is contained in:
Ian Kent 2026-03-17 10:00:58 +08:00
parent 0db5bfbdba
commit 0bcbc9ee96
8 changed files with 533 additions and 1 deletions

View File

@ -0,0 +1,72 @@
autofs-5.1.7 - clear per-mount timeout if not set
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 +++++++-
modules/parse_amd.c | 12 ++++++++----
3 files changed, 16 insertions(+), 5 deletions(-)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -26,6 +26,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.
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/lib/mounts.c
+++ autofs-5.1.9/lib/mounts.c
@@ -2684,8 +2684,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.9.orig/modules/parse_amd.c
+++ autofs-5.1.9/modules/parse_amd.c
@@ -1727,10 +1727,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
@@ -1741,8 +1747,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

View File

@ -0,0 +1,41 @@
autofs-5.1.9 - fix incorrect flags update in update_with_defaults()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -27,6 +27,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().
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/modules/parse_amd.c
+++ autofs-5.1.9/modules/parse_amd.c
@@ -661,7 +661,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;

View File

@ -0,0 +1,34 @@
autofs-5.1.9 - fix lookup search type in umount_subtree_mounts()
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -22,6 +22,7 @@
- fix lock ordering deadlock in expire_cleanup().
- fix handling of ignored offsets.
- fix invalidated map entry handling in hosts module.
+- fix lookup search type in umount_subtree_mounts().
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/daemon/automount.c
+++ autofs-5.1.9/daemon/automount.c
@@ -558,7 +558,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) {

View File

@ -0,0 +1,53 @@
autofs-5.1.9 - fix remount_active_mount() not remounting symlinks
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 12 +++++-------
2 files changed, 6 insertions(+), 7 deletions(-)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -23,6 +23,7 @@
- fix handling of ignored offsets.
- fix invalidated map entry handling in hosts module.
- fix lookup search type in umount_subtree_mounts().
+- fix remount_active_mount() not remounting symlinks.
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/lib/mounts.c
+++ autofs-5.1.9/lib/mounts.c
@@ -2807,16 +2807,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

View File

@ -0,0 +1,51 @@
autofs-5.1.9 - log when setting amd per-mount timeout
From: Ian Kent <raven@themaw.net>
Log action when setting amd per-mount expire timeout.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 12 ++++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -24,6 +24,7 @@
- fix invalidated map entry handling in hosts module.
- fix lookup search type in umount_subtree_mounts().
- fix remount_active_mount() not remounting symlinks.
+- log when setting amd per-mount timeout.
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/modules/parse_amd.c
+++ autofs-5.1.9/modules/parse_amd.c
@@ -1762,16 +1762,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:

View File

@ -0,0 +1,36 @@
autofs-5.1.9 - skip expire check for amd nounmount mounts
From: Ian Kent <raven@themaw.net>
There's no need to check amd mounts with the "nounmount" option set.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/indirect.c | 5 +++++
2 files changed, 6 insertions(+)
--- autofs-5.1.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -28,6 +28,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.
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/daemon/indirect.c
+++ autofs-5.1.9/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

View File

@ -0,0 +1,225 @@
autofs-5.1.9 - update per-mount expire timeout on readmap
From: Ian Kent <raven@themaw.net>
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 <raven@themaw.net>
---
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.9.orig/CHANGELOG
+++ autofs-5.1.9/CHANGELOG
@@ -25,6 +25,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.
02/11/2023 autofs-5.1.9
- fix kernel mount status notification.
--- autofs-5.1.9.orig/daemon/master.c
+++ autofs-5.1.9/daemon/master.c
@@ -1387,7 +1387,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.9.orig/daemon/state.c
+++ autofs-5.1.9/daemon/state.c
@@ -436,6 +436,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.9.orig/include/master.h
+++ autofs-5.1.9/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.9.orig/include/mounts.h
+++ autofs-5.1.9/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.9.orig/lib/mounts.c
+++ autofs-5.1.9/lib/mounts.c
@@ -2610,6 +2610,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.9.orig/modules/parse_amd.c
+++ autofs-5.1.9/modules/parse_amd.c
@@ -1765,7 +1765,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) {
@@ -1776,8 +1776,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);
}
}

View File

@ -12,7 +12,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.9
Release: 13%{?dist}
Release: 14%{?dist}
Epoch: 1
License: GPL-2.0-or-later
Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.gz
@ -44,6 +44,15 @@ Patch22: autofs-5.1.9-fix-lock-ordering-deadlock-in-expire_cleanup.patch
Patch30: autofs-5.1.9-fix-handling-of-ignored-offsets.patch
Patch31: autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch
# RHEL-150239 amd option 'nounmount' (and related options) updates and fixes.
Patch40: autofs-5.1.9-fix-lookup-search-type-in-umount_subtree_mounts.patch
Patch41: autofs-5.1.9-fix-remount_active_mount-not-remounting-symlinks.patch
Patch42: autofs-5.1.9-log-when-setting-amd-per-mount-timeout.patch
Patch43: autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch
Patch44: autofs-5.1.7-clear-per-mount-timeout-if-not-set.patch
Patch45: autofs-5.1.9-fix-incorrect-flags-update-in-update_with_defaults.patch
Patch46: autofs-5.1.9-skip-expire-check-for-amd-nounmount-mounts.patch
%if %{with_systemd}
BuildRequires: systemd-units
BuildRequires: systemd-devel
@ -215,6 +224,17 @@ fi
%dir /etc/auto.master.d
%changelog
* Tue Mar 17 2026 Ian Kent <ikent@redhat.com> - 1:5.1.9-14
- RHEL-150238 - RFE: autofs: add handling for AMD 'nounmount' option [rhel-10]
- 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-150238
* Mon May 12 2025 Ian Kent <ikent@redhat.com> - 1:5.1.9-13
- RHEL-90571 - autofs: segfault while dereferencing null mapent [rhel-10]
- fix handling of ignored offsets.