- Add fix for Jira RHEL-113623.

This commit is contained in:
Ian Kent 2026-03-04 09:56:18 +08:00
parent 0ccd87f413
commit 7f03cb7b09
12 changed files with 943 additions and 1 deletions

View File

@ -0,0 +1,122 @@
autofs-5.1.9 - add function table_lookup_ino()
From: Ian Kent <raven@themaw.net>
Add function table_lookup_ino() to try and locate a mount for a given
device, open a file handle for it, and return it's path in the provided
buffer.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 1
lib/mounts.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -195,6 +195,7 @@
- fix direct mount trigger umount failure case.
- refactor do_umount_autofs_direct().
- fix stale direct mount trigger not umounted on expire.
+- add function table_lookup_ino().
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
@@ -175,6 +175,7 @@ void mnts_remove_amdmounts(struct autofs
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);
+char *table_lookup_ino(struct autofs_point *ap, dev_t dev, ino_t ino, char *buf, size_t len, int *fd);
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);
--- autofs-5.1.7.orig/lib/mounts.c
+++ autofs-5.1.7/lib/mounts.c
@@ -2335,6 +2335,84 @@ void free_mnt_list(struct mnt_list *list
}
}
+char *table_lookup_ino(struct autofs_point *ap,
+ dev_t dev, ino_t ino,
+ char *buf, size_t len, int *fd)
+{
+ struct ioctl_ops *ops;
+ struct mntent *mnt;
+ struct mntent mnt_wrk;
+ char tmp[PATH_MAX * 3];
+ char *path = NULL;
+ FILE *tab;
+ int ret = 0;
+
+ ops = get_ioctl_ops();
+ if (!ops) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ tab = open_fopen_r(_PROC_MOUNTS);
+ if (!tab) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ while ((mnt = local_getmntent_r(tab, &mnt_wrk, tmp, PATH_MAX * 3))) {
+ unsigned int type;
+ int ioctlfd;
+ dev_t devid;
+
+ if (strcmp(mnt->mnt_type, "autofs"))
+ continue;
+
+ type = t_direct;
+ if (strstr(mnt->mnt_opts, "indirect"))
+ type = t_indirect;
+ else if (strstr(mnt->mnt_opts, "offset"))
+ type = t_offset;
+
+ ret = ops->mount_device(ap->logopt, mnt->mnt_dir, type, &devid);
+ if (ret == -1 || ret == 0)
+ continue;
+
+ /* Our <device, inode> should be unique so there can only
+ * be one.
+ */
+ ioctlfd = open_ioctlfd(ap, mnt->mnt_dir, devid);
+ /* errno will be set on fail */
+ if (ioctlfd == -1)
+ break;
+ if (fd > 0) {
+ struct stat st;
+
+ if (fstat(ioctlfd, &st) == -1) {
+ ops->close(ap->logopt, ioctlfd);
+ break;
+ }
+
+ if (strlen(mnt->mnt_dir) >= len) {
+ ops->close(ap->logopt, ioctlfd);
+ errno = ENAMETOOLONG;
+ break;
+ }
+
+ if (st.st_dev == dev && st.st_ino == ino) {
+ strcpy(buf, mnt->mnt_dir);
+ path = buf;
+ *fd = ioctlfd;
+ break;
+ }
+ ops->close(ap->logopt, ioctlfd);
+ break;
+ }
+ }
+ fclose(tab);
+
+ return path;
+}
+
static int table_is_mounted(const char *mp, unsigned int type)
{
struct mntent *mnt;

View File

@ -0,0 +1,48 @@
autofs-5.1.9 - fix cache writelock must be taken in update_map_cache()
From: Ian Kent <raven@themaw.net>
In update_map_cache() the cache writelock must be taken because we need
to clean up the map entry as it will be a problem later if we don't.
It's possible that some other process has taken the lock temporarily but
when this function is called the thread does not hold any cache locks so
it should be ok to aquire it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 12 +++++-------
2 files changed, 6 insertions(+), 7 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -188,6 +188,7 @@
- fix always recreate credential cache.
- quiet possibly noisy log message.
- fix devid update on reload.
+- fix cache writelock must be taken in update_map_cache().
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
@@ -511,13 +511,11 @@ static void update_map_cache(struct auto
}
mc = map->mc;
- /* If the lock is busy try later */
- if (cache_try_writelock(mc)) {
- me = cache_lookup_distinct(mc, key);
- if (me && me->ioctlfd == -1)
- cache_delete(mc, key);
- cache_unlock(mc);
- }
+ cache_writelock(mc);
+ me = cache_lookup_distinct(mc, key);
+ if (me && me->ioctlfd == -1)
+ cache_delete(mc, key);
+ cache_unlock(mc);
map = map->next;
}

