autofs/autofs-5.1.9-update-per-mount-expire-timeout-on-readmap.patch
Ian Kent b58878d9dd Add Add fixes for Jiras RHEL-69485 RHEL-71359 and RHEL-57466
This MR adds fixes for several Jiras.

- RHEL-57466 - autofs crashes on startup after IDM client configuration
We have had several different reports caused by this bug which leads to a
SEGV with very little information about the cuase.

- Resolves: RHEL-57466

- RHEL-69485 - Sporadic mount failures with amd program maps on RHEL8.
This bug causes AMD-style program map mounts to sporadically not work.

- Resolves: RHEL-69485

- RHEL-71359 - RFE: autofs: add handling for AMD 'nounmount' option
This Jira adds support for a map option that was deferred in the original
implementtion. One of our customers needs this so it has been implemented.

- Resolves: RHEL-71359

Signed-off-by: Ian Kent <ikent@redhat.com>
2024-12-17 11:04:01 +08:00

226 lines
7.1 KiB
Diff

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -176,6 +176,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.
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
@@ -1379,7 +1379,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.7.orig/daemon/state.c
+++ autofs-5.1.7/daemon/state.c
@@ -428,6 +428,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.7.orig/include/master.h
+++ autofs-5.1.7/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.7.orig/include/mounts.h
+++ autofs-5.1.7/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.7.orig/lib/mounts.c
+++ autofs-5.1.7/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.7.orig/modules/parse_amd.c
+++ autofs-5.1.7/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);
}
}