- Add fix for Jira RHEL-113623.
This commit is contained in:
parent
0ccd87f413
commit
7f03cb7b09
122
autofs-5.1.9-add-function-table_lookup_ino.patch
Normal file
122
autofs-5.1.9-add-function-table_lookup_ino.patch
Normal 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;
|
||||
@ -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;
|
||||
}
|
||||
180
autofs-5.1.9-fix-devid-update-on-reload.patch
Normal file
180
autofs-5.1.9-fix-devid-update-on-reload.patch
Normal 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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
35
autofs-5.1.9-quiet-possibly-noisy-log-message.patch
Normal file
35
autofs-5.1.9-quiet-possibly-noisy-log-message.patch
Normal 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;
|
||||
158
autofs-5.1.9-refactor-do_umount_autofs_direct.patch
Normal file
158
autofs-5.1.9-refactor-do_umount_autofs_direct.patch
Normal 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)
|
||||
@ -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 &&
|
||||
@ -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");
|
||||
43
autofs.spec
43
autofs.spec
@ -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.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user