View File

@ -0,0 +1,180 @@
autofs-5.1.9 - fix devid update on reload
From: Ian Kent <raven@themaw.net>
On map update if there's a direct mount in the master map it may be
associated with multiple maps.
If there's an entry that's been removed but is present in another map
and the removed entry has a real mount associated with it special case
handling is needed.
Currently the function that looks for these newly valid map entries
doesn't do it properly. It's meant to look for the first "valid" map
entry but doesn't check if the entry is valid. So if a valid entry
follows the an invalid entry it isn't found, the invalid entry is
returned instead.
Once this is fixed the handling of a removed direct mount entry that's
covered by a real mount can be done. Basically, the newly valid map
entry needs to take over the mount (which wasn't being done quite right
either) and the removed map entry deleted so that the covering mount can
expire. From this point onward the newly valid map entry will be used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 38 ++++++++++++--------------------------
daemon/state.c | 17 +++++------------
include/automount.h | 2 +-
4 files changed, 19 insertions(+), 39 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -187,6 +187,7 @@
- always recreate credential cache.
- fix always recreate credential cache.
- quiet possibly noisy log message.
+- fix devid update on reload.
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
@@ -1346,6 +1346,7 @@ void lookup_prune_one_cache(struct autof
me = cache_enumerate(mc, NULL);
while (me) {
+ dev_t devid;
struct mapent *valid;
char *key = NULL, *next_key = NULL;
@@ -1403,6 +1404,7 @@ void lookup_prune_one_cache(struct autof
me = cache_enumerate(mc, me);
continue;
}
+ devid = ap->type == LKP_INDIRECT ? ap->dev : me->dev;
/*
* If this key has another valid entry we want to prune it,
@@ -1410,37 +1412,20 @@ void lookup_prune_one_cache(struct autof
* mount if it is a direct mount or it's just a stale indirect
* cache entry.
*/
- valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT);
- if (valid && valid->mc == mc) {
- /*
- * We've found a map entry that has been removed from
- * the current cache so it isn't really valid. Set the
- * mapent negative to prevent further mount requests
- * using the cache entry.
- */
- debug(ap->logopt, "removed map entry detected, mark negative");
- if (valid->mapent) {
- free(valid->mapent);
- valid->mapent = NULL;
- }
+ valid = lookup_source_valid_mapent(ap, key, LKP_DISTINCT, age);
+ if (valid)
cache_unlock(valid->mc);
- valid = NULL;
- }
- if (!valid &&
- is_mounted(path, MNTS_REAL)) {
+ else if (is_mounted(path, MNTS_REAL)) {
debug(ap->logopt, "prune postponed, %s mounted", path);
free(key);
free(path);
me = cache_enumerate(mc, me);
continue;
}
- if (valid)
- cache_unlock(valid->mc);
me = cache_enumerate(mc, me);
if (me)
next_key = strdup(me->key);
-
cache_unlock(mc);
cache_writelock(mc);
@@ -1453,10 +1438,7 @@ void lookup_prune_one_cache(struct autof
if (valid)
cache_delete(mc, key);
else if (!is_mounted(path, MNTS_AUTOFS)) {
- dev_t devid = ap->dev;
status = CHE_FAIL;
- if (ap->type == LKP_DIRECT)
- devid = this->dev;
if (this->ioctlfd == -1)
status = cache_delete(mc, key);
if (status != CHE_FAIL) {
@@ -1530,7 +1512,7 @@ int lookup_prune_cache(struct autofs_poi
}
/* Return with cache readlock held */
-struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type)
+struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type, time_t age)
{
struct master_mapent *entry = ap->entry;
struct map_source *map;
@@ -1554,8 +1536,12 @@ struct mapent *lookup_source_valid_mapen
me = cache_lookup_distinct(mc, key);
else
me = cache_lookup(mc, key);
- if (me)
- break;
+ if (me) {
+ /* Valid? */
+ if (me->age >= age)
+ break;
+ me = NULL;
+ }
cache_unlock(mc);
map = map->next;
}
--- autofs-5.1.7.orig/daemon/state.c
+++ autofs-5.1.7/daemon/state.c
@@ -333,17 +333,7 @@ static int do_readmap_mount(struct autof
* This is becuase of the requirement to continue running with
* an empty cache awaiting a map re-load.
*/
- valid = lookup_source_valid_mapent(ap, me->key, LKP_DISTINCT);
- if (valid && valid->mc == me->mc) {
- /*
- * We've found a map entry that has been removed from
- * the current cache so there is no need to update it.
- * The stale entry will be dealt with when we prune the
- * cache later.
- */
- cache_unlock(valid->mc);
- valid = NULL;
- }
+ valid = lookup_source_valid_mapent(ap, me->key, LKP_DISTINCT, now);
if (valid) {
struct mapent_cache *vmc = valid->mc;
struct ioctl_ops *ops = get_ioctl_ops();
@@ -365,8 +355,11 @@ static int do_readmap_mount(struct autof
/* Take over the mount if there is one */
valid->ioctlfd = me->ioctlfd;
me->ioctlfd = -1;
+ /* Same path */
+ valid->dev = me->dev;
+ valid->ino = me->ino;
/* Set device and inode number of the new mapent */
- cache_set_ino_index(vmc, me);
+ cache_set_ino_index(vmc, valid);
cache_unlock(vmc);
/* Set timeout and calculate the expire run frequency */
timeout = get_exp_timeout(ap, map);
--- autofs-5.1.7.orig/include/automount.h
+++ autofs-5.1.7/include/automount.h
@@ -274,7 +274,7 @@ int lookup_nss_mount(struct autofs_point
void lookup_close_lookup(struct autofs_point *ap);
void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age);
int lookup_prune_cache(struct autofs_point *ap, time_t age);
-struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type);
+struct mapent *lookup_source_valid_mapent(struct autofs_point *ap, const char *key, unsigned int type, time_t age);
struct mapent *lookup_source_mapent(struct autofs_point *ap, const char *key, unsigned int type);
int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key);

View File

@ -0,0 +1,39 @@
autofs-5.1.9 - fix direct mount trigger umount failure case
From: Ian Kent <raven@themaw.net>
In function do_umount_autofs_direct() for the case where the trigger
mount is found to be in use we should be detaching the mount so it gets
umounted but the process can continue using it while it has an open file
handle for it.
This is because direct mount triggers are only umounted when the map
entry is removed from a map or automount(8) is shutdown which in both
cases the trigger mount needs to go away.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 1 +
2 files changed, 2 insertions(+)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -192,6 +192,7 @@
- fix skip valid map entries on expire cleanup.
- remove unnecessary call to set_direct_mount_tree_catatonic().
- remove unnecessary assignment in umount_multi().
+- fix direct mount trigger umount failure case.
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
@@ -153,6 +153,7 @@ int do_umount_autofs_direct(struct autof
} else {
me->ioctlfd = -1;
ops->close(ap->logopt, ioctlfd);
+ rv = -1;
goto force_umount;
}
}

View File

@ -0,0 +1,51 @@
autofs-5.1.9 - fix skip valid map entries on expire cleanup
From: Ian Kent <raven@themaw.net>
After an expire if the current map entry is stale because it could not
be cleaned up during the map entry prune (due to the presence of a real
mount) it needs to be cleaned up after a successful expire.
Currently this is done by update_map_cache() if the entry is contained
in an invalid map but it should be doing it if the entry is no longer
valid. In addition, if update_map_cache() gets called the umount has
been successful so the ioctlfd does not need to be checked (and is in
fact updated later in the expire process).
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 9 ++-------
2 files changed, 3 insertions(+), 7 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -189,6 +189,7 @@
- quiet possibly noisy log message.
- fix devid update on reload.
- fix cache writelock must be taken in update_map_cache().
+- fix skip valid map entries on expire cleanup.
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
@@ -504,16 +504,11 @@ static void update_map_cache(struct auto
while (map) {
struct mapent *me = NULL;
- /* Skip current, in-use cache */
- if (ap->entry->age <= map->age) {
- map = map->next;
- continue;
- }
-
mc = map->mc;
cache_writelock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->ioctlfd == -1)
+ /* Only for invalid map entries */
+ if (me && map->age > me->age)
cache_delete(mc, key);
cache_unlock(mc);

View File

@ -0,0 +1,90 @@
autofs-5.1.9 - fix stale direct mount trigger not umounted on expire
From: Ian Kent <raven@themaw.net>
If a direct mount map entry is removed but has an active real mount the
mount trigger needs to be unmounted during the expire cleanup.
If the direct mount map entry has been re-added the map entry age will
have been updated so the entry won't be seen as stale so the umount
won't be done.
Also in function umount_multi() update_map_cache() and check_rm_dirs()
are not called for direct mounts because count_mounts() always returns
1 or more for top level direct mounts. Make this clear by using ap->type
in the logical check and rely on the left == 0 check to verify there are
no remaining mounts for indirect mounts since count_mounts() will be
more expensive.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 12 ++++++++----
daemon/direct.c | 22 +++++++++++++++++++++-
3 files changed, 30 insertions(+), 5 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -194,6 +194,7 @@
- remove unnecessary assignment in umount_multi().
- fix direct mount trigger umount failure case.
- refactor do_umount_autofs_direct().
+- fix stale direct mount trigger not umounted on expire.
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
@@ -697,10 +697,14 @@ int umount_multi(struct autofs_point *ap
left = umount_subtree_mounts(ap, path, is_autofs_fs);
- /* Delete detritus like unwanted mountpoints and symlinks */
- if (left == 0 &&
- ap->state != ST_READMAP &&
- !count_mounts(ap, path, ap->dev)) {
+ /* Delete detritus like unwanted mountpoints and symlinks
+ * for indirect mounts. This can't be done for direct mounts
+ * here because there's an ioctl file handle open on the
+ * autofs trigger mount for them so it must be done after
+ * the expire.
+ */
+ if (ap->type == LKP_INDIRECT &&
+ ap->state != ST_READMAP && left == 0) {
update_map_cache(ap, path);
check_rm_dirs(ap, path, incl);
}
--- autofs-5.1.7.orig/daemon/direct.c
+++ autofs-5.1.7/daemon/direct.c
@@ -1003,10 +1003,30 @@ static void *do_expire_direct(void *arg)
mt.ioctlfd, mt.wait_queue_token, -ENOENT);
else {
struct mapent *me;
+
cache_writelock(mt.mc);
me = cache_lookup_distinct(mt.mc, mt.name);
- if (me)
+ if (me) {
+ /* If the direct mount map entry is no longer
+ * valid but there is an autofs mount trigger
+ * for the mount the mount trigger needs to be
+ * umounted, the map entry deleted and the mount
+ * point directory removed (if it was created by
+ * us).
+ */
me->ioctlfd = -1;
+ if (me->mc->map->age > me->age &&
+ is_mounted(mt.name, MNTS_AUTOFS)) {
+ /* We must detach the mount becuase the
+ * umount must be completed before
+ * notifying status to the kernel but
+ * there's an ioctlfd open on the
+ * trigger.
+ */
+ if (!finish_umount(ap, me, -1))
+ cache_delete(me->mc, me->key);
+ }
+ }
cache_unlock(mt.mc);
ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
ops->close(ap->logopt, mt.ioctlfd);

View File

@ -0,0 +1,98 @@
autofs-5.1.9 - improve handling of missing map entry for mount request
From: Ian Kent <raven@themaw.net>
If the map entry isn't found it must have been deleted from the map but
a trigger mount is still mounted because it has sent us this request.
Use the mount table for a brute force lookup to get the path and open a
file handle for it so we can send a failure status to the kernel.
Also remove the crit() log message following open_ioctlfd() as it already
issues an appropriate error message on failure.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 48 insertions(+), 6 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -196,6 +196,7 @@
- refactor do_umount_autofs_direct().
- fix stale direct mount trigger not umounted on expire.
- add function table_lookup_ino().
+- improve handling of missing map entry for mount request.
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
@@ -1368,12 +1368,54 @@ int handle_packet_missing_direct(struct
}
if (!me) {
- /*
- * Shouldn't happen as the kernel is telling us
- * someone has walked on our mount point.
+ char tmp[PATH_MAX + 1];
+ char *path;
+
+ /* If the map entry wasn't found it must have been deleted
+ * from the map but a trigger mount is still mounted because
+ * it has sent us this request. So use the mount table for a
+ * brute force lookup to get the path and open a file handle
+ * for it so we can return a not found status to the kernel.
*/
- logerr("can't find map entry for (%lu,%lu)",
- (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+ path = table_lookup_ino(ap, pkt->dev, pkt->ino, tmp, PATH_MAX + 1, &ioctlfd);
+ if (!path) {
+ /* This could be cuased by an inability to open a file
+ * handle but generally that doesn't happen. The mount
+ * has to exist and be pinned becuase we got this request
+ * so it can't be umounted. Therefore it's very unlikely
+ * this case will happen. If it does happen it's fatal,
+ * the waiter will hang and there's nothing we can do
+ * about it.
+ */
+ logerr("can't find mount for (%lu,%lu)",
+ (unsigned long) pkt->dev, (unsigned long) pkt->ino);
+ /* TODO: how do we clear wait q in kernel ?? */
+ } else {
+ char buf[MAX_ERR_BUF];
+
+ /* Try and recover from this unexpecyedly missing map
+ * entry by detaching the direct mount trigger that
+ * sent the request so it's no longer visible to the
+ * VFS.
+ */
+ info(ap->logopt, "forcing umount of direct mount %s", path);
+ if (umount2(path, MNT_DETACH) == -1) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(ap->logopt, "failed to force umount %s: %s",
+ path, estr);
+ }
+ if (rmdir(path) == -1) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(ap->logopt,
+ "failed to remove dir %s: %s", path, estr);
+ }
+ ops->send_fail(ap->logopt,
+ ioctlfd, pkt->wait_queue_token, -EINVAL);
+ ops->close(ap->logopt, ioctlfd);
+ }
master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(state, NULL);
@@ -1392,7 +1434,6 @@ int handle_packet_missing_direct(struct
master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(state, NULL);
- crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
/* TODO: how do we clear wait q in kernel ?? */
return 1;
}

View File

@ -0,0 +1,35 @@
autofs-5.1.9 - quiet possibly noisy log message
From: Ian Kent <raven@themaw.net>
The message that logs when a mount is already mounted and only the
timeout will be updated on map re-read can create a lot of noise in
the log for direct mount maps. But this is normal operation and is of
limited value for both direct and indirect maps, so remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -186,6 +186,7 @@
- fix invalidated map entry handling in hosts module.
- always recreate credential cache.
- fix always recreate credential cache.
+- quiet possibly noisy log message.
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
@@ -2895,7 +2895,6 @@ 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, NULL, timeout);
ops->close(ap->logopt, fd);
return REMOUNT_READ_MAP;

View File

@ -0,0 +1,158 @@
autofs-5.1.9 - refactor do_umount_autofs_direct()
From: Ian Kent <raven@themaw.net>
Refactor functon do_umount_autofs_direct() so that it can be called from
do_expire_direct() to clean up stale direct mounts that couldn't be
cleaned up at map re-load.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/direct.c | 106 ++++++++++++++++++++++++++++++--------------------------
2 files changed, 58 insertions(+), 49 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -193,6 +193,7 @@
- remove unnecessary call to set_direct_mount_tree_catatonic().
- remove unnecessary assignment in umount_multi().
- fix direct mount trigger umount failure case.
+- refactor do_umount_autofs_direct().
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
@@ -81,12 +81,66 @@ static void mnts_cleanup(void *arg)
mnts_put_expire_list(mnts);
}
+static int finish_umount(struct autofs_point *ap, struct mapent *me, int rv)
+{
+ char buf[MAX_ERR_BUF];
+
+ if (rv != 0) {
+ info(ap->logopt, "forcing umount of direct mount %s", me->key);
+ rv = umount2(me->key, MNT_DETACH);
+ } else
+ info(ap->logopt, "umounted direct mount %s", me->key);
+
+ if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
+ if (rmdir(me->key) == -1) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(ap->logopt, "failed to remove dir %s: %s",
+ me->key, estr);
+ }
+ }
+ return rv;
+}
+
+static int do_umount_direct(struct autofs_point *ap, struct mapent *me)
+{
+ int rv, retries = UMOUNT_RETRIES;
+
+ while ((rv = umount(me->key)) == -1 && retries--) {
+ struct timespec tm = {0, 50000000};
+ if (errno != EBUSY)
+ break;
+ nanosleep(&tm, NULL);
+ }
+
+ if (rv == -1) {
+ switch (errno) {
+ case ENOENT:
+ case EINVAL:
+ warn(ap->logopt, "mount point %s does not exist",
+ me->key);
+ return 0;
+ case EBUSY:
+ warn(ap->logopt, "mount point %s is in use", me->key);
+ if (ap->state == ST_SHUTDOWN_FORCE)
+ goto out;
+ else
+ return 0;
+ case ENOTDIR:
+ error(ap->logopt, "mount point is not a directory");
+ return 0;
+ }
+ return 1;
+ }
+out:
+ return finish_umount(ap, me, rv);
+}
+
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;
+ int ioctlfd = -1, rv, left;
char key[PATH_MAX + 1];
struct mapent *tmp;
int opened = 0;
@@ -153,8 +207,7 @@ int do_umount_autofs_direct(struct autof
} else {
me->ioctlfd = -1;
ops->close(ap->logopt, ioctlfd);
- rv = -1;
- goto force_umount;
+ return finish_umount(ap, me, -1);
}
}
me->ioctlfd = -1;
@@ -167,52 +220,7 @@ int do_umount_autofs_direct(struct autof
sched_yield();
- retries = UMOUNT_RETRIES;
- while ((rv = umount(me->key)) == -1 && retries--) {
- struct timespec tm = {0, 50000000};
- if (errno != EBUSY)
- break;
- nanosleep(&tm, NULL);
- }
-
- if (rv == -1) {
- switch (errno) {
- case ENOENT:
- case EINVAL:
- warn(ap->logopt, "mount point %s does not exist",
- me->key);
- return 0;
- break;
- case EBUSY:
- warn(ap->logopt, "mount point %s is in use", me->key);
- if (ap->state == ST_SHUTDOWN_FORCE)
- goto force_umount;
- else
- return 0;
- break;
- case ENOTDIR:
- error(ap->logopt, "mount point is not a directory");
- return 0;
- break;
- }
- return 1;
- }
-
-force_umount:
- if (rv != 0) {
- info(ap->logopt, "forcing umount of direct mount %s", me->key);
- rv = umount2(me->key, MNT_DETACH);
- } else
- info(ap->logopt, "umounted direct mount %s", me->key);
-
- if (!rv && me->flags & MOUNT_FLAG_DIR_CREATED) {
- if (rmdir(me->key) == -1) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt, "failed to remove dir %s: %s",
- me->key, estr);
- }
- }
- return rv;
+ return do_umount_direct(ap, me);
}
int umount_autofs_direct(struct autofs_point *ap)

