Compare commits

...

4 Commits

Author SHA1 Message Date
447ef72538 import UBI autofs-5.1.4-114.el8_10.2 2025-03-11 09:32:53 +00:00
aba40ee5f4 import UBI autofs-5.1.4-114.el8_10.1 2024-12-03 13:15:36 +00:00
e7542162a3 import UBI autofs-5.1.4-113.el8 2024-05-22 14:35:49 +00:00
eabdullin
5bbc3418a3 import UBI autofs-5.1.4-109.el8_9.1 2024-02-20 14:44:13 +00:00
13 changed files with 1156 additions and 1 deletions

View File

@ -0,0 +1,152 @@
autofs-5.1.8 - allow -null map in indirect maps
From: Ian Kent <raven@themaw.net>
We have had reports of GUI programs (such as Nautilus) probing for files
such as .hidden in the parent directory of the directory being accessed.
If using an indirect mount map with a wildcard map entry autofs is duty
bound to try and mount these which usually results in a mount failure but
can also cause lengthy delays in some cases.
There are some challenges to modifying application code and even if it
can be done it's always open to being broken later by developers that
aren't aware of the reasoning behind the original changes.
Now, there is a machanism in autofs that can be used to ignore certain
map entries, the "builtin map -null", see auto.master(5). Currently it
can be used only in the master map but this change extends it to be used
in indirect mount maps as well. In this way it can be used to handle
problematic entries by simply adding a map entry that uses the builtin
-null map.
For example:
.hidden -null
* someserver:/remote/home/&
This mechanism is not standard so if one is using systems other than
those with Linux autofs and central map storage, such as LDAP, then
it would be necessary to configure nsswitch to ensure the files map
source is consulted first followed by the remote map source. Then the
-null map entries included in a local file map that uses plus map
inclusion to move on the the central map source if there is no match.
For example, in /etc/auto.home we can have:
.hidden -null
+auto.home
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/indirect.c | 12 +++++++++++-
daemon/lookup.c | 4 ++++
include/parse_subs.h | 1 +
lib/parse_subs.c | 13 +++++++++++++
man/auto.master.5.in | 9 +++++++--
6 files changed, 37 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -150,6 +150,7 @@
- fix some sss error return cases.
- fix incorrect matching of cached wildcard key.
- fix expire retry looping.
+- allow -null map in indirect maps.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -796,13 +796,23 @@ int handle_packet_missing_indirect(struc
return 0;
}
- /* Check if we recorded a mount fail for this key anywhere */
me = lookup_source_mapent(ap, pkt->name, LKP_DISTINCT);
if (me) {
+ /* Check if we recorded a mount fail for this key */
if (me->status >= monotonic_time(NULL)) {
ops->send_fail(ap->logopt, ap->ioctlfd,
pkt->wait_queue_token, -ENOENT);
cache_unlock(me->mc);
+ master_mutex_unlock();
+ pthread_setcancelstate(state, NULL);
+ return 0;
+ }
+
+ /* Ignore nulled indirect map entries */
+ if (starts_with_null_opt(me->mapent)) {
+ ops->send_fail(ap->logopt, ap->ioctlfd,
+ pkt->wait_queue_token, -ENOENT);
+ cache_unlock(me->mc);
master_mutex_unlock();
pthread_setcancelstate(state, NULL);
return 0;
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -780,6 +780,10 @@ int lookup_ghost(struct autofs_point *ap
goto next;
}
+ /* Ignore nulled indirect map entries */
+ if (starts_with_null_opt(me->mapent))
+ goto next;
+
fullpath = make_browse_path(ap->logopt,
ap->path, me->key, ap->pref);
if (!fullpath)
--- autofs-5.1.4.orig/include/parse_subs.h
+++ autofs-5.1.4/include/parse_subs.h
@@ -122,6 +122,7 @@ int strmcmp(const char *, const char *,
char *dequote(const char *, int, unsigned int);
int span_space(const char *, unsigned int);
char *sanitize_path(const char *, int, unsigned int, unsigned int);
+int starts_with_null_opt(const char *);
char *merge_options(const char *, const char *);
int expandamdent(const char *, char *, const struct substvar *);
int expand_selectors(struct autofs_point *, const char *, char **, struct substvar *);
--- autofs-5.1.4.orig/lib/parse_subs.c
+++ autofs-5.1.4/lib/parse_subs.c
@@ -878,6 +878,19 @@ char *sanitize_path(const char *path, in
return s_path;
}
+int starts_with_null_opt(const char *str)
+{
+ if (str && strlen(str) >= 5 && *str == '-') {
+ char sep = *(str + 5);
+
+ if (sep == 0 || sep == ' ' || sep == ',') {
+ if (!strncmp(str, "-null", 5))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static char *hasopt(const char *str, const char *opt)
{
const size_t optlen = strlen(opt);
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -267,13 +267,18 @@ master map entry.
If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent
master map entry with the given path.
.P
-It can only be used for paths that appear in the master map (or in direct mount maps).
+It can be used for paths that appear in the master map or in direct mount maps (but
+not in direct mount maps themselves) or as a key in an indirect mount map.
+.P
+An indirect mount map key can be nulled. If so the map key is ignored and does not
+result in a mount attempt (essentially the key lookup is abandoned early on).
.P
An indirect mount map top level mount point path can be nulled. If so no mounts from
the nulled mount are performed (essentially it isn't mounted).
.P
Direct mount map path entries can be nulled. Since they must be present at startup
-they are (notionally) part of the master map.
+they are (notionally) part of the master map so direct mount paths that use the -null
+map may be used in the master map to ignore subsequent direct mount map entries.
.P
A nulled master map entry path will ignore a single subsequent matching entry. Any
matching entry following that will be treated as it normally would be. An example

View File

@ -0,0 +1,44 @@
autofs-5.1.8 - fix multi-mount check
From: Ian Kent <raven@themaw.net>
When checking if a mount location is a multi-mount after the first location
the next '-' or '/' indicates it's a multi-mount.
But the '-' can be part of a mount location and can follow a space leading
to incorrectly deciding the location is a multi-mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 9 ++++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -151,6 +151,7 @@
- fix incorrect matching of cached wildcard key.
- fix expire retry looping.
- allow -null map in indirect maps.
+- fix multi-mount check.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -786,7 +786,14 @@ static int check_is_multi(const char *ma
if (not_first_chunk) {
if (*p == '"')
p++;
- if (*p == '/' || *p == '-') {
+ /*
+ * Although an options string here would mean
+ * we have a multi-mount we can't rely on it
+ * since it's also valid in a mount location.
+ */
+ if (*p == '-')
+ p++;
+ if (*p == '/') {
multi = 1;
break;
}

View File

@ -0,0 +1,60 @@
autofs-5.1.9 - add flags argument to amd do_program_mount()
From: Ian Kent <raven@themaw.net>
Most of the amd mount functions take a flags argument that allows them
to alter their function based on configuration.
For example the amd option autofs_use_lofs will use bind mounts instead
of symlinks in some cases which might be preferred.
The program mount function was not being passed this parameter but the
design of all the amd mount functions is quite similar and adding the
flag works as expected..
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -160,6 +160,7 @@
- don't free ext mount if mounted.
- refactor amd function do_program_mount().
- refactor umount_amd_ext_mount().
+- add flags argument to amd do_program_mount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1405,7 +1405,8 @@ out:
}
static int do_program_mount(struct autofs_point *ap,
- struct amd_entry *entry, const char *name)
+ struct amd_entry *entry, const char *name,
+ unsigned int flags)
{
int rv = 1;
@@ -1479,7 +1480,7 @@ static int do_program_mount(struct autof
goto out;
}
done:
- rv = do_link_mount(ap, name, entry, 0);
+ rv = do_link_mount(ap, name, entry, flags);
if (rv) {
if (!umount_amd_ext_mount(ap, entry->fs, 1)) {
debug(ap->logopt, MODPREFIX
@@ -1708,7 +1709,7 @@ static int amd_mount(struct autofs_point
case AMD_MOUNT_TYPE_PROGRAM:
if (!validate_program_options(ap->logopt, entry))
return 1;
- ret = do_program_mount(ap, entry, name);
+ ret = do_program_mount(ap, entry, name, flags);
break;
default:

View File

@ -0,0 +1,53 @@
autofs-5.1.9 - don't free ext mount if mounted
From: Ian Kent <raven@themaw.net>
If an external mount is in use when a umount is attempted don't free
it just let the reference count go to zero.
This will leave the mount in place and it won't get umounted. But if
another automount uses it it's reference count will become no zero
allowing for it to be umounted as normal if it isn't in use during
automount expire.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 ++++----
2 files changed, 5 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -157,6 +157,7 @@
- fix submount shutdown race.
- fix amd external mount error handling.
- fix amd external mount mount handling.
+- don't free ext mount if mounted.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -906,10 +906,10 @@ int ext_mount_remove(const char *path)
if (!em)
goto done;
- em->ref--;
if (em->ref)
- goto done;
- else {
+ em->ref--;
+
+ if (!em->ref && !is_mounted(path, MNTS_REAL)) {
hlist_del_init(&em->mount);
free(em->mp);
if (em->umount)
@@ -931,7 +931,7 @@ int ext_mount_inuse(const char *path)
em = ext_mount_lookup(path);
if (!em)
goto done;
- ret = em->ref;
+ ret = 1;
done:
ext_mount_hash_mutex_unlock();
return ret;

View File

@ -0,0 +1,55 @@
autofs-5.1.9 - fix amd external mount error handling
From: Ian Kent <raven@themaw.net>
An amd program mount might have defined its own umount program to be used
for external mounts.
In mount failure cases where the mount needs to be umounted be sure to
use the custom umount if there is one.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -155,6 +155,7 @@
- fix get parent multi-mount check in try_remount().
- fix deadlock in remount.
- fix submount shutdown race.
+- fix amd external mount error handling.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1183,7 +1183,7 @@ static int do_generic_mount(struct autof
}
/* If we have an external mount add it to the list */
if (umount && !ext_mount_add(entry->fs, entry->umount)) {
- umount_ent(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s",
entry->fs);
@@ -1233,7 +1233,7 @@ static int do_nfs_mount(struct autofs_po
}
/* We might be using an external mount */
if (umount && !ext_mount_add(entry->fs, entry->umount)) {
- umount_ent(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s", entry->fs);
ret = 1;
@@ -1462,7 +1462,7 @@ static int do_program_mount(struct autof
"%s: mounted %s", entry->type, entry->fs);
goto do_free;
}
- umount_ent(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs);
}
if (!ext_mount_inuse(entry->fs))

View File

@ -0,0 +1,71 @@
autofs-5.1.9 - fix amd external mount mount handling
From: Ian Kent <raven@themaw.net>
Amd external mounts exist outside of the autofs file system and need
extra effort to try and keep track of them so they are mounted and
umounted when they should be.
Cleanup cases where an external mount is already mounted.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 21 ++++++++++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -156,6 +156,7 @@
- fix deadlock in remount.
- fix submount shutdown race.
- fix amd external mount error handling.
+- fix amd external mount mount handling.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1182,8 +1182,9 @@ static int do_generic_mount(struct autof
umount = 1;
}
/* If we have an external mount add it to the list */
- if (umount && !ext_mount_add(entry->fs, entry->umount)) {
- umount_amd_ext_mount(ap, entry->fs);
+ if (!ext_mount_add(entry->fs, entry->umount)) {
+ if (umount)
+ umount_amd_ext_mount(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s",
entry->fs);
@@ -1232,8 +1233,9 @@ static int do_nfs_mount(struct autofs_po
umount = 1;
}
/* We might be using an external mount */
- if (umount && !ext_mount_add(entry->fs, entry->umount)) {
- umount_amd_ext_mount(ap, entry->fs);
+ if (!ext_mount_add(entry->fs, entry->umount)) {
+ if (umount)
+ umount_amd_ext_mount(ap, entry->fs);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s", entry->fs);
ret = 1;
@@ -1435,12 +1437,13 @@ static int do_program_mount(struct autof
* before executing the mount command and removing it at
* umount.
*/
- if (ext_mount_inuse(entry->fs)) {
+ if (is_mounted(entry->fs, MNTS_REAL)) {
+ if (!ext_mount_add(entry->fs, entry->umount)) {
+ error(ap->logopt, MODPREFIX
+ "error: could not add external mount %s", entry->fs);
+ goto out;
+ }
rv = 0;
- /* An external mount with path entry->fs exists
- * so ext_mount_add() won't fail.
- */
- ext_mount_add(entry->fs, entry->umount);
} else {
rv = mkdir_path(entry->fs, mp_mode);
if (rv && errno != EEXIST) {

View File

@ -0,0 +1,66 @@
autofs-5.1.9 - fix deadlock in master_notify_submount()
From: Ian Kent <raven@themaw.net>
A deadlock between mnts_remove_submount() and master_notify_submount()
can occur because master_notify_submount() holds the state mutex over
a call to mnts_find_submount() which then needs to take mnts_hash_mutex.
But mnts_remove_submount() takes mnts_hash_mutex and then needs to take
the state mutex to clear the ->ap field so deadlock cann occur.
But it isn't necessary for master_notify_submount() to take the state
mutex before calling mnts_find_submount() because if the submount is'
found a reference is taken on the entry so it won't go away while it's
being used. All that's needed is to ensure that the ->ap field doesn't
get set to NULL by mnts_remove_submount() while it's being used to check
if the submount has shutdown.
Fixes: 81ac572466e3 ("autofs-5.1.9 - fix submount shutdown race")
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 7 +++----
2 files changed, 4 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -161,6 +161,7 @@
- refactor amd function do_program_mount().
- refactor umount_amd_ext_mount().
- add flags argument to amd do_program_mount().
+- fix deadlock in master_notify_submount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -1237,26 +1237,25 @@ int master_notify_submount(struct autofs
* ST_SHUTDOWN_FORCE we need to wait until it goes away
* or changes to state ST_SHUTDOWN or ST_READY.
*/
- st_mutex_lock();
while ((sbmnt = mnts_find_submount(path))) {
struct timespec t = { 0, 300000000 };
struct timespec r;
+ st_mutex_lock();
if (!sbmnt->ap ||
(sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
sbmnt->ap->state != ST_SHUTDOWN_FORCE)) {
ret = 0;
+ st_mutex_unlock();
mnts_put_mount(sbmnt);
break;
}
+ st_mutex_unlock();
mnts_put_mount(sbmnt);
- st_mutex_unlock();
while (nanosleep(&t, &r) == -1 && errno == EINTR)
memcpy(&t, &r, sizeof(struct timespec));
- st_mutex_lock();
}
- st_mutex_unlock();
done:
mnts_put_mount(this);
}

View File

@ -0,0 +1,68 @@
autofs-5.1.9 - fix deadlock in remount
From: Ian Kent <raven@themaw.net>
If we're starting up or trying to re-connect to an existing direct mount
we could be iterating through the map entries with the cache readlock
held so we can't just take the writelock for direct mounts. But when
trying to re-connect to an existing mount at startup there won't be any
other process updating the map entry cache.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 26 ++++++++++++++++++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -153,6 +153,7 @@
- allow -null map in indirect maps.
- fix multi-mount check.
- fix get parent multi-mount check in try_remount().
+- fix deadlock in remount.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -888,7 +888,18 @@ update_offset_entry(struct autofs_point
strcpy(m_mapent, loc);
}
- cache_writelock(mc);
+ /*
+ * If we're starting up or trying to re-connect to an existing
+ * direct mount we could be iterating through the map entries
+ * with the readlock held so we can't just take the writelock
+ * for direct mounts. But at when trying to re-connect to an
+ * existing mount at startup there won't be any other process
+ * updating the map entry cache.
+ */
+ if (ap->state == ST_INIT && ap->flags & MOUNT_FLAG_REMOUNT)
+ cache_readlock(mc);
+ else
+ cache_writelock(mc);
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
me = cache_lookup_distinct(mc, m_key);
@@ -1580,7 +1591,18 @@ dont_expand:
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
- cache_writelock(mc);
+ /*
+ * If we're starting up or trying to re-connect to an existing
+ * direct mount we could be iterating through the map entries
+ * with the readlock held so we can't just take the writelock
+ * for direct mounts. But at when trying to re-connect to an
+ * existing mount at startup there won't be any other process
+ * updating the map entry cache.
+ */
+ if (ap->state == ST_INIT && ap->flags & MOUNT_FLAG_REMOUNT)
+ cache_readlock(mc);
+ else
+ cache_writelock(mc);
me = cache_lookup_distinct(mc, name);
if (!me) {
cache_unlock(mc);

View File

@ -0,0 +1,43 @@
autofs-5.1.9 - fix get parent multi-mount check in try_remount()
From: Ian Kent <raven@themaw.net>
In commit 635b90ecc (autofs-5.1.8 - fix mount tree startup reconnect)
when getting the parent the check for a multi-mount should include a
check for the root of the multi-mount as well since the root does not
set its parent (it remains NULL).
We could set the root parent to itself but that may have side effects
because the convention has always been the parent is NULL for the
multi-mount root.
Reported-by: Roberto Bergantinos Corpas <rbergant@redhat.com>
Suggested-by: Roberto Bergantinos Corpas <rbergant@redhat.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -152,6 +152,7 @@
- fix expire retry looping.
- allow -null map in indirect maps.
- fix multi-mount check.
+- fix get parent multi-mount check in try_remount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2878,7 +2878,7 @@ int try_remount(struct autofs_point *ap,
}
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
- mapent = IS_MM(me) ? MM_PARENT(me) : me;
+ mapent = IS_MM(me) && !IS_MM_ROOT(me) ? MM_PARENT(me) : me;
/* Direct or offset mount, key is full path */
if (mapent->key[0] == '/') {
if (!is_mounted(mapent->key, MNTS_REAL))

View File

@ -0,0 +1,89 @@
autofs-5.1.9 - fix submount shutdown race
From: Ian Kent <raven@themaw.net>
In function master_notify_submount() an expire notification is sent to
existing submounts. automount waits for the task to complete then, if
the submount is exiting, waits for the submount to reach a completion
state.
But the submount can go away during these checks resulting in the
autofs mount point structure field of the mount list structure to be
set to NULL which can then lead to a crash.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 23 +++++++++++++----------
lib/mounts.c | 2 ++
3 files changed, 16 insertions(+), 10 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -154,6 +154,7 @@
- fix multi-mount check.
- fix get parent multi-mount check in try_remount().
- fix deadlock in remount.
+- fix submount shutdown race.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -1213,22 +1213,24 @@ int master_notify_submount(struct autofs
this = mnts_find_submount(path);
if (this) {
+ struct autofs_point *found;
+
/* We have found a submount to expire */
st_mutex_lock();
-
- if (this->ap->state == ST_SHUTDOWN) {
+ found = this->ap;
+ if (!found || found->state == ST_SHUTDOWN) {
this = NULL;
st_mutex_unlock();
goto done;
}
-
- this->ap->shutdown = ap->shutdown;
-
- __st_add_task(this->ap, state);
-
+ found->shutdown = ap->shutdown;
+ __st_add_task(found, state);
st_mutex_unlock();
- st_wait_task(this->ap, state, 0);
+ /* This is ok because found isn't dereferenced during
+ * the wait checks.
+ */
+ st_wait_task(found, state, 0);
/*
* If our submount gets to state ST_SHUTDOWN_PENDING or
@@ -1240,8 +1242,9 @@ int master_notify_submount(struct autofs
struct timespec t = { 0, 300000000 };
struct timespec r;
- if (sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
- sbmnt->ap->state != ST_SHUTDOWN_FORCE) {
+ if (!sbmnt->ap ||
+ (sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
+ sbmnt->ap->state != ST_SHUTDOWN_FORCE)) {
ret = 0;
mnts_put_mount(sbmnt);
break;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1153,7 +1153,9 @@ void mnts_remove_submount(const char *mp
this = mnts_lookup(mp);
if (this && this->flags & MNTS_AUTOFS) {
this->flags &= ~MNTS_AUTOFS;
+ st_mutex_lock();
this->ap = NULL;
+ st_mutex_unlock();
list_del_init(&this->submount);
__mnts_put_mount(this);
}

View File

@ -0,0 +1,138 @@
autofs-5.1.9 - refactor amd function do_program_mount()
From: Ian Kent <raven@themaw.net>
The amd mounts function do_program_mount() is particularly untidy.
Refactor it to make it a little simpler and to take advantage of the
coming refactoring of the funtion umount_amd_ext_mount().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
modules/parse_amd.c | 74 ++++++++++++++++++++++++----------------------------
2 files changed, 36 insertions(+), 39 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -158,6 +158,7 @@
- fix amd external mount error handling.
- fix amd external mount mount handling.
- don't free ext mount if mounted.
+- refactor amd function do_program_mount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1407,26 +1407,8 @@ out:
static int do_program_mount(struct autofs_point *ap,
struct amd_entry *entry, const char *name)
{
- char *prog, *str;
- char **argv;
- int argc = -1;
int rv = 1;
- str = strdup(entry->mount);
- if (!str)
- goto out;
-
- prog = NULL;
- argv = NULL;
-
- argc = construct_argv(str, &prog, &argv);
- if (argc == -1) {
- error(ap->logopt, MODPREFIX
- "%s: error creating mount arguments", entry->type);
- free(str);
- goto out;
- }
-
/* The am-utils documentation doesn't actually say that the
* mount (and umount, if given) command need to use ${fs} as
* the mount point in the command.
@@ -1445,6 +1427,25 @@ static int do_program_mount(struct autof
}
rv = 0;
} else {
+ char *prog, *str;
+ char **argv;
+ int argc = -1;
+
+ str = strdup(entry->mount);
+ if (!str)
+ goto out;
+
+ prog = NULL;
+ argv = NULL;
+
+ argc = construct_argv(str, &prog, &argv);
+ if (argc == -1) {
+ error(ap->logopt, MODPREFIX
+ "%s: error creating mount arguments", entry->type);
+ free(str);
+ goto out;
+ }
+
rv = mkdir_path(entry->fs, mp_mode);
if (rv && errno != EEXIST) {
char buf[MAX_ERR_BUF];
@@ -1454,7 +1455,9 @@ static int do_program_mount(struct autof
error(ap->logopt,
MODPREFIX "%s: mkdir_path %s failed: %s",
entry->type, entry->fs, estr);
- goto do_free;
+ free_argv(argc, (const char **) argv);
+ free(str);
+ goto out;
}
rv = spawnv(ap->logopt, prog, (const char * const *) argv);
@@ -1463,33 +1466,26 @@ static int do_program_mount(struct autof
rv = 0;
debug(ap->logopt, MODPREFIX
"%s: mounted %s", entry->type, entry->fs);
- goto do_free;
+ free_argv(argc, (const char **) argv);
+ free(str);
+ goto done;
}
umount_amd_ext_mount(ap, entry->fs);
}
-
- if (!ext_mount_inuse(entry->fs))
- rmdir_path(ap, entry->fs, ap->dev);
error(ap->logopt, MODPREFIX
"%s: failed to mount using %s", entry->type, entry->mount);
- }
-do_free:
- free_argv(argc, (const char **) argv);
- free(str);
-
- if (rv)
+ free_argv(argc, (const char **) argv);
+ free(str);
goto out;
-
+ }
+done:
rv = do_link_mount(ap, name, entry, 0);
- if (!rv)
- goto out;
-
- if (umount_amd_ext_mount(ap, entry->fs)) {
- if (!ext_mount_inuse(entry->fs))
- rmdir_path(ap, entry->fs, ap->dev);
- debug(ap->logopt, MODPREFIX
- "%s: failed to umount external mount at %s",
- entry->type, entry->fs);
+ if (rv) {
+ if (umount_amd_ext_mount(ap, entry->fs)) {
+ debug(ap->logopt, MODPREFIX
+ "%s: failed to cleanup external mount at %s",
+ entry->type, entry->fs);
+ }
}
out:
return rv;

View File

@ -0,0 +1,242 @@
autofs-5.1.9 - refactor amd function umount_amd_ext_mount()
From: Ian Kent <raven@themaw.net>
The amd mounts function umount_amd_ext_mount() needs some improvement.
Make sure the function returns true for success and false for failure
and add a parameter to control if the expternal mount reference should
be decremented on successful umount.
If the reference count of the external mount is greater than 1 there's
some other mount using (symlink pointing to) it so don't try to umount
it just return success.
Also check for the case where the mount is already mounted.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 4 +-
include/mounts.h | 2 -
lib/mounts.c | 80 ++++++++++++++++++++++++++++++----------------------
modules/parse_amd.c | 10 +++---
5 files changed, 56 insertions(+), 41 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -159,6 +159,7 @@
- fix amd external mount mount handling.
- don't free ext mount if mounted.
- refactor amd function do_program_mount().
+- refactor umount_amd_ext_mount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/automount.c
+++ autofs-5.1.4/daemon/automount.c
@@ -619,7 +619,7 @@ static int umount_subtree_mounts(struct
/* Check for an external mount and umount if possible */
mnt = mnts_find_amdmount(path);
if (mnt) {
- umount_amd_ext_mount(ap, mnt->ext_mp);
+ umount_amd_ext_mount(ap, mnt->ext_mp, 1);
mnts_remove_amdmount(path);
mnts_put_mount(mnt);
}
@@ -684,7 +684,7 @@ int umount_multi(struct autofs_point *ap
/* Check for an external mount and attempt umount if needed */
mnt = mnts_find_amdmount(path);
if (mnt) {
- umount_amd_ext_mount(ap, mnt->ext_mp);
+ umount_amd_ext_mount(ap, mnt->ext_mp, 1);
mnts_remove_amdmount(path);
mnts_put_mount(mnt);
}
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -199,7 +199,7 @@ int try_remount(struct autofs_point *, s
void set_indirect_mount_tree_catatonic(struct autofs_point *);
void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
int umount_ent(struct autofs_point *, const char *);
-int umount_amd_ext_mount(struct autofs_point *, const char *);
+int umount_amd_ext_mount(struct autofs_point *, const char *, int remove);
int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
#endif
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -3097,37 +3097,62 @@ int umount_ent(struct autofs_point *ap,
return mounted;
}
-int umount_amd_ext_mount(struct autofs_point *ap, const char *path)
+int umount_amd_ext_mount(struct autofs_point *ap, const char *path, int remove)
{
struct ext_mount *em;
char *umount = NULL;
- char *mp;
+ char *mp = NULL;
int rv = 1;
+ int ret;
pthread_mutex_lock(&ext_mount_hash_mutex);
-
em = ext_mount_lookup(path);
if (!em) {
pthread_mutex_unlock(&ext_mount_hash_mutex);
+ rv = 0;
goto out;
}
mp = strdup(em->mp);
if (!mp) {
pthread_mutex_unlock(&ext_mount_hash_mutex);
+ rv = 0;
goto out;
}
if (em->umount) {
umount = strdup(em->umount);
if (!umount) {
pthread_mutex_unlock(&ext_mount_hash_mutex);
- free(mp);
+ rv = 0;
goto out;
}
}
-
+ /* Don't try and umount if there's more than one
+ * user of the external mount.
+ */
+ if (em->ref > 1) {
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+ if (!remove)
+ error(ap->logopt,
+ "reference count mismatch, called with remove false");
+ else
+ ext_mount_remove(mp);
+ goto out;
+ }
+ /* This shouldn't happen ... */
+ if (!is_mounted(mp, MNTS_REAL)) {
+ pthread_mutex_unlock(&ext_mount_hash_mutex);
+ error(ap->logopt, "failed to umount program mount at %s", mp);
+ if (remove)
+ ext_mount_remove(mp);
+ goto out;
+ }
pthread_mutex_unlock(&ext_mount_hash_mutex);
- if (umount) {
+ if (!umount) {
+ ret = umount_ent(ap, mp);
+ if (ret)
+ rv = 0;
+ } else {
char *prog;
char **argv;
int argc = -1;
@@ -3136,41 +3161,30 @@ int umount_amd_ext_mount(struct autofs_p
argv = NULL;
argc = construct_argv(umount, &prog, &argv);
- if (argc == -1)
- goto done;
-
- if (!ext_mount_remove(mp)) {
- rv =0;
- goto out_free;
- }
-
- rv = spawnv(ap->logopt, prog, (const char * const *) argv);
- if (rv == -1 || (WIFEXITED(rv) && WEXITSTATUS(rv)))
+ if (argc == -1) {
error(ap->logopt,
- "failed to umount program mount at %s", mp);
- else {
+ "failed to allocate args for umount of %s", mp);
rv = 0;
- debug(ap->logopt, "umounted program mount at %s", mp);
- rmdir_path(ap, mp, ap->dev);
+ goto out;
}
-out_free:
+ ret = spawnv(ap->logopt, prog, (const char * const *) argv);
+ rv = WIFEXITED(ret) && !WEXITSTATUS(ret);
free_argv(argc, (const char **) argv);
-
- goto done;
}
- if (ext_mount_remove(mp)) {
- rv = umount_ent(ap, mp);
- if (rv)
- error(ap->logopt,
- "failed to umount external mount %s", mp);
- else
- debug(ap->logopt, "umounted external mount %s", mp);
+ if (is_mounted(mp, MNTS_REAL))
+ error(ap->logopt,
+ "failed to umount external mount %s", mp);
+ else {
+ info(ap->logopt, "umounted external mount %s", mp);
+ rmdir_path(ap, mp, ap->dev);
}
-done:
+ if (remove)
+ ext_mount_remove(mp);
+out:
if (umount)
free(umount);
- free(mp);
-out:
+ if (mp)
+ free(mp);
return rv;
}
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1133,7 +1133,7 @@ symlink:
if (entry->sublink) {
/* failed to complete sublink mount */
- umount_amd_ext_mount(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs, 1);
}
out:
return ret;
@@ -1184,7 +1184,7 @@ static int do_generic_mount(struct autof
/* If we have an external mount add it to the list */
if (!ext_mount_add(entry->fs, entry->umount)) {
if (umount)
- umount_amd_ext_mount(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs, 0);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s",
entry->fs);
@@ -1235,7 +1235,7 @@ static int do_nfs_mount(struct autofs_po
/* We might be using an external mount */
if (!ext_mount_add(entry->fs, entry->umount)) {
if (umount)
- umount_amd_ext_mount(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs, 0);
error(ap->logopt, MODPREFIX
"error: could not add external mount %s", entry->fs);
ret = 1;
@@ -1470,7 +1470,7 @@ static int do_program_mount(struct autof
free(str);
goto done;
}
- umount_amd_ext_mount(ap, entry->fs);
+ umount_amd_ext_mount(ap, entry->fs, 0);
}
error(ap->logopt, MODPREFIX
"%s: failed to mount using %s", entry->type, entry->mount);
@@ -1481,7 +1481,7 @@ static int do_program_mount(struct autof
done:
rv = do_link_mount(ap, name, entry, 0);
if (rv) {
- if (umount_amd_ext_mount(ap, entry->fs)) {
+ if (!umount_amd_ext_mount(ap, entry->fs, 1)) {
debug(ap->logopt, MODPREFIX
"%s: failed to cleanup external mount at %s",
entry->type, entry->fs);

View File

@ -8,7 +8,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.4
Release: 109%{?dist}
Release: 114%{?dist}.2
Epoch: 1
License: GPLv2+
Group: System Environment/Daemons
@ -326,6 +326,23 @@ Patch324: autofs-5.1.8-fix-some-sss-error-return-cases.patch
Patch325: autofs-5.1.8-fix-incorrect-matching-of-cached-wildcard-key.patch
Patch326: autofs-5.1.8-fix-expire-retry-looping.patch
Patch327: autofs-5.1.8-allow-null-map-in-indirect-maps.patch
Patch328: autofs-5.1.8-fix-multi-mount-check.patch
Patch329: autofs-5.1.9-fix-get-parent-multi-mount-check-in-try_remount.patch
Patch330: autofs-5.1.9-fix-deadlock-in-remount.patch
Patch331: autofs-5.1.9-fix-submount-shutdown-race.patch
Patch332: autofs-5.1.9-fix-amd-external-mount-error-handling.patch
Patch333: autofs-5.1.9-fix-amd-external-mount-mount-handling.patch
Patch334: autofs-5.1.9-dont-free-ext-mount-if-mounted.patch
Patch335: autofs-5.1.9-refactor-amd-function-do_program_mount.patch
Patch336: autofs-5.1.9-refactor-amd-function-umount_amd_ext_mount.patch
Patch337: autofs-5.1.9-add-flags-argument-to-amd-do_program_mount.patch
Patch338: autofs-5.1.9-fix-deadlock-in-master_notify_submount.patch
%if %{with_systemd}
BuildRequires: systemd-units
BuildRequires: systemd-devel
@ -692,6 +709,23 @@ echo %{version}-%{release} > .version
%patch325 -p1
%patch326 -p1
%patch327 -p1
%patch328 -p1
%patch329 -p1
%patch330 -p1
%patch331 -p1
%patch332 -p1
%patch333 -p1
%patch334 -p1
%patch335 -p1
%patch336 -p1
%patch337 -p1
%patch338 -p1
%build
LDFLAGS=-Wl,-z,now
%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc --without-hesiod %{?systemd_configure_arg:}
@ -786,6 +820,46 @@ fi
%dir /etc/auto.master.d
%changelog
* Wed Jan 15 2025 Ian Kent <ikent@redhat.com> - 5.1.4-114.el8_10.2
- RHEL-72524 - autofs: deadlock between mnts_lookup_mount and mnts_remove_mount
- fix deadlock in master_notify_submount().
-Resolves: RHEL-72524
* Fri Nov 08 2024 Ian Kent <ikent@redhat.com> - 5.1.4-114
- RHEL-61670 - sporadic autofs daemon segfaults
- fix submount shutdown race.
- RHEL-52402 - Sporadic mount failures with amd program maps on RHEL8
- fix amd external mount error handling.
- fix amd external mount mount handling.
- don't free ext mount if mounted.
- refactor amd function do_program_mount().
- refactor umount_amd_ext_mount().
- add flags argument to amd do_program_mount().
- Resolves: RHEL-61670 RHEL-52402
* Mon Dec 18 2023 Ian Kent <ikent@redhat.com> - 5.1.4-113
- RHEL-18035 - SIGSEGV using hierarchical map entries on reload with
autofs-5.1.4-109
- fix get parent multi-mount check in try_remount().
- fix deadlock in remount.
- Resolves: RHEL-18035
* Mon Sep 18 2023 Ian Kent <ikent@redhat.com> - 5.1.4-112
- RHEL-7997 - multi mount detection fails for share with blank+dash
causing SEGV crash
-fix multi-mount check.
-Resolves: RHEL-7997
* Mon Sep 18 2023 Ian Kent <ikent@redhat.com> - 5.1.4-111
- RHEL-12369 - autofs attempts to mount nonexistant ".hidden" filesystems
- update patch "allow -null map in indirect maps".
- Resolves: RHEL-12369
* Mon Sep 18 2023 Ian Kent <ikent@redhat.com> - 5.1.4-110
- bz2232402 - autofs attempts to mount nonexistant ".hidden" filesystems
- allow -null map in indirect maps.
- Resolves: rhbz#2232402
* Fri Jul 14 2023 Ian Kent <ikent@redhat.com> - 5.1.4-109
- bz2213267 - filesystems mount and expire immediately
- fix expire retry looping.