View File

@ -0,0 +1,36 @@
autofs-5.1.9 - remove unnecessary assignment in umount_multi()
From: Ian Kent <raven@themaw.net>
Remove the leftover initialisation of left from when there were multiple
calls to umount_subtree_mounts().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 4 +---
2 files changed, 2 insertions(+), 3 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -191,6 +191,7 @@
- fix cache writelock must be taken in update_map_cache().
- fix skip valid map entries on expire cleanup.
- remove unnecessary call to set_direct_mount_tree_catatonic().
+- remove unnecessary assignment in umount_multi().
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
@@ -695,9 +695,7 @@ int umount_multi(struct autofs_point *ap
mnts_put_mount(sbmnt);
}
- left = 0;
-
- left += umount_subtree_mounts(ap, path, is_autofs_fs);
+ left = umount_subtree_mounts(ap, path, is_autofs_fs);
/* Delete detritus like unwanted mountpoints and symlinks */
if (left == 0 &&

View File

@ -0,0 +1,44 @@
autofs-5.1.9 - remove unnecessary call to set_direct_mount_tree_catatonic()
From: Ian Kent <raven@themaw.net>
Function do_umount_autofs_direct() is called in two cases, during a
readmap and when umounting top level direct mounts.
During a readmap, mounts should not be set catatonic so the call to
set_direct_mount_tree_catatonic() is not needed. If it's called for a
top level direct mount the caller, umount_autofs_direct(), calls
set_direct_mount_tree_catatonic() itself already. So remove this
unnecessary call.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 5 +----
2 files changed, 2 insertions(+), 4 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -190,6 +190,7 @@
- fix devid update on reload.
- fix cache writelock must be taken in update_map_cache().
- fix skip valid map entries on expire cleanup.
+- remove unnecessary call to set_direct_mount_tree_catatonic().
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
@@ -186,11 +186,8 @@ int do_umount_autofs_direct(struct autof
warn(ap->logopt, "mount point %s is in use", me->key);
if (ap->state == ST_SHUTDOWN_FORCE)
goto force_umount;
- else {
- if (ap->state != ST_READMAP)
- set_direct_mount_tree_catatonic(ap, me);
+ else
return 0;
- }
break;
case ENOTDIR:
error(ap->logopt, "mount point is not a directory");

View File

@ -12,7 +12,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.7
Release: 65%{?dist}
Release: 66%{?dist}
Epoch: 1
License: GPLv2+
Source: https://www.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-2.tar.gz
@ -233,6 +233,19 @@ Patch211: autofs-5.1.9-fix-invalidated-map-entry-handling-in-hosts-module.patch
Patch212: autofs-5.1.8-always-recreate-credential-cache.patch
Patch213: autofs-5.1.9-fix-always-recreate-credential-cache.patch
# JIRA: RHEL-113623
Patch214: autofs-5.1.9-quiet-possibly-noisy-log-message.patch
Patch215: autofs-5.1.9-fix-devid-update-on-reload.patch
Patch216: autofs-5.1.9-fix-cache-writelock-must-be-taken-in-update_map_cache.patch
Patch217: autofs-5.1.9-fix-skip-valid-map-entries-on-expire-cleanup.patch
Patch218: autofs-5.1.9-remove-unnecessary-call-to-set_direct_mount_tree_catatonic.patch
Patch219: autofs-5.1.9-remove-unnecessary-assignment-in-umount_multi.patch
Patch220: autofs-5.1.9-fix-direct-mount-trigger-umount-failure-case.patch
Patch221: autofs-5.1.9-refactor-do_umount_autofs_direct.patch
Patch222: autofs-5.1.9-fix-stale-direct-mount-trigger-not-umounted-on-expire.patch
Patch223: autofs-5.1.9-add-function-table_lookup_ino.patch
Patch224: autofs-5.1.9-improve-handling-of-missing-map-entry-for-mount-request.patch
%if %{with_systemd}
BuildRequires: systemd-units
BuildRequires: systemd-devel
@ -496,6 +509,18 @@ echo %{version}-%{release} > .version
%patch -P 212 -p1
%patch -P 213 -p1
%patch -P 214 -p1
%patch -P 215 -p1
%patch -P 216 -p1
%patch -P 217 -p1
%patch -P 218 -p1
%patch -P 219 -p1
%patch -P 220 -p1
%patch -P 221 -p1
%patch -P 222 -p1
%patch -P 223 -p1
%patch -P 224 -p1
%build
LDFLAGS=-Wl,-z,now
%configure \
@ -603,6 +628,22 @@ fi
%dir /etc/auto.master.d
%changelog
* Wed Mar 04 2026 Ian Kent <ikent@redhat.com> - 1:5.1.7-66
- RHEL-113623 - Wrong oz_pgrp in autofs_sb_info causes automount to wait
on automount.
- quiet possibly noisy log message.
- fix devid update on reload.
- fix cache writelock must be taken in update_map_cache().
- fix skip valid map entries on expire cleanup.
- remove unnecessary call to set_direct_mount_tree_catatonic().
- remove unnecessary assignment in umount_multi().
- fix direct mount trigger umount failure case.
- refactor do_umount_autofs_direct().
- fix stale direct mount trigger not umounted on expire.
- add function table_lookup_ino().
- improve handling of missing map entry for mount request.
- Resolves: RHEL-113623
* Tue May 13 2025 Ian Kent <ikent@redhat.com> - 1:5.1.7-65
- RHEL-85615 - autofs fails to mount shares when using kerberised LDAP
- always recreate credential cache.