Compare commits

...

No commits in common. "imports/c8s/autofs-5.1.4-68.el8" and "c8" have entirely different histories.

89 changed files with 10581 additions and 1 deletions

View File

@ -0,0 +1,41 @@
autofs-5.1.4 - make umount_ent() recognise forced umount
From: Ian Kent <raven@themaw.net>
When doing a forced shutdown umount_ent() tries a normal expire
first resulting in a fair amount of unnecessary log noise.
Change umount_ent() to do a forced expire when a forced shutdown
has been requested to avoid the log noise.
Signed-off-by: Ian Kent <raven@themaw.net>
---
lib/mounts.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2984,14 +2984,16 @@ int umount_ent(struct autofs_point *ap,
{
int rv;
- rv = spawn_umount(ap->logopt, path, NULL);
- /* We are doing a forced shutcwdown down so unlink busy mounts */
- if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
- if (ap->state == ST_SHUTDOWN_FORCE) {
- info(ap->logopt, "forcing umount of %s", path);
- rv = spawn_umount(ap->logopt, "-l", path, NULL);
- }
+ if (ap->state != ST_SHUTDOWN_FORCE)
+ rv = spawn_umount(ap->logopt, path, NULL);
+ else {
+ /* We are doing a forced shutdown so unlink busy
+ * mounts */
+ info(ap->logopt, "forcing umount of %s", path);
+ rv = spawn_umount(ap->logopt, "-l", path, NULL);
+ }
+ if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
/*
* Verify that we actually unmounted the thing. This is a
* belt and suspenders approach to not eating user data.

View File

@ -0,0 +1,36 @@
autofs-5.1.6 - fix double quoting in auto.smb
From: Ian Kent <raven@themaw.net>
The example program mount script installed to /etc/auto.smb incorrectly
adds a quote for the trailing dollar of special Windows mounts. But they
are already surrounded by double quotes. This may have been handled by
mount.cifs at some point but it's failing now.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
samples/auto.smb | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
--- autofs-5.1.4.orig/samples/auto.smb
+++ autofs-5.1.4/samples/auto.smb
@@ -75,8 +75,6 @@ $SMBCLIENT $smbopts -gL "$key" 2>/dev/nu
dir = $2
loc = $2
# Enclose mount dir and location in quotes
- # Double quote "$" in location as it is special
- gsub(/\$$/, "\\$", loc);
gsub(/\&/,"\\\\&",loc)
print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\""
}
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -81,6 +81,7 @@
- fix kernel mount status notification.
- fix set open file limit.
- improve descriptor open error reporting.
+- fix double quoting in auto.smb.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.

View File

@ -0,0 +1,35 @@
autofs-5.1.6 - fix double quoting of ampersand in auto.smb as well
From: Ian Kent <raven@themaw.net>
The example program mount script installed to /etc/auto.smb incorrectly
adds a quote for the & character that causes mount failures. But the
produced map entry is already surrounded by double quotes. This may have
been handled by mount.cifs at some point but it's failing now.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
samples/auto.smb | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.4.orig/samples/auto.smb
+++ autofs-5.1.4/samples/auto.smb
@@ -75,7 +75,6 @@ $SMBCLIENT $smbopts -gL "$key" 2>/dev/nu
dir = $2
loc = $2
# Enclose mount dir and location in quotes
- gsub(/\&/,"\\\\&",loc)
print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\""
}
END { if (!first) print "\n"; else exit 1 }
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -82,6 +82,7 @@
- fix set open file limit.
- improve descriptor open error reporting.
- fix double quoting in auto.smb.
+- fix double quoting of ampersand in auto.smb as well.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.

View File

@ -0,0 +1,47 @@
autofs-5.1.6 - fix empty mounts list return from unlink_mount_tree()
From: Ian Kent <raven@themaw.net>
If there are no appropriate mounts found by get_mnt_list() then
unlink_mount_tree() should return 1 not 0 since if there are no
mounts to umount this shouldn't cause a failure return.
Also, if a real error occurs in get_mnt_list() we should check for
it and return a failure from unlink_mount_tree() since that would
be mount table not found or out of memory. If that's ignored things
would only get worse from that point.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 ++++++--
2 files changed, 7 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -75,6 +75,7 @@
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
- add missing description of null map option.
+- fix empty mounts list return from unlink_mount_tree().
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
@@ -2115,9 +2115,13 @@ int unlink_mount_tree(struct autofs_poin
struct mnt_list *mnts, *mnt;
int rv, ret = 1;
+ errno = 0;
mnts = get_mnt_list(mp, 1);
- if (!mnts)
- return 0;
+ if (!mnts) {
+ if (errno)
+ return 0;
+ return 1;
+ }
for (mnt = mnts; mnt; mnt = mnt->next) {
if (mnt->flags & MNTS_AUTOFS)

View File

@ -0,0 +1,113 @@
autofs-5.1.6 - remove intr hosts map mount option
From: Ian Kent <raven@themaw.net>
Don't use the intr option on NFS mounts by default, it's been ignored
by the kernel for a long time now.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
man/auto.master.5.in | 4 ++--
man/autofs.5 | 4 ++--
modules/parse_sun.c | 9 +++------
samples/auto.misc | 2 +-
samples/auto.net | 2 +-
6 files changed, 10 insertions(+), 12 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -77,6 +77,7 @@
- add missing description of null map option.
- fix empty mounts list return from unlink_mount_tree().
- fix nonstrict offset mount fail handling.
+- remove intr hosts map mount option.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -260,8 +260,8 @@ For example, with an entry in the master
accessing /net/myserver will mount exports from myserver on directories below
/net/myserver.
.P
-NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
-unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the
+NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev" options
+unless overridden by explicitly specifying the "suid", "dev" options in the
master map entry.
.SH BUILTIN MAP \-null
If "\-null" is given as the map it is used to tell automount(8) to ignore a subsequent
--- autofs-5.1.4.orig/man/autofs.5
+++ autofs-5.1.4/man/autofs.5
@@ -86,13 +86,13 @@ Indirect map:
.RS +.2i
.ta 1.0i 3.0i
.nf
-kernel \-ro,soft,intr ftp.kernel.org:/pub/linux
+kernel \-ro,soft ftp.kernel.org:/pub/linux
boot \-fstype=ext2 :/dev/hda1
windoze \-fstype=smbfs ://windoze/c
removable \-fstype=ext2 :/dev/hdd
cd \-fstype=iso9660,ro :/dev/hdc
floppy \-fstype=auto :/dev/fd0
-server \-rw,hard,intr / \-ro myserver.me.org:/ \\
+server \-rw,hard / \-ro myserver.me.org:/ \\
/usr myserver.me.org:/usr \\
/home myserver.me.org:/home
.fi
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -628,10 +628,9 @@ static int sun_mount(struct autofs_point
int len = strlen(options);
int suid = strstr(options, "suid") ? 0 : 7;
int dev = strstr(options, "dev") ? 0 : 6;
- int nointr = strstr(options, "nointr") ? 0 : 5;
- if (suid || dev || nointr) {
- char *tmp = alloca(len + suid + dev + nointr + 1);
+ if (suid || dev) {
+ char *tmp = alloca(len + suid + dev + 1);
if (!tmp) {
error(ap->logopt, MODPREFIX
"alloca failed for options");
@@ -645,8 +644,6 @@ static int sun_mount(struct autofs_point
strcat(tmp, ",nosuid");
if (dev)
strcat(tmp, ",nodev");
- if (nointr)
- strcat(tmp, ",intr");
options = tmp;
}
} else {
@@ -658,7 +655,7 @@ static int sun_mount(struct autofs_point
return -1;
return 1;
}
- strcpy(tmp, "nosuid,nodev,intr");
+ strcpy(tmp, "nosuid,nodev");
options = tmp;
}
}
--- autofs-5.1.4.orig/samples/auto.misc
+++ autofs-5.1.4/samples/auto.misc
@@ -6,7 +6,7 @@
cd -fstype=iso9660,ro,nosuid,nodev :/dev/cdrom
# the following entries are samples to pique your imagination
-#linux -ro,soft,intr ftp.example.org:/pub/linux
+#linux -ro,soft ftp.example.org:/pub/linux
#boot -fstype=ext2 :/dev/hda1
#floppy -fstype=auto :/dev/fd0
#floppy -fstype=ext2 :/dev/fd0
--- autofs-5.1.4.orig/samples/auto.net
+++ autofs-5.1.4/samples/auto.net
@@ -9,7 +9,7 @@ key="$1"
# add "nosymlink" here if you want to suppress symlinking local filesystems
# add "nonstrict" to make it OK for some filesystems to not mount
-opts="-fstype=nfs,hard,intr,nodev,nosuid"
+opts="-fstype=nfs,hard,nodev,nosuid"
for P in /bin /sbin /usr/bin /usr/sbin
do

View File

@ -0,0 +1,104 @@
autofs-5.1.7 - add buffer length checks to autofs mount_mount()
From: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
modules/mount_autofs.c | 59 +++++++++++++++++++++++++++++++++----------------
2 files changed, 41 insertions(+), 19 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -131,6 +131,7 @@
- fix amd selector function matching.
- get rid entry thid field.
- continue expire immediately after submount check.
+- add buffer length checks to autofs mount_mount().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -50,8 +50,8 @@ int mount_mount(struct autofs_point *ap,
{
struct startup_cond suc;
pthread_t thid;
- char realpath[PATH_MAX];
- char mountpoint[PATH_MAX];
+ char realpath[PATH_MAX + 1];
+ char mountpoint[PATH_MAX + 1];
const char **argv;
int argc, status;
int nobind = ap->flags & MOUNT_FLAG_NOBIND;
@@ -68,32 +68,53 @@ int mount_mount(struct autofs_point *ap,
struct mnt_list *mnt;
char buf[MAX_ERR_BUF];
char *options, *p;
- int len, ret;
+ int err, ret;
int hosts = 0;
/* Root offset of multi-mount */
- len = strlen(root);
- if (root[len - 1] == '/') {
- strcpy(realpath, ap->path);
- strcat(realpath, "/");
- strcat(realpath, name);
- len--;
- strncpy(mountpoint, root, len);
- mountpoint[len] = '\0';
+ if (root[strlen(root) - 1] == '/') {
+ err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ mountpoint[err - 1] = 0;
} else if (*name == '/') {
if (ap->flags & MOUNT_FLAG_REMOUNT) {
- strcpy(mountpoint, name);
- strcpy(realpath, name);
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
} else {
- strcpy(mountpoint, root);
- strcpy(realpath, name);
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
+ err = snprintf(realpath, PATH_MAX + 1, "%s", name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for realpath");
+ return 1;
+ }
}
} else {
- strcpy(mountpoint, root);
- strcat(mountpoint, "/");
+ err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name);
+ if (err > PATH_MAX) {
+ error(ap->logopt, MODPREFIX "string too long for mountpoint");
+ return 1;
+ }
strcpy(realpath, mountpoint);
- strcat(mountpoint, name);
- strcat(realpath, name);
}
options = NULL;

View File

@ -0,0 +1,51 @@
autofs-5.1.7 - add missing desciption of null map option
From: Ian Kent <raven@themaw.net>
The description of how the -null master map option behaves is
mising from auto.master(5).
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
man/auto.master.5.in | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -74,6 +74,7 @@
- fix hosts map offset order.
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
+- add missing description of null map option.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/man/auto.master.5.in
+++ autofs-5.1.4/man/auto.master.5.in
@@ -263,6 +263,25 @@ accessing /net/myserver will mount expor
NOTE: mounts done from a hosts map will be mounted with the "nosuid,nodev,intr" options
unless overridden by explicitly specifying the "suid", "dev" or "nointr" options in the
master map entry.
+.SH BUILTIN MAP \-null
+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).
+.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.
+.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
+use of this is allowing local master map entries to override remote ones.
+.P
+NOTE: If a duplicate master map entry path is seen (excluding paths of null entries)
+it will be ignored and noted in the log, that is the first encountered master map
+entry is used unless there is a corresponding null entry.
.SH LDAP MAPS
If the map type \fBldap\fP is specified the mapname is of the form
\fB[//servername/]dn\fP, where the optional \fBservername\fP is

View File

@ -0,0 +1,82 @@
autofs-5.1.7 - eliminate buffer usage from handle_mounts_cleanup()
From: Ian Kent <raven@themaw.net>
This buffer was originally added because a SEGV was seen accessing
the ap->path field on shutdown.
But this was actually caused by calling master_remove_mapent() too
early which adds the map entry to the master map join list that leads
to freeing the autofs_point (ap in the code) which also frees ap->path.
But the master map join list is protected by the master map mutex which
is held until after all the accesses are completed. So whatever the
problem was it doesn't appear to be present any more.
Nevertheless, to be sure, delay the call to master_remove_mapent() until
after all accesses to ap->path are completed.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 13 ++++++-------
2 files changed, 7 insertions(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -140,6 +140,7 @@
- change to use printf functions in amd parser.
- dont call umount_subtree_mounts() on parent at umount.
- dont take parent source lock at mount shutdown.
+- eliminate buffer usage from handle_mounts_cleanup().
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
@@ -1720,7 +1720,6 @@ void handle_mounts_startup_cond_destroy(
static void handle_mounts_cleanup(void *arg)
{
struct autofs_point *ap;
- char path[PATH_MAX + 1];
char buf[MAX_ERR_BUF];
unsigned int clean = 0, submount, logopt;
unsigned int pending = 0;
@@ -1730,7 +1729,6 @@ static void handle_mounts_cleanup(void *
logopt = ap->logopt;
submount = ap->submount;
- strcpy(path, ap->path);
if (!submount && strcmp(ap->path, "/-") &&
ap->flags & MOUNT_FLAG_DIR_CREATED)
clean = 1;
@@ -1752,8 +1750,8 @@ static void handle_mounts_cleanup(void *
/* Don't signal the handler if we have already done so */
if (!list_empty(&master_list->completed))
pending = 1;
- master_remove_mapent(ap->entry);
- master_source_unlock(ap->entry);
+
+ info(logopt, "shut down path %s", ap->path);
/*
* Submounts are detached threads and don't belong to the
@@ -1766,14 +1764,15 @@ static void handle_mounts_cleanup(void *
}
if (clean) {
- if (rmdir(path) == -1) {
+ if (rmdir(ap->path) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
warn(logopt, "failed to remove dir %s: %s",
- path, estr);
+ ap->path, estr);
}
}
- info(logopt, "shut down path %s", path);
+ master_remove_mapent(ap->entry);
+ master_source_unlock(ap->entry);
/*
* If we are not a submount send a signal to the signal handler

View File

@ -0,0 +1,82 @@
autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Since we need to create the offset tree after adding the offset entries
to the mapent cache (from a list.h list) there's no need to lookup the
mapent in tree_mapent_add_node() and validate it. Just use it directly
when calling tree_mapent_add_node() and avoid a cache lookup on every
node addition.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 13 ++-----------
modules/parse_sun.c | 2 +-
4 files changed, 5 insertions(+), 13 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -70,6 +70,7 @@
- fix amd hosts mount expire.
- fix offset entries order.
- use mapent tree root for tree_mapent_add_node().
+- eliminate redundant cache lookup in tree_mapent_add_node().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
void mnts_put_expire_list(struct list_head *mnts);
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
struct tree_node *tree_mapent_root(struct mapent *me);
-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
void tree_mapent_cleanup_offsets(struct mapent *oe);
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree
}
int tree_mapent_add_node(struct mapent_cache *mc,
- struct tree_node *root, const char *key)
+ struct tree_node *root, struct mapent *me)
{
- unsigned int logopt = mc->ap->logopt;
struct tree_node *n;
struct mapent *parent;
- struct mapent *me;
-
- me = cache_lookup_distinct(mc, key);
- if (!me) {
- error(logopt,
- "failed to find key %s of multi-mount", key);
- return 0;
- }
n = tree_add_node(root, me);
if (!n)
@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_c
MAPENT_SET_ROOT(me, root)
/* Set the subtree parent */
- parent = cache_get_offset_parent(mc, key);
+ parent = cache_get_offset_parent(mc, me->key);
if (!parent)
MAPENT_SET_PARENT(me, root)
else
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1548,7 +1548,7 @@ dont_expand:
return 1;
}
list_for_each_entry_safe(oe, tmp, &offsets, work) {
- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe))
error(ap->logopt, "failed to add offset %s to tree", oe->key);
list_del_init(&oe->work);
}

View File

@ -0,0 +1,206 @@
autofs-5.1.7 - eliminate some more alloca usage
From: Ian Kent <raven@themaw.net>
Quite a bit of the alloca(3) usage has been eliminated over time.
Use malloc(3) for some more cases that might need to allocate a largish
amount of storage.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_program.c | 11 ++++++++++-
modules/lookup_yp.c | 22 +++++++++++++++++++---
modules/parse_sun.c | 18 ++++++++++++++----
modules/replicated.c | 19 ++++++-------------
5 files changed, 50 insertions(+), 21 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -143,6 +143,7 @@
- eliminate buffer usage from handle_mounts_cleanup().
- fix possible use after free in handle_mounts_exit().
- make submount cleanup the same as top level mounts.
+- eliminate some more alloca usage.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_program.c
+++ autofs-5.1.4/modules/lookup_program.c
@@ -651,7 +651,14 @@ int lookup_mount(struct autofs_point *ap
char *ent = NULL;
if (me->mapent) {
- ent = alloca(strlen(me->mapent) + 1);
+ ent = malloc(strlen(me->mapent) + 1);
+ if (!ent) {
+ char buf[MAX_ERR_BUF];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ cache_unlock(mc);
+ goto out_free;
+ }
strcpy(ent, me->mapent);
}
cache_unlock(mc);
@@ -659,6 +666,8 @@ int lookup_mount(struct autofs_point *ap
ap->entry->current = source;
ret = ctxt->parse->parse_mount(ap, name,
name_len, ent, ctxt->parse->context);
+ if (ent)
+ free(ent);
goto out_free;
} else {
if (IS_MM(me) && !IS_MM_ROOT(me)) {
--- autofs-5.1.4.orig/modules/lookup_yp.c
+++ autofs-5.1.4/modules/lookup_yp.c
@@ -254,7 +254,7 @@ int yp_all_master_callback(int status, c
len = ypkeylen + 1 + vallen + 2;
- buffer = alloca(len);
+ buffer = malloc(len);
if (!buffer) {
error(logopt, MODPREFIX "could not malloc parse buffer");
return 0;
@@ -267,6 +267,8 @@ int yp_all_master_callback(int status, c
master_parse_entry(buffer, timeout, logging, age);
+ free(buffer);
+
return 0;
}
@@ -368,7 +370,12 @@ int yp_all_callback(int status, char *yp
return 0;
}
- mapent = alloca(vallen + 1);
+ mapent = malloc(vallen + 1);
+ if (!mapent) {
+ error(logopt, MODPREFIX "could not malloc mapent buffer");
+ free(key);
+ return 0;
+ }
strncpy(mapent, val, vallen);
*(mapent + vallen) = '\0';
@@ -377,6 +384,7 @@ int yp_all_callback(int status, char *yp
cache_unlock(mc);
free(key);
+ free(mapent);
if (ret == CHE_FAIL)
return -1;
@@ -922,7 +930,14 @@ int lookup_mount(struct autofs_point *ap
}
if (me && (me->source == source || *me->key == '/')) {
mapent_len = strlen(me->mapent);
- mapent = alloca(mapent_len + 1);
+ mapent = malloc(mapent_len + 1);
+ if (!mapent) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ cache_unlock(mc);
+ free(lkp_key);
+ return NSS_STATUS_TRYAGAIN;
+ }
strcpy(mapent, me->mapent);
}
}
@@ -947,6 +962,7 @@ int lookup_mount(struct autofs_point *ap
ret = ctxt->parse->parse_mount(ap, key, key_len,
mapent, ctxt->parse->context);
+ free(mapent);
if (ret) {
/* Don't update negative cache when re-connecting */
if (ap->flags & MOUNT_FLAG_REMOUNT)
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -672,9 +672,16 @@ static int sun_mount(struct autofs_point
}
}
+ what = malloc(loclen + 1);
+ if (!what) {
+ char buf[MAX_ERR_BUF];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ return 1;
+ }
+
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
if (!strcmp(fstype, "nfs") || !strcmp(fstype, "nfs4")) {
- what = alloca(loclen + 1);
memcpy(what, loc, loclen);
what[loclen] = '\0';
@@ -710,10 +717,10 @@ static int sun_mount(struct autofs_point
rv = mount_nfs->mount_mount(ap, root, name, namelen,
what, fstype, options, mount_nfs->context);
} else {
- if (!loclen)
+ if (!loclen) {
+ free(what);
what = NULL;
- else {
- what = alloca(loclen + 1);
+ } else {
if (*loc == ':') {
loclen--;
memcpy(what, loc + 1, loclen);
@@ -732,6 +739,9 @@ static int sun_mount(struct autofs_point
/* Generic mount routine */
rv = do_mount(ap, root, name, namelen, what, fstype, options);
}
+ if (what)
+ free(what);
+
pthread_setcancelstate(cur_state, NULL);
if (nonstrict && rv)
--- autofs-5.1.4.orig/modules/replicated.c
+++ autofs-5.1.4/modules/replicated.c
@@ -1044,25 +1044,18 @@ done:
return ret;
}
-static int add_path(struct host *hosts, const char *path, int len)
+static int add_path(struct host *hosts, const char *path)
{
struct host *this;
- char *tmp, *tmp2;
-
- tmp = alloca(len + 1);
- if (!tmp)
- return 0;
-
- strncpy(tmp, path, len);
- tmp[len] = '\0';
+ char *tmp;
this = hosts;
while (this) {
if (!this->path) {
- tmp2 = strdup(tmp);
- if (!tmp2)
+ tmp = strdup(path);
+ if (!tmp)
return 0;
- this->path = tmp2;
+ this->path = tmp;
}
this = this->next;
}
@@ -1191,7 +1184,7 @@ int parse_location(unsigned logopt, stru
}
}
- if (!add_path(*hosts, path, strlen(path))) {
+ if (!add_path(*hosts, path)) {
free_host_list(hosts);
free(str);
return 0;

View File

@ -0,0 +1,120 @@
autofs-5.1.7 - fix concat_options() error handling
From: Ian Kent <raven@themaw.net>
There's a possibility of a memory leak in the mount options processing
when calling concat_options() in parse_mount() of the Sun format map
entry parsing.
There's also a case in do_init() of the Sun map format parsing where
a previously freed value is used in a logging statement without being
set to MULL.
So ensure concat_options() always frees it's arguments so that the
handling can be consistent in all places.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 13 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -102,6 +102,7 @@
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
- fix memory leak in update_hosts_mounts().
+- fix concat_options() error handling.
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
@@ -380,7 +380,8 @@ static int do_init(int argc, const char
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "concat_options: %s", estr);
- free(gbl_options);
+ /* freed in concat_options */
+ ctxt->optstr = NULL;
} else
ctxt->optstr = tmp;
} else {
@@ -492,12 +493,16 @@ static char *concat_options(char *left,
char *ret;
if (left == NULL || *left == '\0') {
+ if (!right || *right == '\0')
+ return NULL;
ret = strdup(right);
free(right);
return ret;
}
if (right == NULL || *right == '\0') {
+ if (left == NULL || *left == '\0')
+ return NULL;
ret = strdup(left);
free(left);
return ret;
@@ -508,6 +513,8 @@ static char *concat_options(char *left,
if (ret == NULL) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
logerr(MODPREFIX "malloc: %s", estr);
+ free(left);
+ free(right);
return NULL;
}
@@ -988,14 +995,13 @@ static int parse_mapent(const char *ent,
if (newopt && strstr(newopt, myoptions)) {
free(myoptions);
myoptions = newopt;
- } else {
+ } else if (newopt) {
tmp = concat_options(myoptions, newopt);
if (!tmp) {
char *estr;
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
- free(myoptions);
return 0;
}
myoptions = tmp;
@@ -1363,16 +1369,12 @@ dont_expand:
if (mnt_options && noptions && strstr(noptions, mnt_options)) {
free(mnt_options);
mnt_options = noptions;
- } else {
+ } else if (noptions) {
tmp = concat_options(mnt_options, noptions);
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
MODPREFIX "concat_options: %s", estr);
- if (noptions)
- free(noptions);
- if (mnt_options)
- free(mnt_options);
free(options);
free(pmapent);
return 1;
@@ -1392,15 +1394,11 @@ dont_expand:
if (options && mnt_options && strstr(mnt_options, options)) {
free(options);
options = mnt_options;
- } else {
+ } else if (mnt_options) {
tmp = concat_options(options, mnt_options);
if (!tmp) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "concat_options: %s", estr);
- if (options)
- free(options);
- if (mnt_options)
- free(mnt_options);
free(pmapent);
return 1;
}

View File

@ -0,0 +1,129 @@
autofs-5.1.7 - fix direct mount deadlock
From: Ian Kent <raven@themaw.net>
When umounting direct mounts at exit or when umounting mounts no
longer in the map on re-load a deadlock can occur.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 22 +++++++++++++++++++++-
daemon/state.c | 14 +++++++++-----
3 files changed, 31 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -72,6 +72,7 @@
- use mapent tree root for tree_mapent_add_node().
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
+- fix direct mount deadlock.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg)
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;
+ char key[PATH_MAX + 1];
+ struct mapent *tmp;
int opened = 0;
- left = umount_multi(ap, me->key, 0);
+ if (me->len > PATH_MAX) {
+ error(ap->logopt, "path too long");
+ return 1;
+ }
+ strcpy(key, me->key);
+
+ cache_unlock(mc);
+ left = umount_multi(ap, key, 0);
+ cache_readlock(mc);
+ tmp = cache_lookup_distinct(mc, key);
+ if (tmp != me) {
+ error(ap->logopt, "key %s no longer in mapent cache", key);
+ return -1;
+ }
if (left) {
warn(ap->logopt, "could not unmount %d dirs under %s",
left, me->key);
@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_p
mc = map->mc;
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_readlock(mc);
+restart:
me = cache_enumerate(mc, NULL);
while (me) {
int error;
@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_p
* failed umount.
*/
error = do_umount_autofs_direct(ap, me);
+ /* cache became invalid, restart */
+ if (error == -1)
+ goto restart;
if (!error)
goto done;
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -348,11 +348,12 @@ static void do_readmap_cleanup(void *arg
return;
}
-static void do_readmap_mount(struct autofs_point *ap,
+static int do_readmap_mount(struct autofs_point *ap,
struct map_source *map, struct mapent *me, time_t now)
{
struct mapent_cache *nc;
struct mapent *ne, *nested, *valid;
+ int ret = 0;
nc = ap->entry->master->nc;
@@ -411,7 +412,7 @@ static void do_readmap_mount(struct auto
cache_unlock(vmc);
error(ap->logopt,
"failed to find expected existing valid map entry");
- return;
+ return ret;
}
/* Take over the mount if there is one */
valid->ioctlfd = me->ioctlfd;
@@ -430,14 +431,14 @@ static void do_readmap_mount(struct auto
ap->exp_runfreq = runfreq;
}
} else if (!is_mounted(me->key, MNTS_REAL))
- do_umount_autofs_direct(ap, me);
+ ret = do_umount_autofs_direct(ap, me);
else
debug(ap->logopt,
"%s is mounted", me->key);
} else
do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map));
- return;
+ return ret;
}
static void *do_readmap(void *arg)
@@ -504,9 +505,12 @@ static void *do_readmap(void *arg)
mc = map->mc;
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_readlock(mc);
+restart:
me = cache_enumerate(mc, NULL);
while (me) {
- do_readmap_mount(ap, map, me, now);
+ int ret = do_readmap_mount(ap, map, me, now);
+ if (ret == -1)
+ goto restart;
me = cache_enumerate(mc, me);
}
lookup_prune_one_cache(ap, map->mc, now);

View File

@ -0,0 +1,289 @@
autofs-5.1.7 - fix hosts map offset order
From: Ian Kent <raven@themaw.net>
Map entry offset paths to be in shortest to longest order but exports
from a server could come in any order. If there are a large number of
exports this can result in a lot of overhead when adding the offset
to the ordered list use to mount the offset during parsing since the
path length of exports can cary a lot.
So leverage the tree implemention to sort the export offsets into
shortest to longest order as we go when constructing the mapent from
the exports list.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 2 -
include/mounts.h | 8 +++++
include/rpc_subs.h | 3 ++
lib/mounts.c | 57 +++++++++++++++++++++++++++++++++++++--
modules/lookup_hosts.c | 71 ++++++++++++++++++++++++++++++++++++++-----------
6 files changed, 124 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -71,6 +71,7 @@
- fix offset entries order.
- use mapent tree root for tree_mapent_add_node().
- eliminate redundant cache lookup in tree_mapent_add_node().
+- fix hosts map offset order.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -31,9 +31,9 @@
#include "master.h"
#include "macros.h"
#include "log.h"
+#include "mounts.h"
#include "rpc_subs.h"
#include "parse_subs.h"
-#include "mounts.h"
#include "dev-ioctl-lib.h"
#include "parse_amd.h"
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -52,6 +52,7 @@ extern const unsigned int t_direct;
extern const unsigned int t_offset;
struct mnt_list;
+struct exportinfo;
struct mapent;
struct tree_ops;
@@ -66,6 +67,9 @@ struct tree_node {
#define MNT_LIST(n) (container_of(n, struct mnt_list, node))
#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node)
+#define EXPORTINFO(n) (container_of(n, struct exportinfo, node))
+#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node)
+
#define MAPENT(n) (container_of(n, struct mapent, node))
#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node)
#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root)
@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a
void mnts_remove_mount(const char *mp, unsigned int flags);
struct mnt_list *get_mnt_list(const char *path, int include);
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);
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
void mnts_put_expire_list(struct list_head *mnts);
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
+struct tree_node *tree_host_root(struct exportinfo *exp);
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp);
struct tree_node *tree_mapent_root(struct mapent *me);
int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
--- autofs-5.1.4.orig/include/rpc_subs.h
+++ autofs-5.1.4/include/rpc_subs.h
@@ -23,6 +23,8 @@
#include <linux/nfs2.h>
#include <linux/nfs3.h>
+#include "automount.h"
+
#define NFS4_VERSION 4
/* rpc helper subs */
@@ -57,6 +59,7 @@ struct exportinfo {
char *dir;
struct hostinfo *hosts;
struct exportinfo *next;
+ struct tree_node node;
};
struct conn_info {
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
};
static struct tree_ops *tree_mnt_ops = &mnt_ops;
+static struct tree_node *tree_host_new(void *ptr);
+static int tree_host_cmp(struct tree_node *n, void *ptr);
+static void tree_host_free(struct tree_node *n);
+
+static struct tree_ops host_ops = {
+ .new = tree_host_new,
+ .cmp = tree_host_cmp,
+ .free = tree_host_free,
+};
+static struct tree_ops *tree_host_ops = &host_ops;
+
static struct tree_node *tree_mapent_new(void *ptr);
static int tree_mapent_cmp(struct tree_node *n, void *ptr);
static void tree_mapent_free(struct tree_node *n);
@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s
return NULL;
}
-static void tree_free(struct tree_node *root)
+void tree_free(struct tree_node *root)
{
struct tree_ops *ops = root->ops;
@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *
ops->free(root);
}
-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
{
int ret;
@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he
mnts_hash_mutex_unlock();
}
+struct tree_node *tree_host_root(struct exportinfo *exp)
+{
+ return tree_root(tree_host_ops, exp);
+}
+
+static struct tree_node *tree_host_new(void *ptr)
+{
+ struct tree_node *n = EXPORT_NODE(ptr);
+
+ n->ops = tree_host_ops;
+ n->left = NULL;
+ n->right = NULL;
+
+ return n;
+}
+
+static int tree_host_cmp(struct tree_node *n, void *ptr)
+{
+ struct exportinfo *n_exp = EXPORTINFO(n);
+ size_t n_exp_len = strlen(n_exp->dir);
+ struct exportinfo *exp = ptr;
+ size_t exp_len = strlen(exp->dir);
+ int eq;
+
+ eq = strcmp(exp->dir, n_exp->dir);
+ if (!eq)
+ return 0;
+ return (exp_len < n_exp_len) ? -1 : 1;
+}
+
+static void tree_host_free(struct tree_node *n)
+{
+ n->ops = NULL;
+ n->left = NULL;
+ n->right = NULL;
+}
+
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp)
+{
+ return tree_add_node(root, exp);
+}
+
struct tree_node *tree_mapent_root(struct mapent *me)
{
return tree_root(tree_mapent_ops, me);
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma
return NSS_STATUS_UNKNOWN;
}
+struct work_info {
+ char *mapent;
+ const char *host;
+ int pos;
+};
+
+static int tree_host_work(struct tree_node *n, void *ptr)
+{
+ struct exportinfo *exp = EXPORTINFO(n);
+ struct work_info *wi = ptr;
+ int len;
+
+ if (!wi->pos)
+ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"",
+ exp->dir, wi->host, exp->dir);
+ else
+ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"",
+ exp->dir, wi->host, exp->dir);
+ wi->pos += len;
+
+ return 1;
+}
+
static char *get_exports(struct autofs_point *ap, const char *host)
{
char buf[MAX_ERR_BUF];
char *mapent;
struct exportinfo *exp, *this;
+ struct tree_node *tree = NULL;
+ struct work_info wi;
size_t hostlen = strlen(host);
size_t mapent_len;
- int len, pos;
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p
this = exp;
mapent_len = 0;
while (this) {
+ struct tree_node *n;
+
mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
+
+ if (!tree) {
+ tree = tree_host_root(this);
+ if (!tree) {
+ error(ap->logopt, "failed to create exports tree root");
+ rpc_exports_free(exp);
+ return NULL;
+ }
+ goto next;
+ }
+
+ n = tree_host_add_node(tree, this);
+ if (!n) {
+ error(ap->logopt, "failed to add exports tree node");
+ tree_free(tree);
+ rpc_exports_free(exp);
+ return NULL;
+ }
+next:
this = this->next;
}
@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p
}
*mapent = 0;
- pos = 0;
- this = exp;
- if (this) {
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
- }
-
- while (this) {
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
- this->dir, host, this->dir);
- pos += len;
- this = this->next;
+ wi.mapent = mapent;
+ wi.host = host;
+ wi.pos = 0;
+
+ if (!tree) {
+ free(mapent);
+ mapent = NULL;
+ } else {
+ tree_traverse_inorder(tree, tree_host_work, &wi);
+ tree_free(tree);
}
rpc_exports_free(exp);

View File

@ -0,0 +1,40 @@
autofs-5.1.7 - fix incorrect print format specifiers in get_pkt()
From: Ian Kent <raven@themaw.net>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -115,6 +115,7 @@
- make amd mapent search function name clear.
- rename statemachine() to signal_handler().
- make signal handling consistent.
+- fix incorrect print format specifiers in get_pkt().
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
@@ -1105,7 +1105,7 @@ static int get_pkt(struct autofs_point *
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
"read error on state pipe, "
- "read %u, error %s",
+ "read %lu, error %s",
read, estr);
st_mutex_unlock();
continue;
@@ -1123,7 +1123,7 @@ static int get_pkt(struct autofs_point *
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
"read error on request pipe, "
- "read %u, expected %u error %s",
+ "read %lu, expected %lu error %s",
read, kpkt_len, estr);
}
return read;

View File

@ -0,0 +1,56 @@
autofs-5.1.7 - fix lookup_prune_one_cache() refactoring change
From: Ian Kent <raven@themaw.net>
Commit 256963d6b (autofs-5.1.7 - refactor lookup_prune_one_cache() a bit)
changed the position of the getting the next enumeration map entry but
failed to update a couple of other locations that assume the next map
entry has been set. Under certain fairly common conditions this leads
to an infinite loop.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -73,6 +73,7 @@
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
- fix direct mount deadlock.
+- fix lookup_prune_one_cache() refactoring change.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -1387,6 +1387,7 @@ void lookup_prune_one_cache(struct autof
if (!key || strchr(key, '*')) {
if (key)
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1394,6 +1395,7 @@ void lookup_prune_one_cache(struct autof
if (!path) {
warn(ap->logopt, "can't malloc storage for path");
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1421,9 +1423,10 @@ void lookup_prune_one_cache(struct autof
}
if (!valid &&
is_mounted(path, MNTS_REAL)) {
- debug(ap->logopt, "prune posponed, %s mounted", path);
+ debug(ap->logopt, "prune postponed, %s mounted", path);
free(key);
free(path);
+ me = cache_enumerate(mc, me);
continue;
}
if (valid)

View File

@ -0,0 +1,54 @@
autofs-5.1.7 - fix nonstrict offset mount fail handling
From: Ian Kent <raven@themaw.net>
If a triggered offset mount fails automount is not handling nonstrict
mount failure correctly.
The nonstrict mount failure handling needs to convert an offset mount
failure to a success if the offset subtree below the failed mount is not
empty otherwise it must return the failure. The previous implementation
used -1 to indicate the subtree was empty and that was used to detect
when the mount should fail instead of converting the fail to a success.
Make the new implementation do the same.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
modules/parse_sun.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -76,6 +76,7 @@
- fix lookup_prune_one_cache() refactoring change.
- add missing description of null map option.
- fix empty mounts list return from unlink_mount_tree().
+- fix nonstrict offset mount fail handling.
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
@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(
{
struct traverse_subtree_context *ctxt = ptr;
struct mapent *oe = MAPENT(n);
- int ret = 1;
+ int ret = -1;
if (n->left) {
ret = tree_mapent_traverse_subtree(n->left, work, ctxt);
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1183,7 +1183,7 @@ static int mount_subtree(struct autofs_p
* offsets to be mounted.
*/
rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt);
- if (rv == 0) {
+ if (rv <= 0) {
ret = tree_mapent_mount_offsets(me, 1);
if (!ret) {
tree_mapent_cleanup_offsets(me);

View File

@ -0,0 +1,199 @@
autofs-5.1.7 - fix offset entries order
From: Ian Kent <raven@themaw.net>
While it's rare it's possible that a mapent entry might not have
it's offsets in shortest to longest path order.
If this happens adding an entry to the mapent tree can result in
an incorrect tree topology that doesn't work. That's because adding
tree entries ensures that nodes in a sub-tree are placed below the
containing node so the containing node must be present for that to
work. This topology is critical to the performance of map entries
that have a very large number of offsets such as an NFS server with
many exports.
There's no other choice but make a traversal after the offset entries
have all been added to create the mapent tree.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 1
lib/cache.c | 1
modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++-----------
4 files changed, 62 insertions(+), 15 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -68,6 +68,7 @@
- add ext_mount_hash_mutex lock helpers.
- fix amd section mounts map reload.
- fix amd hosts mount expire.
+- fix offset entries order.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -169,6 +169,7 @@ struct mapent {
/* Parent nesting point within multi-mount */
struct tree_node *mm_parent;
struct tree_node node;
+ struct list_head work;
char *key;
size_t len;
char *mapent;
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s
me->mm_parent = NULL;
INIT_TREE_NODE(&me->node);
INIT_LIST_HEAD(&me->ino_index);
+ INIT_LIST_HEAD(&me->work);
me->ioctlfd = -1;
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -791,14 +791,15 @@ static int check_is_multi(const char *ma
static int
update_offset_entry(struct autofs_point *ap,
- struct mapent_cache *mc, const char *name,
- const char *m_root, int m_root_len,
+ struct mapent_cache *mc, struct list_head *offsets,
+ const char *name, const char *m_root, int m_root_len,
const char *m_offset, const char *myoptions,
const char *loc, time_t age)
{
char m_key[PATH_MAX + 1];
char m_mapent[MAPENT_MAX_LEN + 1];
int o_len, m_key_len, m_options_len, m_mapent_len;
+ struct mapent *me;
int ret;
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
@@ -864,8 +865,29 @@ update_offset_entry(struct autofs_point
cache_writelock(mc);
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
- if (!tree_mapent_add_node(mc, name, m_key))
- error(ap->logopt, "failed to add offset %s to tree", m_key);
+ me = cache_lookup_distinct(mc, m_key);
+ if (me && list_empty(&me->work)) {
+ struct list_head *last;
+
+ /* Offset entries really need to be in shortest to
+ * longest path order. If not and the list of offsets
+ * is large there will be a performace hit.
+ */
+ list_for_each_prev(last, offsets) {
+ struct mapent *this;
+
+ this = list_entry(last, struct mapent, work);
+ if (me->len >= this->len) {
+ if (last->next == offsets)
+ list_add_tail(&me->work, offsets);
+ else
+ list_add_tail(&me->work, last);
+ break;
+ }
+ }
+ if (list_empty(&me->work))
+ list_add(&me->work, offsets);
+ }
cache_unlock(mc);
if (ret == CHE_DUPLICATE) {
@@ -1211,6 +1233,25 @@ static char *do_expandsunent(const char
return mapent;
}
+static void cleanup_offset_entries(struct autofs_point *ap,
+ struct mapent_cache *mc,
+ struct list_head *offsets)
+{
+ struct mapent *me, *tmp;
+ int ret;
+
+ if (list_empty(offsets))
+ return;
+ cache_writelock(mc);
+ list_for_each_entry_safe(me, tmp, offsets, work) {
+ list_del(&me->work);
+ ret = cache_delete(mc, me->key);
+ if (ret != CHE_OK)
+ crit(ap->logopt, "failed to delete offset %s", me->key);
+ }
+ cache_unlock(mc);
+}
+
/*
* syntax is:
* [-options] location [location] ...
@@ -1230,7 +1271,8 @@ int parse_mount(struct autofs_point *ap,
char buf[MAX_ERR_BUF];
struct map_source *source;
struct mapent_cache *mc;
- struct mapent *me;
+ struct mapent *me, *oe, *tmp;
+ LIST_HEAD(offsets);
char *pmapent, *options;
const char *p;
int mapent_len, rv = 0;
@@ -1446,9 +1488,7 @@ dont_expand:
if (!m_offset) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(options);
free(pmapent);
pthread_setcancelstate(cur_state, NULL);
@@ -1463,9 +1503,7 @@ dont_expand:
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
if (!l) {
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(m_offset);
free(options);
free(pmapent);
@@ -1476,15 +1514,13 @@ dont_expand:
p += l;
p = skipspace(p);
- status = update_offset_entry(ap, mc,
+ status = update_offset_entry(ap, mc, &offsets,
name, m_root, m_root_len,
m_offset, myoptions, loc, age);
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
- cache_writelock(mc);
- tree_mapent_delete_offsets(mc, name);
- cache_unlock(mc);
+ cleanup_offset_entries(ap, mc, &offsets);
free(m_offset);
free(options);
free(pmapent);
@@ -1501,6 +1537,14 @@ dont_expand:
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
+ cache_writelock(mc);
+ list_for_each_entry_safe(oe, tmp, &offsets, work) {
+ if (!tree_mapent_add_node(mc, name, oe->key))
+ error(ap->logopt, "failed to add offset %s to tree", oe->key);
+ list_del_init(&oe->work);
+ }
+ cache_unlock(mc);
+
rv = mount_subtree(ap, mc, name, NULL, options, ctxt);
free(options);

View File

@ -0,0 +1,111 @@
autofs-5.1.7 - use mapent tree root for tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Since we need to create the offset tree after adding the offset entries
to the mapent cache lookup the root mapent once and use it when calling
tree_mapent_add_node() instread of doing a cache lookup on every node
addition.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 24 +++++-------------------
modules/parse_sun.c | 11 ++++++++++-
4 files changed, 17 insertions(+), 21 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -69,6 +69,7 @@
- fix amd section mounts map reload.
- fix amd hosts mount expire.
- fix offset entries order.
+- use mapent tree root for tree_mapent_add_node().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
void mnts_put_expire_list(struct list_head *mnts);
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
struct tree_node *tree_mapent_root(struct mapent *me);
-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key);
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
void tree_mapent_cleanup_offsets(struct mapent *oe);
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree
}
int tree_mapent_add_node(struct mapent_cache *mc,
- const char *root, const char *key)
+ struct tree_node *root, const char *key)
{
unsigned int logopt = mc->ap->logopt;
- struct tree_node *tree, *n;
- struct mapent *base;
+ struct tree_node *n;
struct mapent *parent;
struct mapent *me;
- base = cache_lookup_distinct(mc, root);
- if (!base) {
- error(logopt,
- "failed to find multi-mount root for key %s", key);
- return 0;
- }
-
- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) {
- error(logopt, "key %s is not multi-mount root", root);
- return 0;
- }
- tree = MAPENT_ROOT(base);
-
me = cache_lookup_distinct(mc, key);
if (!me) {
error(logopt,
@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_c
return 0;
}
- n = tree_add_node(tree, me);
+ n = tree_add_node(root, me);
if (!n)
return 0;
- MAPENT_SET_ROOT(me, tree)
+ MAPENT_SET_ROOT(me, root)
/* Set the subtree parent */
parent = cache_get_offset_parent(mc, key);
if (!parent)
- MAPENT_SET_PARENT(me, tree)
+ MAPENT_SET_PARENT(me, root)
else
MAPENT_SET_PARENT(me, MAPENT_NODE(parent))
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1538,8 +1538,17 @@ dont_expand:
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
cache_writelock(mc);
+ me = cache_lookup_distinct(mc, name);
+ if (!me) {
+ cache_unlock(mc);
+ free(options);
+ free(pmapent);
+ cleanup_offset_entries(ap, mc, &offsets);
+ pthread_setcancelstate(cur_state, NULL);
+ return 1;
+ }
list_for_each_entry_safe(oe, tmp, &offsets, work) {
- if (!tree_mapent_add_node(mc, name, oe->key))
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
error(ap->logopt, "failed to add offset %s to tree", oe->key);
list_del_init(&oe->work);
}

View File

@ -0,0 +1,310 @@
autofs-5.1.8 - add command pipe handling functions
From: Ian Kent <raven@themaw.net>
In order to use a single file handle for a command pipe the pipe needs
to be independent of the kernel message packet handling function.
Add most of the functions needed for this as preperation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 270 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -119,6 +119,7 @@
- eliminate last remaining state_pipe usage.
- add function master_find_mapent_by_devid().
- use device id to locate autofs_point when setting log priotity.
+- add command pipe handling functions.
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
@@ -60,6 +60,14 @@ unsigned int nfs_mount_uses_string_optio
static struct nfs_mount_vers vers, check = {1, 1, 1};
#define FIFO_BUF_SIZE 25
+static int cmd_pipe_fifo = -1;
+
+/* autofs cmd fifo name */
+#define FIFO_NAME "autofs.cmd.fifo"
+const char *cmd_pipe_name = AUTOFS_FIFO_DIR "/" FIFO_NAME;
+
+int start_cmd_pipe_handler(void);
+void finish_cmd_pipe_handler(void);
/* autofs fifo name prefix */
#define FIFO_NAME_PREFIX "autofs.fifo"
@@ -1650,6 +1658,267 @@ static void *signal_handler(void *arg)
}
}
+static pthread_mutex_t cmd_pipe_mutex = PTHREAD_MUTEX_INITIALIZER;
+static unsigned int done = 0;
+static pthread_t cmd_pipe_thid;
+
+void cmd_pipe_mutex_lock(void)
+{
+ int status = pthread_mutex_lock(&cmd_pipe_mutex);
+ if (status)
+ fatal(status);
+}
+
+void cmd_pipe_mutex_unlock(void)
+{
+ int status = pthread_mutex_unlock(&cmd_pipe_mutex);
+ if (status)
+ fatal(status);
+}
+
+static int create_cmd_pipe_fifo(void)
+{
+ char buf[MAX_ERR_BUF];
+ int ret = -1;
+ int fd;
+
+ if (cmd_pipe_fifo != -1)
+ return 0;
+
+ ret = unlink(cmd_pipe_name);
+ if (ret != 0 && errno != ENOENT) {
+ fprintf(stderr,
+ "%s: failed to unlink command pipe. Is the "
+ "automount daemon already running?", program);
+ return ret;
+ }
+
+ ret = mkfifo(cmd_pipe_name, S_IRUSR|S_IWUSR);
+ if (ret != 0 && errno != EEXIST) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ fprintf(stderr, "%s: mkfifo for %s failed: %s",
+ program, cmd_pipe_name, estr);
+ return ret;
+ }
+
+ fd = open_fd(cmd_pipe_name, O_RDWR|O_NONBLOCK);
+ if (fd < 0) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ unlink(cmd_pipe_name);
+ fprintf(stderr, "%s: failed to open cwcommand pipe %s: %s",
+ program, cmd_pipe_name, estr);
+ return -1;
+ }
+
+ cmd_pipe_fifo = fd;
+
+ return 0;
+}
+
+static int destroy_cmd_pipe_fifo(void)
+{
+ char buf[MAX_ERR_BUF];
+ int ret = -1;
+
+ if (cmd_pipe_fifo == -1)
+ return 0;
+
+ ret = close(cmd_pipe_fifo);
+ if (ret != 0) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(LOGOPT_ANY,
+ "close for command pipe %s: %s", cmd_pipe_name, estr);
+ }
+
+ cmd_pipe_fifo = -1;
+
+ ret = unlink(cmd_pipe_name);
+ if (ret != 0) {
+ warn(LOGOPT_ANY,
+ "failed to unlink FIFO. Was the fifo created OK?");
+ }
+
+ return 0;
+}
+
+static void handle_cmd_pipe_fifo_message(int fd)
+{
+ struct autofs_point *ap;
+ char buffer[PIPE_BUF];
+ char *end, *sep;
+ char buf[MAX_ERR_BUF];
+ dev_t devid;
+ int ret;
+ long pri;
+
+ memset(buffer, 0, sizeof(buffer));
+ ret = read(fd, &buffer, sizeof(buffer));
+ if (ret < 0) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(LOGOPT_ANY,
+ "read on command pipe returned error: %s", estr);
+ return;
+ }
+
+ sep = strrchr(buffer, ' ');
+ if (!sep) {
+ error(LOGOPT_ANY,
+ "incorrect command pipe message format %s.", buffer);
+ return;
+ }
+ sep++;
+
+ errno = 0;
+ devid = strtol(buffer, &end, 10);
+ if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) {
+ debug(LOGOPT_ANY, "strtol reported a range error.");
+ error(LOGOPT_ANY, "invalid command pipe message format %s.", buffer);
+ return;
+ }
+
+ if ((devid == 0 && errno == EINVAL) || end == buffer) {
+ debug(LOGOPT_ANY, "devid id is expected to be a integer.");
+ return;
+ }
+
+ ap = master_find_mapent_by_devid(master_list, devid);
+ if (!ap) {
+ error(LOGOPT_ANY, "can't locate autofs_point for device id %ld.", devid);
+ return;
+ }
+
+ errno = 0;
+ pri = strtol(sep, &end, 10);
+ if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) {
+ error(ap->logopt, "failed to set log priority.");
+ error(ap->logopt, "strtol reported an %s.",
+ pri == LONG_MIN ? "underflow" : "overflow");
+ return;
+ }
+
+ if ((pri == 0 && errno == EINVAL) || end == sep) {
+ debug(ap->logopt, "priority is expected to be an integer "
+ "in the range 0-7 inclusive.");
+ return;
+ }
+
+ if (pri > LOG_DEBUG || pri < LOG_EMERG) {
+ debug(ap->logopt,
+ "invalid log priority (%ld) received on fifo", pri);
+ return;
+ }
+
+ /*
+ * OK, the message passed all of the sanity checks. The
+ * automounter actually only supports three log priorities.
+ * Everything is logged at log level debug, deamon messages
+ * and everything except debug messages are logged with the
+ * verbose setting and only error and critical messages are
+ * logged when debugging isn't enabled.
+ */
+ if (pri >= LOG_WARNING) {
+ if (pri == LOG_DEBUG) {
+ set_log_debug_ap(ap);
+ info(ap->logopt, "debug logging set for %s", ap->path);
+ } else {
+ set_log_verbose_ap(ap);
+ info(ap->logopt, "verbose logging set for %s", ap->path);
+ }
+ } else {
+ if (ap->logopt & LOGOPT_ANY)
+ info(ap->logopt, "basic logging set for %s", ap->path);
+ set_log_norm_ap(ap);
+ }
+}
+
+static void cmd_pipe_dummy(int sig)
+{
+}
+
+static void *cmd_pipe_handler(void *arg)
+{
+ struct sigaction sa;
+ sigset_t signalset;
+ struct pollfd fds[1];
+ int pollfds = 1;
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
+ if (create_cmd_pipe_fifo())
+ return NULL;
+
+ fds[0].fd = cmd_pipe_fifo;
+ fds[0].events = POLLIN;
+
+ sa.sa_handler = cmd_pipe_dummy;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGPIPE, &sa, NULL) == -1) {
+ error(LOGOPT_ANY, "failed to set signal handler %d", errno);
+ return NULL;
+ }
+
+ sigfillset(&signalset);
+ sigdelset(&signalset, SIGPIPE);
+
+ while (1) {
+ cmd_pipe_mutex_lock();
+ if (done) {
+ cmd_pipe_mutex_unlock();
+ break;
+ }
+ cmd_pipe_mutex_unlock();
+
+ errno = 0;
+ if (ppoll(fds, pollfds, NULL, &signalset) == -1) {
+ if (errno == EINTR)
+ continue;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr("poll failed: %s", estr);
+ return NULL;
+ }
+
+ if (fds[0].revents & POLLIN) {
+ debug(LOGOPT_ANY, "message pending on control fifo.");
+ handle_cmd_pipe_fifo_message(fds[0].fd);
+ }
+ }
+ destroy_cmd_pipe_fifo();
+ return NULL;
+}
+
+int start_cmd_pipe_handler(void)
+{
+ pthread_t thid;
+ pthread_attr_t attrs;
+ pthread_attr_t *pattrs = &attrs;
+ int status;
+
+ status = pthread_attr_init(pattrs);
+ if (status)
+ pattrs = NULL;
+ else
+ pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED);
+
+ status = pthread_create(&thid, pattrs, cmd_pipe_handler, NULL);
+
+ if (pattrs)
+ pthread_attr_destroy(pattrs);
+
+ if (!status)
+ cmd_pipe_thid = thid;
+
+ return !status;
+}
+
+void finish_cmd_pipe_handler(void)
+{
+ cmd_pipe_mutex_lock();
+ done = 1;
+ pthread_kill(cmd_pipe_thid, SIGPIPE);
+ cmd_pipe_mutex_unlock();
+}
+
static void return_start_status(void *arg)
{
struct startup_cond *sc;

View File

@ -0,0 +1,125 @@
autofs-5.1.8 - add function master_find_mapent_by_devid()
From: Ian Kent <raven@themaw.net>
Add a helper function that can locate an automount given its device id.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 28 ++++++++++++++++++++++++++++
include/master.h | 1 +
include/mounts.h | 1 +
lib/mounts.c | 34 ++++++++++++++++++++++++++++++++++
5 files changed, 65 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -117,6 +117,7 @@
- make signal handling consistent.
- fix incorrect print format specifiers in get_pkt().
- eliminate last remaining state_pipe usage.
+- add function master_find_mapent_by_devid().
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
@@ -739,6 +739,34 @@ struct master_mapent *master_find_mapent
return NULL;
}
+struct autofs_point *master_find_mapent_by_devid(struct master *master, dev_t devid)
+{
+ struct autofs_point *ap = NULL;
+ struct list_head *head, *p;
+
+ master_mutex_lock();
+
+ head = &master->mounts;
+ list_for_each(p, head) {
+ struct master_mapent *entry;
+
+ entry = list_entry(p, struct master_mapent, list);
+
+ if (entry->ap->dev == devid) {
+ ap = entry->ap;
+ break;
+ }
+
+ ap = mnt_find_submount_by_devid(&entry->ap->submounts, devid);
+ if (ap)
+ break;
+ }
+
+ master_mutex_unlock();
+
+ return ap;
+}
+
static unsigned int master_partial_match_amd_mapent(struct master *master, const char *path)
{
struct list_head *head, *p;
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -110,6 +110,7 @@ void master_source_lock_cleanup(void *);
void master_source_current_wait(struct master_mapent *);
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
+struct autofs_point *master_find_mapent_by_devid(struct master *master, dev_t devid);
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
void master_add_mapent(struct master *, struct master_mapent *);
void master_remove_mapent(struct master_mapent *);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -160,6 +160,7 @@ int ext_mount_inuse(const char *);
struct mnt_list *mnts_lookup_mount(const char *mp);
void mnts_put_mount(struct mnt_list *mnt);
struct mnt_list *mnts_find_submount(const char *path);
+struct autofs_point *mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid);
struct mnt_list *mnts_add_submount(struct autofs_point *ap);
void mnts_remove_submount(const char *mp);
struct mnt_list *mnts_find_amdmount(const char *path);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1059,6 +1059,40 @@ struct mnt_list *mnts_find_submount(cons
return NULL;
}
+static struct autofs_point *__mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid)
+{
+ struct autofs_point *ap = NULL;
+ struct list_head *p;
+
+ list_for_each(p, submounts) {
+ struct mnt_list *this;
+
+ this = list_entry(p, struct mnt_list, submount);
+
+ if (this->ap->dev == devid) {
+ ap = this->ap;
+ break;
+ }
+
+ ap = mnt_find_submount_by_devid(&this->ap->submounts, devid);
+ if (ap)
+ break;
+ }
+
+ return ap;
+}
+
+struct autofs_point *mnt_find_submount_by_devid(struct list_head *submounts, dev_t devid)
+{
+ struct autofs_point *ap = NULL;
+
+ mnts_hash_mutex_lock();
+ ap = __mnt_find_submount_by_devid(submounts, devid);
+ mnts_hash_mutex_unlock();
+
+ return ap;
+}
+
struct mnt_list *mnts_add_submount(struct autofs_point *ap)
{
struct mnt_list *this;

View File

@ -0,0 +1,270 @@
autofs-5.1.8 - add ioctlfd open helper
From: Ian Kent <raven@themaw.net>
Add an ioctl fd open helper, it simplifies the code in some areas.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/direct.c | 25 ++++++++--------
daemon/indirect.c | 9 ++---
include/mounts.h | 3 +
lib/mounts.c | 82 ++++++++++++++++++++++++++++++------------------------
5 files changed, 68 insertions(+), 52 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -145,6 +145,7 @@
- make submount cleanup the same as top level mounts.
- eliminate some more alloca usage.
- add soucre parameter to module functions.
+- add ioctlfd open helper.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -121,7 +121,9 @@ int do_umount_autofs_direct(struct autof
}
ioctlfd = me->ioctlfd;
} else {
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
+ if (ioctlfd == -1)
+ return 1;
opened = 1;
}
@@ -317,8 +319,7 @@ int do_mount_autofs_direct(struct autofs
save_ioctlfd = ioctlfd = me->ioctlfd;
if (ioctlfd == -1)
- ops->open(ap->logopt,
- &ioctlfd, me->dev, me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
if (ioctlfd < 0) {
error(ap->logopt,
@@ -416,7 +417,7 @@ int do_mount_autofs_direct(struct autofs
if (ap->mode && (err = chmod(me->key, ap->mode)))
warn(ap->logopt, "failed to change mode of %s", me->key);
- ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
if (ioctlfd < 0) {
crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
goto out_umount;
@@ -540,7 +541,9 @@ int umount_autofs_offset(struct autofs_p
me->key);
return 0;
}
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
+ if (ioctlfd == -1)
+ return 1;
opened = 1;
}
@@ -770,11 +773,9 @@ int mount_autofs_offset(struct autofs_po
me->dev = st.st_dev;
me->ino = st.st_ino;
- ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
- if (ioctlfd < 0) {
- crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
+ if (ioctlfd < 0)
goto out_umount;
- }
ops->timeout(ap->logopt, ioctlfd, timeout);
cache_set_ino_index(me->mc, me);
@@ -1059,9 +1060,9 @@ int handle_packet_expire_direct(struct a
/* Can't expire it if it isn't mounted */
if (me->ioctlfd == -1) {
int ioctlfd;
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
+
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
if (ioctlfd == -1) {
- crit(ap->logopt, "can't open ioctlfd for %s", me->key);
cache_unlock(mc);
master_source_unlock(ap->entry);
pthread_setcancelstate(state, NULL);
@@ -1355,8 +1356,8 @@ int handle_packet_missing_direct(struct
close(me->ioctlfd);
me->ioctlfd = -1;
}
- ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
+ ioctlfd = open_ioctlfd(ap, me->key, me->dev);
if (ioctlfd == -1) {
cache_unlock(mc);
master_source_unlock(ap->entry);
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -124,18 +124,18 @@ static int do_mount_autofs_indirect(stru
"failed to stat mount for autofs path %s", ap->path);
goto out_umount;
}
+ ap->dev = st.st_dev; /* Device number for mount point checks */
if (ap->mode && (err = chmod(ap->path, ap->mode)))
warn(ap->logopt, "failed to change mode of %s", ap->path);
- if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, ap->path)) {
+ ap->ioctlfd = open_ioctlfd(ap, ap->path, ap->dev);
+ if (ap->ioctlfd == -1) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
goto out_umount;
}
- ap->dev = st.st_dev; /* Device number for mount point checks */
-
ops->timeout(ap->logopt, ap->ioctlfd, timeout);
notify_mount_result(ap, ap->path, timeout, str_indirect);
@@ -284,8 +284,7 @@ int umount_autofs_indirect(struct autofs
return 0;
}
#endif
- ops->open(ap->logopt,
- &ap->ioctlfd, ap->dev, ap->path);
+ ap->ioctlfd = open_ioctlfd(ap, ap->path, ap->dev);
if (ap->ioctlfd < 0) {
warn(ap->logopt,
"could not recover autofs path %s",
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -151,6 +151,9 @@ void free_amd_entry_list(struct list_hea
unsigned int query_kproto_ver(void);
unsigned int get_kver_major(void);
unsigned int get_kver_minor(void);
+
+int open_ioctlfd(struct autofs_point *ap, const char *path, dev_t dev);
+
char *make_options_string(char *path, int pipefd,
const char *type, unsigned int flags);
char *make_mnt_name_string(char *path);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -231,6 +231,32 @@ unsigned int get_kver_minor(void)
return kver.minor;
}
+int open_ioctlfd(struct autofs_point *ap, const char *path, dev_t dev)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+ int fd = -1;
+ int error;
+
+ error = ops->open(ap->logopt, &fd, dev, path);
+ if (error == -1) {
+ char buf[MAX_ERR_BUF];
+ int err = errno;
+ char *estr;
+
+ if (errno == ENOENT)
+ return -1;
+
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt,
+ "failed to open ioctlfd for %s, error: %s",
+ path, estr);
+ errno = err;
+ return -1;
+ }
+
+ return fd;
+}
+
#ifdef HAVE_MOUNT_NFS
static int extract_version(char *start, struct nfs_mount_vers *vers)
{
@@ -2719,7 +2745,7 @@ static int remount_active_mount(struct a
*ioctlfd = -1;
/* Open failed, no mount present */
- ops->open(ap->logopt, &fd, devid, path);
+ fd = open_ioctlfd(ap, path, devid);
if (fd == -1)
return REMOUNT_OPEN_FAIL;
@@ -2918,10 +2944,9 @@ static int set_mount_catatonic(struct au
{
struct ioctl_ops *ops = get_ioctl_ops();
unsigned int opened = 0;
- char buf[MAX_ERR_BUF];
- char *path;
- int fd = -1;
- int error;
+ const char *path;
+ int fd;
+ int err;
dev_t dev;
path = ap->path;
@@ -2936,44 +2961,31 @@ static int set_mount_catatonic(struct au
else if (me && me->ioctlfd >= 0)
fd = me->ioctlfd;
else {
- error = ops->open(ap->logopt, &fd, dev, path);
- if (error == -1) {
- int err = errno;
- char *estr;
-
- if (errno == ENOENT)
- return 0;
-
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt,
- "failed to open ioctlfd for %s, error: %s",
- path, estr);
- return err;
- }
+ fd = open_ioctlfd(ap, path, dev);
+ if (fd == -1)
+ return (errno == ENOENT ? 0 : errno);
opened = 1;
}
- if (fd >= 0) {
- error = ops->catatonic(ap->logopt, fd);
- if (error == -1) {
- int err = errno;
- char *estr;
+ err = ops->catatonic(ap->logopt, fd);
+ if (err == -1) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt,
- "failed to set %s catatonic, error: %s",
- path, estr);
- if (opened)
- ops->close(ap->logopt, fd);
- return err;
- }
- if (opened)
- ops->close(ap->logopt, fd);
+ err = errno;
+ estr = strerror_r(err, buf, MAX_ERR_BUF);
+ error(ap->logopt,
+ "failed to set %s catatonic, error: %s",
+ path, estr);
+ goto out;
}
debug(ap->logopt, "set %s catatonic", path);
+out:
+ if (opened)
+ ops->close(ap->logopt, fd);
- return 0;
+ return err;
}
static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr)

File diff suppressed because it is too large Load Diff

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,35 @@
autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id
From: Ian Kent <raven@themaw.net>
Don't call pthread_getspecific() if key_thread_attempt_id is NULL in
case the pthread_getspecific() implementation doesn't check for this.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/log.c | 3 +++
2 files changed, 4 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -90,6 +90,7 @@
- simplify cache_add() a little.
- fix use after free in tree_mapent_delete_offset_tree().
- fix memory leak in xdr_exports().
+- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/log.c
+++ autofs-5.1.4/lib/log.c
@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(cons
char buffer[ATTEMPT_ID_SIZE + 1];
char *prefixed_msg = NULL;
+ if (!key_thread_attempt_id)
+ return NULL;
+
attempt_id = pthread_getspecific(key_thread_attempt_id);
if (attempt_id) {
int len = sizeof(buffer) + 1 + strlen(msg) + 1;

View File

@ -0,0 +1,144 @@
autofs-5.1.8 - change to use printf functions in amd parser
From: Ian Kent <raven@themaw.net>
Change to use the printf(3) functions in the amd parser rather than
string functions. These functions seem to have less overhead and they
are a little more compact.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 45 +++++++++++++++++----------------------------
2 files changed, 18 insertions(+), 28 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -137,6 +137,7 @@
- get rid of strlen call in handle_packet_missing_direct().
- remove redundant stat call in lookup_ghost().
- set mapent dev and ino before adding to index.
+- change to use printf functions in amd parser.
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
@@ -170,11 +170,9 @@ static struct substvar *add_lookup_vars(
if (*key == '/')
strcpy(path, key);
- else {
- strcpy(path, ap->path);
- strcat(path, "/");
- strcat(path, key);
- }
+ else
+ sprintf(path, "%s/%s", ap->path, key);
+
list = macro_addvar(list, "path", 4, path);
me = cache_lookup_distinct(source->mc, lkp_key);
@@ -1067,24 +1065,23 @@ static int do_auto_mount(struct autofs_p
struct amd_entry *entry, unsigned int flags)
{
char target[PATH_MAX + 1];
+ int len;
if (!entry->map_type) {
- if (strlen(entry->fs) > PATH_MAX) {
+ len = snprintf(target, PATH_MAX, "%s", entry->fs);
+ if (len > PATH_MAX) {
error(ap->logopt, MODPREFIX
"error: fs option length is too long");
return 0;
}
- strcpy(target, entry->fs);
} else {
- if (strlen(entry->fs) +
- strlen(entry->map_type) + 5 > PATH_MAX) {
+ len = snprintf(target, PATH_MAX,
+ "%s,amd:%s", entry->map_type, entry->fs);
+ if (len > PATH_MAX) {
error(ap->logopt, MODPREFIX
"error: fs + maptype options length is too long");
return 0;
}
- strcpy(target, entry->map_type);
- strcat(target, ",amd:");
- strcat(target, entry->fs);
}
return do_mount(ap, ap->path,
@@ -1207,17 +1204,15 @@ static int do_nfs_mount(struct autofs_po
char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL;
unsigned int umount = 0;
int ret = 0;
+ int len;
- if (strlen(entry->rhost) + strlen(entry->rfs) + 1 > PATH_MAX) {
+ len = snprintf(target, PATH_MAX, "%s:%s", entry->rhost, entry->rfs);
+ if (len > PATH_MAX) {
error(ap->logopt, MODPREFIX
"error: rhost + rfs options length is too long");
return 1;
}
- strcpy(target, entry->rhost);
- strcat(target, ":");
- strcat(target, entry->rfs);
-
proximity = get_network_proximity(entry->rhost);
if (proximity == PROXIMITY_OTHER && entry->remopts && *entry->remopts)
opts = entry->remopts;
@@ -1319,7 +1314,7 @@ static int do_host_mount(struct autofs_p
*/
if (strcmp(name, entry->rhost)) {
char *target;
- size_t len;
+ int len;
len = ap->len + strlen(entry->rhost) + 2;
target = malloc(len);
@@ -1328,9 +1323,7 @@ static int do_host_mount(struct autofs_p
"failed to alloc target to hosts mount base");
goto out;
}
- strcpy(target, ap->path);
- strcat(target, "/");
- strcat(target, entry->rhost);
+ sprintf(target, "%s/%s", ap->path, entry->rhost);
if (entry->path)
free(entry->path);
entry->path = target;
@@ -1819,7 +1812,7 @@ static void normalize_sublink(unsigned i
struct amd_entry *entry, struct substvar *sv)
{
char *new;
- size_t len;
+ int len;
/* Normalizing sublink requires a non-blank fs option */
if (!*entry->fs)
@@ -1833,9 +1826,7 @@ static void normalize_sublink(unsigned i
"error: couldn't allocate storage for sublink");
return;
}
- strcpy(new, entry->fs);
- strcat(new, "/");
- strcat(new, entry->sublink);
+ sprintf(new, "%s/%s", entry->fs, entry->sublink);
debug(logopt, MODPREFIX
"rfs dequote(\"%.*s\") -> %s",
strlen(entry->sublink), entry->sublink, new);
@@ -1866,9 +1857,7 @@ static void update_prefix(struct autofs_
len = strlen(ap->pref) + strlen(name) + 2;
new = malloc(len);
if (new) {
- strcpy(new, ap->pref);
- strcat(new, name);
- strcat(new, "/");
+ sprintf(new, "%s%s/", ap->pref, name);
entry->pref = new;
}
}

View File

@ -0,0 +1,56 @@
autofs-5.1.8 - continue expire immediately after submount check
From: Ian Kent <raven@themaw.net>
The expire proc for both direct and indirect mounts doesn't immediately
continue after seeing an autofs submount and sending it a notification.
Add the "continue" to avoid some wasted overhead.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 5 ++++-
daemon/indirect.c | 5 ++++-
3 files changed, 9 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -130,6 +130,7 @@
- include addtional log info for mounts.
- fix amd selector function matching.
- get rid entry thid field.
+- continue expire immediately after submount check.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -854,8 +854,11 @@ void *expire_proc_direct(void *arg)
* one of them and pass on state change.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- if (mnt->flags & MNTS_AUTOFS)
+ if (mnt->flags & MNTS_AUTOFS) {
master_notify_submount(ap, mnt->mp, ap->state);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
if (me->ioctlfd == -1) {
pthread_setcancelstate(cur_state, NULL);
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -392,8 +392,11 @@ void *expire_proc_indirect(void *arg)
* one of them and pass on the state change.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- if (mnt->flags & MNTS_AUTOFS)
+ if (mnt->flags & MNTS_AUTOFS) {
master_notify_submount(ap, mnt->mp, ap->state);
+ pthread_setcancelstate(cur_state, NULL);
+ continue;
+ }
/* An offset without a real mount, check for manual umount */
if (mnt->flags & MNTS_OFFSET &&

View File

@ -0,0 +1,32 @@
autofs-5.1.8 - coverity fix for invalid access
From: Ian Kent <raven@themaw.net>
Fix invalid access in modules/parse_amd.c:do_host_mount().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -98,6 +98,7 @@
- fix invalid tsv access.
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
+- coverity fix for invalid access.
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
@@ -1366,7 +1366,6 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- close_lookup(lookup);
goto out;
}
}

View File

@ -0,0 +1,40 @@
autofs-5.1.8 - dont call umount_subtree_mounts() on parent at umount
From: Ian Kent <raven@themaw.net>
There shouldn't be any multi-mount offsets mounted within a submount
because the submount will be a nesting point and offsets will be mounted
within it when it gets mounted and expired before it's umounted.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 -------
2 files changed, 1 insertion(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -138,6 +138,7 @@
- remove redundant stat call in lookup_ghost().
- set mapent dev and ino before adding to index.
- change to use printf functions in amd parser.
+- dont call umount_subtree_mounts() on parent at umount.
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
@@ -706,13 +706,6 @@ int umount_multi(struct autofs_point *ap
left = 0;
- /*
- * If we are a submount we need to umount any offsets our
- * parent may have mounted over top of us.
- */
- if (ap->submount)
- left += umount_subtree_mounts(ap->parent, path, 1);
-
left += umount_subtree_mounts(ap, path, is_autofs_fs);
/* Delete detritus like unwanted mountpoints and symlinks */

View File

@ -0,0 +1,47 @@
autofs-5.1.8 - don't close lookup at umount
From: Ian Kent <raven@themaw.net>
Since map sources are reference counted they persist beyond autofs
submounts.
Now the map source moudule lookup gets closed at submount umount and
if we are unlucky enough to be using the same map in other submounts
and a lookup is underway at the time of the umount a crash can occur.
To resolve this it's much better to just not close the lookup at
submount umount and rely on the map source free to close the module
lookup and instances when the map source is no longer referenced.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 -------
2 files changed, 1 insertion(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -109,6 +109,7 @@
- improve handling of ENOENT in sss setautomntent().
- don't immediately call function when waiting.
- fix return status of mount_autofs().
+- don't close lookup at umount.
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
@@ -737,13 +737,6 @@ static int umount_autofs(struct autofs_p
if (ap->state == ST_INIT)
return -1;
- /*
- * Since lookup.c is lazy about closing lookup modules
- * to prevent unneeded opens, we need to clean them up
- * before umount.
- */
- lookup_close_lookup(ap);
-
if (ap->type == LKP_INDIRECT) {
umount_all(ap);
ret = umount_autofs_indirect(ap, root);

View File

@ -0,0 +1,94 @@
autofs-5.1.8 - dont delay expire
From: Ian Kent <raven@themaw.net>
There's a delay on expire of submounts that can be as much as the
expire timeout. This was originally an attempt to reduce re-reading
the map but it can cause very long delays on expire.
So get rid of the delay and allow submounts to expire normally.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 9 ++++-----
daemon/state.c | 30 ++++--------------------------
3 files changed, 9 insertions(+), 31 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -111,6 +111,7 @@
- fix return status of mount_autofs().
- don't close lookup at umount.
- fix deadlock in lookups.
+- dont delay expire.
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
@@ -1250,17 +1250,16 @@ int master_notify_submount(struct autofs
st_wait_task(this->ap, state, 0);
/*
- * If our submount gets to state ST_SHUTDOWN, ST_SHUTDOWN_PENDING or
- * ST_SHUTDOWN_FORCE we need to wait until it goes away or changes
- * to ST_READY.
+ * If our submount gets to state ST_SHUTDOWN_PENDING or
+ * 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;
- if (sbmnt->ap->state != ST_SHUTDOWN &&
- sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
+ if (sbmnt->ap->state != ST_SHUTDOWN_PENDING &&
sbmnt->ap->state != ST_SHUTDOWN_FORCE) {
ret = 0;
mnts_put_mount(sbmnt);
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -123,36 +123,14 @@ void expire_cleanup(void *arg)
/*
* If we're a submount and we've just pruned or
* expired everything away, try to shut down.
- *
- * Since we use the the fact that a mount will not
- * expire for at least ap->exp_timeout to avoid a
- * mount <-> expire race we need to wait before
- * letting a submount expire away. We also need
- * them to go away fairly quickly so the owner
- * mount expires in a reasonable time. Just skip
- * one expire check after it's no longer busy before
- * allowing it to shutdown.
- *
- * But if this mount point is an amd format map it
- * is better to keep the mount around longer. This
- * is because of the common heavy reuse of maps in
- * amd maps and we want to try and avoid constantly
- * re-reading large maps.
*/
if (ap->submount && !success) {
rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle);
- if (!rv && idle && ap->submount > 1) {
- struct map_source *map = ap->entry->maps;
-
- if (ap->submount > 4 ||
- !(map->flags & MAP_FLAG_FORMAT_AMD)) {
- next = ST_SHUTDOWN_PENDING;
- break;
- }
+ if (!rv && idle) {
+ next = ST_SHUTDOWN_PENDING;
+ break;
}
- ap->submount++;
- } else if (ap->submount > 1)
- ap->submount = 1;
+ }
if (ap->state == ST_EXPIRE)
conditional_alarm_add(ap, ap->exp_runfreq);

View File

@ -0,0 +1,46 @@
autofs-5.1.8 - dont fail on duplicate host export entry
From: Ian Kent <raven@themaw.net>
If we encounter a duplicate host export entry don't fail, just ignore
it and return the duplicate.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -85,6 +85,7 @@
- fix double quoting of ampersand in auto.smb as well.
- fix root offset error handling.
- fix nonstrict fail handling of last offset mount.
+- dont fail on duplicate offset entry tree add.
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
@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(s
}
if (!eq)
- error(LOGOPT_ANY, "cannot add duplicate entry to tree");
+ return p;
else {
if (eq < 0)
return tree_add_left(p, ptr);
@@ -1515,8 +1515,10 @@ static int tree_host_cmp(struct tree_nod
int eq;
eq = strcmp(exp->dir, n_exp->dir);
- if (!eq)
+ if (!eq) {
+ error(LOGOPT_ANY, "duplicate entry %s ignored", exp->dir);
return 0;
+ }
return (exp_len < n_exp_len) ? -1 : 1;
}

View File

@ -0,0 +1,101 @@
autofs-5.1.8 - dont immediately call function when waiting
From: Ian Kent <raven@themaw.net>
When autofs needs to wait for a sss connection the connection function
is immediately called a second time without first waiting. Adjust the
calling so that there's a wait before the next call.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_sss.c | 24 ++++++++++++------------
2 files changed, 13 insertions(+), 12 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -107,6 +107,7 @@
- fix incorrect path for is_mounted() in try_remount().
- fail on empty replicated host name.
- improve handling of ENOENT in sss setautomntent().
+- don't immediately call function when waiting.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_sss.c
+++ autofs-5.1.4/modules/lookup_sss.c
@@ -338,10 +338,13 @@ static int setautomntent_wait(unsigned i
"can't connect to sssd, retry for %d seconds",
retries);
- while (++retry <= retries) {
+ while (++retry < retries) {
struct timespec t = { SSS_WAIT_INTERVAL, 0 };
struct timespec r;
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+
ret = ctxt->setautomntent(ctxt->mapname, sss_ctxt);
if (proto_version(ctxt) == 0) {
if (ret != ENOENT)
@@ -355,9 +358,6 @@ static int setautomntent_wait(unsigned i
free(*sss_ctxt);
*sss_ctxt = NULL;
}
-
- while (nanosleep(&t, &r) == -1 && errno == EINTR)
- memcpy(&t, &r, sizeof(struct timespec));
}
if (!ret)
@@ -475,10 +475,13 @@ static int getautomntent_wait(unsigned i
"can't contact sssd to to get map entry, retry for %d seconds",
retries);
- while (++retry <= retries) {
+ while (++retry < retries) {
struct timespec t = { SSS_WAIT_INTERVAL, 0 };
struct timespec r;
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+
ret = ctxt->getautomntent_r(key, value, sss_ctxt);
if (proto_version(ctxt) == 0) {
if (ret != ENOENT)
@@ -487,9 +490,6 @@ static int getautomntent_wait(unsigned i
if (ret != EHOSTDOWN)
break;
}
-
- while (nanosleep(&t, &r) == -1 && errno == EINTR)
- memcpy(&t, &r, sizeof(struct timespec));
}
if (!ret)
@@ -600,10 +600,13 @@ static int getautomntbyname_wait(unsigne
"can't contact sssd to to lookup key value, retry for %d seconds",
retries);
- while (++retry <= retries) {
+ while (++retry < retries) {
struct timespec t = { SSS_WAIT_INTERVAL, 0 };
struct timespec r;
+ while (nanosleep(&t, &r) == -1 && errno == EINTR)
+ memcpy(&t, &r, sizeof(struct timespec));
+
ret = ctxt->getautomntbyname_r(key, value, sss_ctxt);
if (proto_version(ctxt) == 0) {
if (ret != ENOENT)
@@ -612,9 +615,6 @@ static int getautomntbyname_wait(unsigne
if (ret != EHOSTDOWN)
break;
}
-
- while (nanosleep(&t, &r) == -1 && errno == EINTR)
- memcpy(&t, &r, sizeof(struct timespec));
}
if (!ret)

View File

@ -0,0 +1,118 @@
autofs-5.1.8 - dont take parent source lock at mount shutdown
From: Ian Kent <raven@themaw.net>
There shouldn't be any need to take the parent source lock at autofs mount
shutdown so don't take it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 60 ++---------------------------------------------------
2 files changed, 4 insertions(+), 57 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -139,6 +139,7 @@
- set mapent dev and ino before adding to index.
- change to use printf functions in amd parser.
- dont call umount_subtree_mounts() on parent at umount.
+- dont take parent source lock at mount shutdown.
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
@@ -1761,7 +1761,6 @@ static void handle_mounts_cleanup(void *
* here.
*/
if (submount) {
- master_source_unlock(ap->parent->entry);
master_free_mapent_sources(ap->entry, 1);
master_free_mapent(ap->entry);
}
@@ -1789,36 +1788,6 @@ static void handle_mounts_cleanup(void *
return;
}
-static int submount_source_writelock_nested(struct autofs_point *ap)
-{
- struct autofs_point *parent = ap->parent;
- int status;
-
- status = pthread_rwlock_trywrlock(&parent->entry->source_lock);
- if (status)
- goto done;
-
- status = pthread_rwlock_trywrlock(&ap->entry->source_lock);
- if (status)
- master_source_unlock(parent->entry);
-
-done:
- if (status && status != EBUSY) {
- logmsg("submount nested master_mapent source write lock failed");
- fatal(status);
- }
-
- return status;
-}
-
-static void submount_source_unlock_nested(struct autofs_point *ap)
-{
- struct autofs_point *parent = ap->parent;
-
- master_source_unlock(ap->entry);
- master_source_unlock(parent->entry);
-}
-
int handle_mounts_exit(struct autofs_point *ap)
{
int ret, cur_state;
@@ -1833,33 +1802,13 @@ int handle_mounts_exit(struct autofs_poi
master_mutex_lock();
- if (!ap->submount)
- master_source_writelock(ap->entry);
- else {
- /*
- * If a mount request arrives before the locks are
- * aquired just return to ready state.
- */
- ret = submount_source_writelock_nested(ap);
- if (ret) {
- warn(ap->logopt,
- "can't shutdown submount: mount in progress");
- /* Return to ST_READY is done immediately */
- st_add_task(ap, ST_READY);
- master_mutex_unlock();
- pthread_setcancelstate(cur_state, NULL);
- return 0;
- }
- }
+ master_source_writelock(ap->entry);
if (ap->state != ST_SHUTDOWN) {
conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
- if (ap->submount)
- submount_source_unlock_nested(ap);
- else
- master_source_unlock(ap->entry);
+ master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(cur_state, NULL);
@@ -1900,10 +1849,7 @@ int handle_mounts_exit(struct autofs_poi
conditional_alarm_add(ap, ap->exp_runfreq);
/* Return to ST_READY is done immediately */
st_add_task(ap, ST_READY);
- if (ap->submount)
- submount_source_unlock_nested(ap);
- else
- master_source_unlock(ap->entry);
+ master_source_unlock(ap->entry);
master_mutex_unlock();
pthread_setcancelstate(cur_state, NULL);

View File

@ -0,0 +1,131 @@
autofs-5.1.8 - dont use initgroups() at spawn
From: Ian Kent <raven@themaw.net>
The initgroups(3) function isn't safe to use between fork() and
exec() in a threaded program.
Using it this way often leads to a hang for even moderate work
loads.
But the getgrouplist()/setgroups() combination can be used safely
in this case and this patch changes autofs to use these (the safety
of using of setgroups() is yet to to be documented).
A large portion of the work on this patch has been contributed
by Roberto Bergantinos <rbergant@redhat.com>.
Reported-by: Roberto Bergantinos <rbergant@redhat.com>
Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()")
Signed-off-by: Roberto Bergantinos <rbergant@redhat.com>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 48 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -94,6 +94,7 @@
- fix sysconf(3) return handling.
- remove nonstrict parameter from tree_mapent_umount_offsets().
- fix handling of incorrect return from umount_ent().
+- dont use initgroups() at spawn.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/spawn.c
+++ autofs-5.1.4/daemon/spawn.c
@@ -26,6 +26,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <pwd.h>
#include "automount.h"
@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, uns
struct thread_stdenv_vars *tsv;
pid_t euid = 0;
gid_t egid = 0;
+ gid_t *groups = NULL;
+ gid_t *saved_groups = NULL;
+ int ngroups = 0;
+ int nsaved_groups = 0;
if (open_pipe(pipefd))
return -1;
@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, uns
}
open_mutex_lock();
+
+ if (euid) {
+ struct passwd *pwd;
+
+ pwd = getpwuid(getuid());
+ if (!pwd)
+ fprintf(stderr,
+ "warning: getpwuid: can't get current username\n");
+ else {
+ /* get number of groups for current gid */
+ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups);
+ saved_groups = malloc(nsaved_groups * sizeof(gid_t));
+
+ /* get current gid groups list */
+ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups);
+ }
+
+ /* get number of groups of mount triggering process */
+ getgrouplist(tsv->user, egid, NULL, &ngroups);
+ groups = malloc(ngroups * sizeof(gid_t));
+
+ /* get groups list of mount triggering process */
+ getgrouplist(tsv->user, egid, groups, &ngroups);
+ }
+
f = fork();
if (f == 0) {
char **pargv = (char **) argv;
@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, uns
if (!tsv->user)
fprintf(stderr,
"warning: can't init groups\n");
- else if (initgroups(tsv->user, egid) == -1)
- fprintf(stderr,
- "warning: initgroups: %s\n",
- strerror(errno));
+ else if (groups) {
+ if (setgroups(ngroups, groups) == -1)
+ fprintf(stderr,
+ "warning: setgroups: %s\n",
+ strerror(errno));
+ free(groups);
+ }
if (setegid(egid) == -1)
fprintf(stderr,
@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, uns
strerror(errno));
if (pgrp >= 0)
setpgid(0, pgrp);
+ /* Reset groups for trigger of trailing mount */
+ if (euid && saved_groups) {
+ setgroups(nsaved_groups, saved_groups);
+ free(saved_groups);
+ }
/*
* The kernel leaves mount type autofs alone because
@@ -474,6 +512,11 @@ done:
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
open_mutex_unlock();
+ if (groups)
+ free(groups);
+ if (saved_groups)
+ free(saved_groups);
+
close(pipefd[1]);
if (f < 0) {

View File

@ -0,0 +1,292 @@
autofs-5.1.8 - eliminate last remaining state_pipe usage
From: Ian Kent <raven@themaw.net>
Eliminate the last remaining usage autofs mount struct state_pipe that
is used when changing state to ST_SHUTDOWN at submount exit. Ths single
usage consumes a pipe file handle pair for every autofs file system
mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 78 ++++++++++++++++++++--------------------------------
daemon/direct.c | 2 -
daemon/indirect.c | 7 ----
daemon/master.c | 21 ++------------
daemon/state.c | 16 +++-------
include/automount.h | 1
include/state.h | 1
8 files changed, 40 insertions(+), 87 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -116,6 +116,7 @@
- rename statemachine() to signal_handler().
- make signal handling consistent.
- fix incorrect print format specifiers in get_pkt().
+- eliminate last remaining state_pipe usage.
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
@@ -1063,58 +1063,51 @@ static int set_log_priority(const char *
return 0;
}
+static void dummy(int sig)
+{
+}
+
static int get_pkt(struct autofs_point *ap, union autofs_v5_packet_union *pkt)
{
- struct pollfd fds[3];
- int pollfds = 3;
+ struct sigaction sa;
+ sigset_t signalset;
+ struct pollfd fds[2];
+ int pollfds = 2;
char buf[MAX_ERR_BUF];
size_t read;
char *estr;
fds[0].fd = ap->pipefd;
fds[0].events = POLLIN;
- fds[1].fd = ap->state_pipe[0];
+ fds[1].fd = ap->logpri_fifo;
fds[1].events = POLLIN;
- fds[2].fd = ap->logpri_fifo;
- fds[2].events = POLLIN;
- if (fds[2].fd == -1)
+ if (fds[1].fd == -1)
pollfds--;
- for (;;) {
- if (poll(fds, pollfds, -1) == -1) {
- if (errno == EINTR)
- continue;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr("poll failed: %s", estr);
- return -1;
- }
-
- if (fds[1].revents & POLLIN) {
- enum states next_state;
- size_t read_size = sizeof(next_state);
- int state_pipe;
+ sa.sa_handler = dummy;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGCONT, &sa, NULL) == -1)
+ error(LOGOPT_ANY, "failed to set signal handler %d", errno);
- next_state = ST_INVAL;
+ sigfillset(&signalset);
+ sigdelset(&signalset, SIGCONT);
- st_mutex_lock();
-
- state_pipe = ap->state_pipe[0];
-
- read = fullread(state_pipe, &next_state, read_size);
- if (read) {
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt,
- "read error on state pipe, "
- "read %lu, error %s",
- read, estr);
+ for (;;) {
+ errno = 0;
+ if (ppoll(fds, pollfds, NULL, &signalset) == -1) {
+ if (errno == EINTR) {
+ st_mutex_lock();
+ if (ap->state == ST_SHUTDOWN) {
+ st_mutex_unlock();
+ return -1;
+ }
st_mutex_unlock();
continue;
}
-
- st_mutex_unlock();
-
- if (next_state == ST_SHUTDOWN)
- return -1;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr("poll failed: %s", estr);
+ return -1;
}
if (fds[0].revents & POLLIN) {
@@ -1129,9 +1122,9 @@ static int get_pkt(struct autofs_point *
return read;
}
- if (fds[2].fd != -1 && fds[2].revents & POLLIN) {
+ if (fds[1].fd != -1 && fds[1].revents & POLLIN) {
debug(ap->logopt, "message pending on control fifo.");
- handle_fifo_message(ap, fds[2].fd);
+ handle_fifo_message(ap, fds[1].fd);
}
}
}
@@ -1191,15 +1184,6 @@ static int autofs_init_ap(struct autofs_
ap->pipefd = pipefd[0];
ap->kpipefd = pipefd[1];
- /* Pipe state changes from signal handler to main loop */
- if (open_pipe(ap->state_pipe) < 0) {
- crit(ap->logopt,
- "failed create state pipe for autofs path %s", ap->path);
- close(ap->pipefd);
- close(ap->kpipefd); /* Close kernel pipe end */
- return -1;
- }
-
if (create_logpri_fifo(ap) < 0) {
logmsg("could not create FIFO for path %s\n", ap->path);
logmsg("dynamic log level changes not available for %s", ap->path);
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -263,8 +263,6 @@ done:
}
pthread_cleanup_pop(1);
- close(ap->state_pipe[0]);
- close(ap->state_pipe[1]);
if (ap->pipefd >= 0)
close(ap->pipefd);
if (ap->kpipefd >= 0) {
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -152,8 +152,6 @@ out_rmdir:
out_err:
if (options)
free(options);
- close(ap->state_pipe[0]);
- close(ap->state_pipe[1]);
close(ap->pipefd);
close(ap->kpipefd);
@@ -216,11 +214,6 @@ void close_mount_fds(struct autofs_point
if (ap->submount)
lookup_source_close_ioctlfd(ap->parent, ap->path);
- close(ap->state_pipe[0]);
- close(ap->state_pipe[1]);
- ap->state_pipe[0] = -1;
- ap->state_pipe[1] = -1;
-
if (ap->pipefd >= 0)
close(ap->pipefd);
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -112,8 +112,6 @@ int master_add_autofs_point(struct maste
ap->state = ST_INIT;
- ap->state_pipe[0] = -1;
- ap->state_pipe[1] = -1;
ap->logpri_fifo = -1;
ap->path = strdup(entry->path);
@@ -1390,7 +1388,7 @@ static int master_do_mount(struct master
handle_mounts_startup_cond_destroy(&suc);
return 0;
}
- entry->thid = thid;
+ entry->thid = ap->thid = thid;
handle_mounts_startup_cond_destroy(&suc);
@@ -1474,9 +1472,6 @@ int master_mount_mounts(struct master *m
struct master_mapent *this;
struct autofs_point *ap;
struct mapent *ne, *nested;
- struct stat st;
- int state_pipe, save_errno;
- int ret;
this = list_entry(p, struct master_mapent, list);
p = p->next;
@@ -1533,19 +1528,9 @@ int master_mount_mounts(struct master *m
}
cache_unlock(nc);
cont:
- st_mutex_lock();
-
- state_pipe = this->ap->state_pipe[1];
-
- /* No pipe so mount is needed */
- ret = fstat(state_pipe, &st);
- save_errno = errno;
-
- st_mutex_unlock();
-
- if (!ret)
+ if (ap->thid && is_mounted(this->path, MNTS_AUTOFS))
check_update_map_sources(this, master->readall);
- else if (ret == -1 && save_errno == EBADF) {
+ else {
if (!master_do_mount(this)) {
list_del_init(&this->list);
master_free_mapent_sources(ap->entry, 1);
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -76,16 +76,6 @@ void dump_state_queue(void)
}
}
-void nextstate(int statefd, enum states next)
-{
- char buf[MAX_ERR_BUF];
-
- if (write(statefd, &next, sizeof(next)) != sizeof(next)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr("write failed %s", estr);
- }
-}
-
/*
* Handle expire thread cleanup and return the next state the system
* should enter as a result.
@@ -655,12 +645,16 @@ static unsigned int st_force_shutdown(st
static unsigned int st_shutdown(struct autofs_point *ap)
{
+ int ret;
+
debug(ap->logopt, "state %d path %s", ap->state, ap->path);
assert(ap->state == ST_SHUTDOWN_PENDING || ap->state == ST_SHUTDOWN_FORCE);
ap->state = ST_SHUTDOWN;
- nextstate(ap->state_pipe[1], ST_SHUTDOWN);
+ ret = pthread_kill(ap->thid, SIGCONT);
+ if (ret)
+ error(LOGOPT_ANY, "error %d sending shutdown signal", ret);
return 0;
}
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -563,7 +563,6 @@ struct autofs_point {
pthread_t exp_thread; /* Thread that is expiring */
pthread_t readmap_thread; /* Thread that is reading maps */
enum states state; /* Current state */
- int state_pipe[2]; /* State change router pipe */
struct autofs_point *parent; /* Owner of mounts list for submount */
struct list_head mounts; /* List of autofs mounts at current level */
unsigned int submount; /* Is this a submount */
--- autofs-5.1.4.orig/include/state.h
+++ autofs-5.1.4/include/state.h
@@ -86,7 +86,6 @@ void st_mutex_unlock(void);
void expire_cleanup(void *);
void expire_proc_cleanup(void *);
-void nextstate(int, enum states);
int st_add_task(struct autofs_point *, enum states);
int __st_add_task(struct autofs_point *, enum states);

View File

@ -0,0 +1,101 @@
autofs-5.1.8 - eliminate realpath from mount of submount
From: Ian Kent <raven@themaw.net>
None of the tests I have show that the realpath local variable in the
autofs submount mount function is needed, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
modules/mount_autofs.c | 25 ++++---------------------
1 file changed, 4 insertions(+), 21 deletions(-)
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -50,7 +50,6 @@ int mount_mount(struct autofs_point *ap,
{
struct startup_cond suc;
pthread_t thid;
- char realpath[PATH_MAX + 1];
char mountpoint[PATH_MAX + 1];
const char **argv;
int argc, status;
@@ -73,11 +72,6 @@ int mount_mount(struct autofs_point *ap,
/* Root offset of multi-mount */
if (root[strlen(root) - 1] == '/') {
- err = snprintf(realpath, PATH_MAX + 1, "%s/%s", ap->path, name);
- if (err > PATH_MAX) {
- error(ap->logopt, MODPREFIX "string too long for realpath");
- return 1;
- }
err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
if (err > PATH_MAX) {
error(ap->logopt, MODPREFIX "string too long for mountpoint");
@@ -91,22 +85,12 @@ int mount_mount(struct autofs_point *ap,
error(ap->logopt, MODPREFIX "string too long for mountpoint");
return 1;
}
- err = snprintf(realpath, PATH_MAX + 1, "%s", name);
- if (err > PATH_MAX) {
- error(ap->logopt, MODPREFIX "string too long for realpath");
- return 1;
- }
} else {
err = snprintf(mountpoint, PATH_MAX + 1, "%s", root);
if (err > PATH_MAX) {
error(ap->logopt, MODPREFIX "string too long for mountpoint");
return 1;
}
- err = snprintf(realpath, PATH_MAX + 1, "%s", name);
- if (err > PATH_MAX) {
- error(ap->logopt, MODPREFIX "string too long for realpath");
- return 1;
- }
}
} else {
err = snprintf(mountpoint, PATH_MAX + 1, "%s/%s", root, name);
@@ -114,7 +98,6 @@ int mount_mount(struct autofs_point *ap,
error(ap->logopt, MODPREFIX "string too long for mountpoint");
return 1;
}
- strcpy(realpath, mountpoint);
}
options = NULL;
@@ -180,7 +163,7 @@ int mount_mount(struct autofs_point *ap,
master = ap->entry->master;
- entry = master_new_mapent(master, realpath, ap->entry->age);
+ entry = master_new_mapent(master, mountpoint, ap->entry->age);
if (!entry) {
error(ap->logopt,
MODPREFIX "failed to malloc master_mapent struct");
@@ -332,7 +315,7 @@ int mount_mount(struct autofs_point *ap,
mnt = mnts_add_submount(nap);
if (!mnt) {
crit(ap->logopt,
- MODPREFIX "failed to allocate mount %s", realpath);
+ MODPREFIX "failed to allocate mount %s", mountpoint);
handle_mounts_startup_cond_destroy(&suc);
master_free_map_source(source, 1);
master_free_mapent(entry);
@@ -349,7 +332,7 @@ int mount_mount(struct autofs_point *ap,
crit(ap->logopt,
MODPREFIX
"failed to create mount handler thread for %s",
- realpath);
+ mountpoint);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
master_free_map_source(source, 1);
@@ -370,7 +353,7 @@ int mount_mount(struct autofs_point *ap,
if (suc.status) {
crit(ap->logopt,
- MODPREFIX "failed to create submount for %s", realpath);
+ MODPREFIX "failed to create submount for %s", mountpoint);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
master_free_map_source(source, 1);

View File

@ -0,0 +1,396 @@
autofs-5.1.8 - eliminate root param from autofs mount and umount
From: Ian Kent <raven@themaw.net>
Eliminate the "root" parameter of both mount and umount of autofs mounts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 30 ++++++-------------------
daemon/indirect.c | 57 ++++++++++++++++++++-----------------------------
daemon/lookup.c | 4 +--
daemon/master.c | 1
daemon/state.c | 2 -
include/automount.h | 7 ++----
modules/mount_autofs.c | 1
8 files changed, 39 insertions(+), 64 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -132,6 +132,7 @@
- get rid entry thid field.
- continue expire immediately after submount check.
- add buffer length checks to autofs mount_mount().
+- eliminate root param from autofs mount and umount.
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
@@ -736,7 +736,7 @@ static void umount_all(struct autofs_poi
left, ap->path);
}
-static int umount_autofs(struct autofs_point *ap, const char *root)
+static int umount_autofs(struct autofs_point *ap)
{
int ret = 0;
@@ -745,7 +745,7 @@ static int umount_autofs(struct autofs_p
if (ap->type == LKP_INDIRECT) {
umount_all(ap);
- ret = umount_autofs_indirect(ap, root);
+ ret = umount_autofs_indirect(ap);
} else
ret = umount_autofs_direct(ap);
@@ -915,7 +915,7 @@ static int autofs_init_ap(struct autofs_
return 0;
}
-static int mount_autofs(struct autofs_point *ap, const char *root)
+static int mount_autofs(struct autofs_point *ap)
{
int status;
@@ -930,7 +930,7 @@ static int mount_autofs(struct autofs_po
if (ap->type == LKP_DIRECT)
status = mount_autofs_direct(ap);
else
- status = mount_autofs_indirect(ap, root);
+ status = mount_autofs_indirect(ap);
st_add_task(ap, ST_READY);
@@ -1884,7 +1884,7 @@ int handle_mounts_exit(struct autofs_poi
* to check for possible recovery.
*/
if (ap->type == LKP_DIRECT) {
- umount_autofs(ap, NULL);
+ umount_autofs(ap);
handle_mounts_cleanup(ap);
return 1;
}
@@ -1895,7 +1895,7 @@ int handle_mounts_exit(struct autofs_poi
* so we can continue. This can happen if a lookup
* occurs while we're trying to umount.
*/
- ret = umount_autofs(ap, NULL);
+ ret = umount_autofs(ap);
if (!ret) {
set_indirect_mount_tree_catatonic(ap);
handle_mounts_cleanup(ap);
@@ -1923,12 +1923,10 @@ void *handle_mounts(void *arg)
struct startup_cond *suc;
struct autofs_point *ap;
int cancel_state, status = 0;
- char *root;
suc = (struct startup_cond *) arg;
ap = suc->ap;
- root = strdup(suc->root);
pthread_cleanup_push(return_start_status, suc);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
@@ -1936,30 +1934,18 @@ void *handle_mounts(void *arg)
status = pthread_mutex_lock(&suc->mutex);
if (status) {
logerr("failed to lock startup condition mutex!");
- if (root)
- free(root);
fatal(status);
}
- if (!root) {
- crit(ap->logopt, "failed to alloc string root");
- suc->status = 1;
- pthread_setcancelstate(cancel_state, NULL);
- pthread_exit(NULL);
- }
-
- if (mount_autofs(ap, root) < 0) {
+ if (mount_autofs(ap) < 0) {
if (!(do_force_unlink & UNLINK_AND_EXIT))
crit(ap->logopt, "mount of %s failed!", ap->path);
suc->status = 1;
- umount_autofs(ap, root);
- free(root);
+ umount_autofs(ap);
pthread_setcancelstate(cancel_state, NULL);
pthread_exit(NULL);
}
- free(root);
-
if (ap->flags & MOUNT_FLAG_NOBIND)
info(ap->logopt, "bind mounts disabled");
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -40,7 +40,7 @@
/* Attribute to create detached thread */
extern pthread_attr_t th_attr_detached;
-static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
+static int do_mount_autofs_indirect(struct autofs_point *ap)
{
const char *str_indirect = mount_type_str(t_indirect);
struct ioctl_ops *ops = get_ioctl_ops();
@@ -89,11 +89,11 @@ static int do_mount_autofs_indirect(stru
}
/* In case the directory doesn't exist, try to mkdir it */
- if (mkdir_path(root, mp_mode) < 0) {
+ if (mkdir_path(ap->path, mp_mode) < 0) {
if (errno != EEXIST && errno != EROFS) {
crit(ap->logopt,
"failed to create autofs directory %s",
- root);
+ ap->path);
goto out_err;
}
/* If we recieve an error, and it's EEXIST or EROFS we know
@@ -108,27 +108,27 @@ static int do_mount_autofs_indirect(stru
if (!type || strcmp(ap->entry->maps->type, "hosts"))
map_name = ap->entry->maps->argv[0];
- ret = mount(map_name, root, "autofs", MS_MGC_VAL, options);
+ ret = mount(map_name, ap->path, "autofs", MS_MGC_VAL, options);
if (ret) {
crit(ap->logopt,
- "failed to mount autofs path %s at %s", ap->path, root);
+ "failed to mount autofs at %s", ap->path);
goto out_rmdir;
}
free(options);
options = NULL;
- ret = stat(root, &st);
+ ret = stat(ap->path, &st);
if (ret == -1) {
crit(ap->logopt,
"failed to stat mount for autofs path %s", ap->path);
goto out_umount;
}
- if (ap->mode && (err = chmod(root, ap->mode)))
+ if (ap->mode && (err = chmod(ap->path, ap->mode)))
warn(ap->logopt, "failed to change mode of %s", ap->path);
- if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) {
+ if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, ap->path)) {
crit(ap->logopt,
"failed to create ioctl fd for autofs path %s", ap->path);
goto out_umount;
@@ -137,18 +137,15 @@ static int do_mount_autofs_indirect(stru
ap->dev = st.st_dev; /* Device number for mount point checks */
ops->timeout(ap->logopt, ap->ioctlfd, timeout);
- if (ap->logopt & LOGOPT_DEBUG)
- notify_mount_result(ap, root, timeout, str_indirect);
- else
- notify_mount_result(ap, ap->path, timeout, str_indirect);
+ notify_mount_result(ap, ap->path, timeout, str_indirect);
return 0;
out_umount:
- umount(root);
+ umount(ap->path);
out_rmdir:
if (ap->flags & MOUNT_FLAG_DIR_CREATED)
- rmdir(root);
+ rmdir(ap->path);
out_err:
if (options)
free(options);
@@ -158,7 +155,7 @@ out_err:
return -1;
}
-int mount_autofs_indirect(struct autofs_point *ap, const char *root)
+int mount_autofs_indirect(struct autofs_point *ap)
{
time_t now = monotonic_time(NULL);
int status;
@@ -180,11 +177,11 @@ int mount_autofs_indirect(struct autofs_
}
}
- status = do_mount_autofs_indirect(ap, root);
+ status = do_mount_autofs_indirect(ap);
if (status < 0)
return -1;
- map = lookup_ghost(ap, root);
+ map = lookup_ghost(ap);
if (map & LKP_FAIL) {
if (map & LKP_DIRECT) {
error(ap->logopt,
@@ -223,19 +220,13 @@ void close_mount_fds(struct autofs_point
return;
}
-int umount_autofs_indirect(struct autofs_point *ap, const char *root)
+int umount_autofs_indirect(struct autofs_point *ap)
{
struct ioctl_ops *ops = get_ioctl_ops();
char buf[MAX_ERR_BUF];
- char mountpoint[PATH_MAX + 1];
int rv, retries;
unsigned int unused;
- if (root)
- strcpy(mountpoint, root);
- else
- strcpy(mountpoint, ap->path);
-
/* If we are trying to shutdown make sure we can umount */
rv = ops->askumount(ap->logopt, ap->ioctlfd, &unused);
if (rv == -1) {
@@ -257,7 +248,7 @@ int umount_autofs_indirect(struct autofs
sched_yield();
retries = UMOUNT_RETRIES;
- while ((rv = umount(mountpoint)) == -1 && retries--) {
+ while ((rv = umount(ap->path)) == -1 && retries--) {
struct timespec tm = {0, 50000000};
if (errno != EBUSY)
break;
@@ -269,13 +260,13 @@ int umount_autofs_indirect(struct autofs
case ENOENT:
case EINVAL:
error(ap->logopt,
- "mount point %s does not exist", mountpoint);
+ "mount point %s does not exist", ap->path);
close_mount_fds(ap);
return 0;
break;
case EBUSY:
debug(ap->logopt,
- "mount point %s is in use", mountpoint);
+ "mount point %s is in use", ap->path);
if (ap->state == ST_SHUTDOWN_FORCE) {
close_mount_fds(ap);
goto force_umount;
@@ -294,11 +285,11 @@ int umount_autofs_indirect(struct autofs
}
#endif
ops->open(ap->logopt,
- &ap->ioctlfd, ap->dev, mountpoint);
+ &ap->ioctlfd, ap->dev, ap->path);
if (ap->ioctlfd < 0) {
warn(ap->logopt,
"could not recover autofs path %s",
- mountpoint);
+ ap->path);
close_mount_fds(ap);
return 0;
}
@@ -323,12 +314,12 @@ int umount_autofs_indirect(struct autofs
force_umount:
if (rv != 0) {
warn(ap->logopt,
- "forcing umount of indirect mount %s", mountpoint);
- rv = umount2(mountpoint, MNT_DETACH);
+ "forcing umount of indirect mount %s", ap->path);
+ rv = umount2(ap->path, MNT_DETACH);
} else {
- info(ap->logopt, "umounting indirect mount %s succeeded", mountpoint);
+ info(ap->logopt, "umounting indirect mount %s succeeded", ap->path);
if (ap->submount)
- rm_unwanted(ap, mountpoint, 1);
+ rm_unwanted(ap, ap->path, 1);
}
return rv;
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -720,7 +720,7 @@ static char *make_browse_path(unsigned i
return path;
}
-int lookup_ghost(struct autofs_point *ap, const char *root)
+int lookup_ghost(struct autofs_point *ap)
{
struct master_mapent *entry = ap->entry;
struct map_source *map;
@@ -784,7 +784,7 @@ int lookup_ghost(struct autofs_point *ap
}
fullpath = make_browse_path(ap->logopt,
- root, me->key, ap->pref);
+ ap->path, me->key, ap->pref);
if (!fullpath)
goto next;
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -1384,7 +1384,6 @@ static int master_do_mount(struct master
}
suc.ap = ap;
- suc.root = ap->path;
suc.done = 0;
suc.status = 0;
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -453,7 +453,7 @@ static void *do_readmap(void *arg)
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
ops->timeout(ap->logopt, ap->ioctlfd, timeout);
lookup_prune_cache(ap, now);
- status = lookup_ghost(ap, ap->path);
+ status = lookup_ghost(ap);
} else {
struct mapent *me;
unsigned int append_alarm = !ap->exp_runfreq;
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -269,7 +269,7 @@ int lookup_nss_read_master(struct master
int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time_t age);
int lookup_enumerate(struct autofs_point *ap,
int (*fn)(struct autofs_point *,struct mapent *, int), time_t now);
-int lookup_ghost(struct autofs_point *ap, const char *root);
+int lookup_ghost(struct autofs_point *ap);
int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len);
void lookup_close_lookup(struct autofs_point *ap);
void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, time_t age);
@@ -391,7 +391,6 @@ struct startup_cond {
pthread_mutex_t mutex;
pthread_cond_t cond;
struct autofs_point *ap;
- char *root;
unsigned int done;
unsigned int status;
};
@@ -588,13 +587,13 @@ int do_expire(struct autofs_point *ap, c
void *expire_proc_indirect(void *);
void *expire_proc_direct(void *);
int expire_offsets_direct(struct autofs_point *ap, struct mapent *me, int now);
-int mount_autofs_indirect(struct autofs_point *ap, const char *root);
+int mount_autofs_indirect(struct autofs_point *ap);
int do_mount_autofs_direct(struct autofs_point *ap, struct mapent *me, time_t timeout);
int mount_autofs_direct(struct autofs_point *ap);
int mount_autofs_offset(struct autofs_point *ap, struct mapent *me);
void submount_signal_parent(struct autofs_point *ap, unsigned int success);
void close_mount_fds(struct autofs_point *ap);
-int umount_autofs_indirect(struct autofs_point *ap, const char *root);
+int umount_autofs_indirect(struct autofs_point *ap);
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me);
int umount_autofs_direct(struct autofs_point *ap);
int umount_autofs_offset(struct autofs_point *ap, struct mapent *me);
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -324,7 +324,6 @@ int mount_mount(struct autofs_point *ap,
suc.ap = nap;
- suc.root = mountpoint;
suc.done = 0;
suc.status = 0;

View File

@ -0,0 +1,57 @@
autofs-5.1.8 - fail on empty replicated host name
From: Ian Kent <raven@themaw.net>
If a mount location host (or hosts) has an empty host name it has to be
a mistake so fail the automount request.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -105,6 +105,7 @@
- fix concat_options() error handling.
- fix minus only option handling in concat_options().
- fix incorrect path for is_mounted() in try_remount().
+- fail on empty replicated host name.
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
@@ -924,6 +924,12 @@ static int validate_location(unsigned in
if (*ptr == ':')
return 1;
+ /* Fail on replicated entry with empty first host name */
+ if (*ptr == ',') {
+ error(logopt, "missing first host name in location %s", loc);
+ return 0;
+ }
+
/*
* If a ':/' is present now it must be a host name, except
* for those special file systems like sshfs which use "#"
@@ -960,6 +966,18 @@ static int validate_location(unsigned in
"found in location %s", *ptr, loc);
return 0;
}
+
+ /* Fail on replicated entry with empty host name */
+ if (*ptr == ',') {
+ char next = *(ptr + 1);
+
+ if (next == ',' || next == ':') {
+ error(logopt,
+ "missing host name in location %s", loc);
+ return 0;
+ }
+ }
+
ptr++;
}

View File

@ -0,0 +1,49 @@
autofs-5.1.8 - fix amd selector function matching
From: Ian Kent <raven@themaw.net>
The top level lexical analyser matching of 1 and 2 arg selector
functions did not have enough context to match correctly.
This was causing it to attempt to match the selector function and its
parameter(s) against the selector function names which wasn't working.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/amd_tok.l | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -128,6 +128,7 @@
- fix fix mount tree startup reconnect.
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
+- fix amd selector function matching.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/amd_tok.l
+++ autofs-5.1.4/modules/amd_tok.l
@@ -159,15 +159,17 @@ CUTSEP (\|\||\/)
return SELECTOR;
}
- "!"/({SEL1ARG}|{SEL2ARG}) { return NOT; }
+ "!"/({SEL1ARG})(\([^,]+\)) { return NOT; }
- {SEL1ARG} {
+ "!"/({SEL2ARG})(\(([^,]+)(,([^,]+))?\)) { return NOT; }
+
+ ({SEL1ARG})/(\([^,]+\)) {
BEGIN(SELARGVAL);
amd_copy_buffer();
return SELECTOR;
}
- {SEL2ARG} {
+ ({SEL2ARG})/(\([^,]+)(,([^,]+))?\) {
BEGIN(SELARGVAL);
amd_copy_buffer();
return SELECTOR;

View File

@ -0,0 +1,141 @@
autofs-5.1.8 - fix deadlock in lookups
From: Ian Kent <raven@themaw.net>
After adding locking to fix a crash during lookups we're seeing a
deadlock becuase of recursive calls.
But once the lookup is open we shouldn't need to open it again during
the recursive call, fix it based on that.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/lookup.c | 62 +++++++++++++++++++++++++++++++++-------------------
daemon/master.c | 8 ++++++
include/master.h | 1
modules/parse_amd.c | 2 -
5 files changed, 51 insertions(+), 23 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -110,6 +110,7 @@
- don't immediately call function when waiting.
- fix return status of mount_autofs().
- don't close lookup at umount.
+- fix deadlock in lookups.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -318,31 +318,49 @@ static int do_read_map(struct autofs_poi
struct lookup_mod *lookup;
int status;
- pthread_cleanup_push(map_module_lock_cleanup, map);
- map_module_writelock(map);
- if (!map->lookup) {
- status = open_lookup(map->type, "", map->format,
- map->argc, map->argv, &lookup);
- if (status == NSS_STATUS_SUCCESS)
- map->lookup = lookup;
- else
- debug(ap->logopt,
- "lookup module %s open failed", map->type);
- } else {
- status = map->lookup->lookup_reinit(map->format,
- map->argc, map->argv,
- &map->lookup->context);
- if (status)
- warn(ap->logopt,
- "lookup module %s reinit failed", map->type);
- }
- pthread_cleanup_pop(1);
- if (status != NSS_STATUS_SUCCESS)
- return status;
-
if (!map->stale)
return NSS_STATUS_SUCCESS;
+ /* If this readmap is the result of trying to mount a submount
+ * the readlock may already be held if the map is the same as
+ * that of the caller. In that case the map has already been
+ * read so just skip the map open/reinit.
+ */
+ status = map_module_try_writelock(map);
+ if (status) {
+ if (!map->lookup) {
+ error(ap->logopt, "map module lock not held as expected");
+ return NSS_STATUS_UNAVAIL;
+ }
+ } else {
+ if (!map->lookup) {
+ pthread_cleanup_push(map_module_lock_cleanup, map);
+ status = open_lookup(map->type, "", map->format,
+ map->argc, map->argv, &lookup);
+ pthread_cleanup_pop(0);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(map);
+ debug(ap->logopt,
+ "lookup module %s open failed", map->type);
+ return status;
+ }
+ map->lookup = lookup;
+ } else {
+ pthread_cleanup_push(map_module_lock_cleanup, map);
+ status = map->lookup->lookup_reinit(map->format,
+ map->argc, map->argv,
+ &map->lookup->context);
+ pthread_cleanup_pop(0);
+ if (status) {
+ map_module_unlock(map);
+ warn(ap->logopt,
+ "lookup module %s reinit failed", map->type);
+ return status;
+ }
+ }
+ map_module_unlock(map);
+ }
+
master_source_current_wait(ap->entry);
ap->entry->current = map;
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -72,6 +72,14 @@ void map_module_writelock(struct map_sou
fatal(status);
}
+int map_module_try_writelock(struct map_source *map)
+{
+ int status = pthread_rwlock_trywrlock(&map->module_lock);
+ if (status && status != EBUSY && status != EDEADLK)
+ fatal(status);
+ return status;
+}
+
void map_module_readlock(struct map_source *map)
{
int status = pthread_rwlock_rdlock(&map->module_lock);
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -128,6 +128,7 @@ int master_list_empty(struct master *);
int master_done(struct master *);
int master_kill(struct master *);
void map_module_writelock(struct map_source *map);
+int map_module_try_writelock(struct map_source *map);
void map_module_readlock(struct map_source *map);
void map_module_unlock(struct map_source *map);
void map_module_lock_cleanup(void *arg);
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1391,7 +1391,7 @@ static int do_host_mount(struct autofs_p
cache_unlock(source->mc);
master_source_current_wait(ap->entry);
- ap->entry->current = source;
+ ap->entry->current = instance;
map_module_readlock(instance);
lookup = instance->lookup;

View File

@ -0,0 +1,169 @@
autofs-5.1.8 - fix deadlock with hosts map reload
From: Ian Kent <raven@themaw.net>
When reloading maps the hosts map calls lookup method ->parse_mount()
for each multi-mount root entry in the map (each host) while holding
the cache read lock which leads to a cache lock deadlock.
Remove the need to hold the cache read lock by creating an independent
list of entries for the update so the lock doesn't need to be taken.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
modules/lookup_hosts.c | 100 ++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 83 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -100,6 +100,7 @@
- serialise lookup module open and reinit.
- coverity fix for invalid access.
- fix hosts map deadlock on restart.
+- fix deadlock with hosts map reload.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -201,10 +201,72 @@ static int do_parse_mount(struct autofs_
return NSS_STATUS_SUCCESS;
}
+struct update_context {
+ char *key;
+ int key_len;
+ char *entry;
+ struct update_context *next;
+};
+
+static int add_update_entry(struct update_context **entries, struct mapent *me)
+{
+ struct update_context *upd;
+ char *key, *ent;
+
+ key = strdup(me->key);
+ if (!key)
+ return 0;
+
+ ent = strdup(me->mapent);
+ if (!ent) {
+ free(key);
+ return 0;
+ }
+
+ upd = malloc(sizeof(struct update_context));
+ if (!upd) {
+ free(ent);
+ free(key);
+ return 0;
+ }
+
+ upd->key = key;
+ upd->key_len = me->len;
+ upd->entry = ent;
+ upd->next = NULL;
+ if (*entries)
+ (*entries)->next = upd;
+ *entries = upd;
+
+ return 1;
+}
+
+static void free_update_entries(struct update_context *entries)
+{
+ struct update_context *this = entries;
+
+ while (this) {
+ struct update_context *next = this->next;
+ free(this->key);
+ free(this->entry);
+ free(this);
+ this = next;
+ }
+}
+
+void entries_cleanup(void *arg)
+{
+ struct update_context *entries = arg;
+
+ free_update_entries(entries);
+}
+
static void update_hosts_mounts(struct autofs_point *ap,
struct map_source *source, time_t age,
struct lookup_context *ctxt)
{
+ struct update_context *head = NULL;
+ struct update_context *entries = NULL;
struct mapent_cache *mc;
struct mapent *me;
char *mapent;
@@ -212,6 +274,8 @@ static void update_hosts_mounts(struct a
mc = source->mc;
+ pthread_cleanup_push(entries_cleanup, head);
+
pthread_cleanup_push(cache_lock_cleanup, mc);
cache_writelock(mc);
me = cache_lookup_first(mc);
@@ -224,39 +288,39 @@ static void update_hosts_mounts(struct a
mapent = get_exports(ap, me->key);
if (mapent) {
- cache_update(mc, source, me->key, mapent, age);
+ int ret;
+
+ ret = cache_update(mc, source, me->key, mapent, age);
free(mapent);
+ if (!IS_MM_ROOT(me))
+ goto next;
+ if (ret != CHE_FAIL) {
+ if (!add_update_entry(&entries, me))
+ warn(ap->logopt, MODPREFIX
+ "failed to add update entry for %s", me->key);
+ else if (!head)
+ head = entries;
+ }
}
next:
me = cache_lookup_next(mc, me);
}
pthread_cleanup_pop(1);
- pthread_cleanup_push(cache_lock_cleanup, mc);
- cache_readlock(mc);
- me = cache_lookup_first(mc);
- while (me) {
- /*
- * Hosts map entry not yet expanded, already expired
- * or not the base of the tree
- */
- if (!IS_MM(me) || !IS_MM_ROOT(me))
- goto cont;
-
+ while (head) {
debug(ap->logopt, MODPREFIX
- "attempt to update exports for %s", me->key);
+ "attempt to update exports for %s", head->key);
master_source_current_wait(ap->entry);
ap->entry->current = source;
ap->flags |= MOUNT_FLAG_REMOUNT;
- ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
- me->mapent, ctxt->parse->context);
+ ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
+ head->entry, ctxt->parse->context);
if (ret)
warn(ap->logopt, MODPREFIX
- "failed to parse mount %s", me->mapent);
+ "failed to parse mount %s", head->entry);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
-cont:
- me = cache_lookup_next(mc, me);
+ head = head->next;
}
pthread_cleanup_pop(1);
}

View File

@ -0,0 +1,83 @@
autofs-5.1.8 - fix expire retry looping
From: Ian Kent <raven@themaw.net>
Commit aa6da48d1 (autofs-5.1.7 - eliminate count_mounts() from
expire_proc_indirect()) stopped using the count_mounts() function
in indirect mount expires because it can be a significant overhead
and shouldn't be needed if the kernel expire dentry selection works
as it should.
Unfortunately there is a case where it doesn't work properly, when
a USR1 signal is sent to the automount process it is meant to expire
mounts regardless of the expire timeout. In this case if a mount has
been propagated to a mount namespace and is held busy the mount will
fail to umount and because setting the last used field of the mount
dentry doesn't prevent the mount dentry from being selected for expire
again immediately in this case automount will look continually.
The problem occurs because the the kernel doesn't know how to check
these propagated mounts for busyness and the init namespace automount
process tries to expire the mount but fails and continues trying to
expire the mount because the expire function assumes only mounts that
are not busy will be selected for expire.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/indirect.c | 13 ++++++++++++-
include/automount.h | 2 +-
3 files changed, 14 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -149,6 +149,7 @@
- make open files limit configurable.
- fix some sss error return cases.
- fix incorrect matching of cached wildcard key.
+- fix expire retry looping.
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
@@ -343,6 +343,7 @@ void *expire_proc_indirect(void *arg)
int offsets, submnts, count;
int ioctlfd, cur_state;
int status, ret, left;
+ int retries;
ea = (struct expire_args *) arg;
@@ -490,9 +491,19 @@ void *expire_proc_indirect(void *arg)
* If there are no more real mounts left we could still
* have some offset mounts with no '/' offset or symlinks
* so we need to umount or unlink them here.
+ *
+ * The dentry info last_used field is set to 'now' when a
+ * dentry is selected for expire so that it isn't immediately
+ * selected again if the expire fails. But this can't work
+ * for immediate expires so the count_mounts() function must
+ * be used to limit the number of expire iterations.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- while (1) {
+ if (how == AUTOFS_EXP_IMMEDIATE)
+ retries = count_mounts(ap, ap->path, ap->dev);
+ else
+ retries = -1;
+ while (retries--) {
ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how);
if (ret != 0 && errno == EAGAIN)
break;
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -141,7 +141,7 @@ struct autofs_point;
#define NEGATIVE_TIMEOUT 10
#define POSITIVE_TIMEOUT 120
#define UMOUNT_RETRIES 16
-#define EXPIRE_RETRIES 3
+#define EXPIRE_RETRIES 1
struct mapent_cache {
pthread_rwlock_t rwlock;

View File

@ -0,0 +1,45 @@
autofs-5.1.8 - fix fix mount tree startup reconnect
From: Ian Kent <raven@themaw.net>
In function master_mount_mounts() commit 635b90eccee9 checks if the
current top level mount is already running by using two things, if the
mount handling thread id is set in the autofs mount point structure and
if the mount point path is a mounted autofs file system.
But the top level master map entry for a direct mount map is the
reserved path "/-" and doesn't have an actual mount associated with it
so a mounted check can't be used. But we know that top level mounts
start in state ST_INIT and once that state is changed it never changes
back to it. So using the presence of the mount handling thread id and
the state not being ST_INIT is sufficient to know if this is a new
mount or not.
Fixes: 635b90eccee9 ("autofs-5.1.8 - fix mount tree startup reconnect")
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -125,6 +125,7 @@
- fix mount tree startup reconnect.
- fix unterminated read in handle_cmd_pipe_fifo_message().
- fix memory leak in sasl_do_kinit()
+- fix fix mount tree startup reconnect.
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
@@ -1553,7 +1553,7 @@ int master_mount_mounts(struct master *m
}
cache_unlock(nc);
cont:
- if (ap->thid && is_mounted(this->path, MNTS_AUTOFS))
+ if (ap->thid && ap->state != ST_INIT)
check_update_map_sources(this, master->readall);
else {
if (!master_do_mount(this)) {

View File

@ -0,0 +1,110 @@
autofs-5.1.8 - fix handling of incorrect return from umount_ent()
From: Ian Kent <raven@themaw.net>
Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount
return") guards against umount_ent() returning a fail when the mount
has actually been umounted.
But we also see umount_ent() return success when in fact the mount has
not been umounted leading to incorrect handling of automounts.
So checking the return of umount_ent() isn't always giving the correct
result in more than just one case, consequently we should ignore the
result from the spawned umount(8) and check if the mount has in fact
been umounted.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 3 +--
lib/mounts.c | 19 ++++++++++---------
3 files changed, 12 insertions(+), 11 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -93,6 +93,7 @@
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
- fix sysconf(3) return handling.
- remove nonstrict parameter from tree_mapent_umount_offsets().
+- fix handling of incorrect return from umount_ent().
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
@@ -606,8 +606,7 @@ static int umount_subtree_mounts(struct
struct mnt_list *mnt;
debug(ap->logopt, "unmounting dir = %s", path);
- if (umount_ent(ap, path) &&
- is_mounted(path, MNTS_REAL)) {
+ if (umount_ent(ap, path)) {
warn(ap->logopt, "could not umount dir %s", path);
left++;
goto done;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(str
*/
if (oe->ioctlfd != -1 ||
is_mounted(oe->key, MNTS_REAL)) {
- if (umount_ent(ap, oe->key) &&
- is_mounted(oe->key, MNTS_REAL)) {
+ if (umount_ent(ap, oe->key)) {
debug(ap->logopt,
"offset %s has active mount, invalidate",
oe->key);
@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct ma
*/
if (is_mounted(mp, MNTS_REAL)) {
info(ap->logopt, "unmounting dir = %s", mp);
- if (umount_ent(ap, mp) &&
- is_mounted(mp, MNTS_REAL)) {
+ if (umount_ent(ap, mp)) {
if (!tree_mapent_mount_offsets(oe, 1))
warn(ap->logopt,
"failed to remount offset triggers");
@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(str
int umount_ent(struct autofs_point *ap, const char *path)
{
+ unsigned int mounted;
int rv;
if (ap->state != ST_SHUTDOWN_FORCE)
@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap,
rv = spawn_umount(ap->logopt, "-l", path, NULL);
}
+ mounted = is_mounted(path, MNTS_REAL);
+
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
/*
* Verify that we actually unmounted the thing. This is a
@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap,
* so that we do not try to call rmdir_path on the
* directory.
*/
- if (is_mounted(path, MNTS_REAL)) {
+ if (mounted) {
crit(ap->logopt,
"the umount binary reported that %s was "
"unmounted, but there is still something "
"mounted on this path.", path);
- rv = -1;
+ mounted = -1;
}
}
- /* On success, check for mounted mount and remove it if found */
- if (!rv)
+ /* If mount is gone remove it from mounted mounts list. */
+ if (!mounted)
mnts_remove_mount(path, MNTS_MOUNTED);
- return rv;
+ return mounted;
}
int umount_amd_ext_mount(struct autofs_point *ap, const char *path)

View File

@ -0,0 +1,97 @@
autofs-5.1.8 - fix hosts map deadlock on restart
From: Ian Kent <raven@themaw.net>
When starting automount(8) with a hosts map that has mounts that were
in use at the last exit a deadlock can occur.
In this case automount(8) will perform the same steps but not actually
perform the mount to re-construct the context of each mount. But, with
the hosts map, that leads to calling back into the sun parse module
while holding the map module read lock which will again try and take
the write lock.
Fix this by only taking the write lock in the mount code path if the
module handle has not already been opened.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 22 ++++++++++++----------
modules/parse_amd.c | 18 ++++++++++--------
3 files changed, 23 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -99,6 +99,7 @@
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
- coverity fix for invalid access.
+- fix hosts map deadlock on restart.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -815,19 +815,21 @@ int do_lookup_mount(struct autofs_point
struct lookup_mod *lookup;
int status;
- map_module_writelock(map);
if (!map->lookup) {
- status = open_lookup(map->type, "",
- map->format, map->argc, map->argv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- map_module_unlock(map);
- debug(ap->logopt,
- "lookup module %s open failed", map->type);
- return status;
+ map_module_writelock(map);
+ if (!map->lookup) {
+ status = open_lookup(map->type, "",
+ map->format, map->argc, map->argv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(map);
+ debug(ap->logopt,
+ "lookup module %s open failed", map->type);
+ return status;
+ }
+ map->lookup = lookup;
}
- map->lookup = lookup;
+ map_module_unlock(map);
}
- map_module_unlock(map);
master_source_current_wait(ap->entry);
ap->entry->current = map;
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1370,17 +1370,19 @@ static int do_host_mount(struct autofs_p
}
}
- map_module_writelock(instance);
if (!instance->lookup) {
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- map_module_unlock(instance);
- debug(ap->logopt, "open lookup module hosts failed");
- goto out;
+ map_module_writelock(instance);
+ if (!instance->lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(instance);
+ debug(ap->logopt, "open lookup module hosts failed");
+ goto out;
+ }
+ instance->lookup = lookup;
}
- instance->lookup = lookup;
+ map_module_unlock(instance);
}
- map_module_unlock(instance);
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);

View File

@ -0,0 +1,62 @@
autofs-5.1.8 - fix incorrect matching of cached wildcard key
From: Ian Kent <raven@themaw.net>
During the implementation of amd format map entry support the code
to match a cached key was modified.
Unfortunately there's a case were the key lookup behaves incorrectly.
That case is when there are included maps in the map itself and one
of the maps (usually the last) has a wildcard key entry. In this case
the wildcard key may be found during lookup but the map it blongs to
isn't checked so it can be incorrectly returned instead of a matching
entry in a subsequent included map.
Another problem case is when there's a wildcard match and a cache prune
occurs while the mount is being done. In this case the matched cache
entry that has been added is seen as stale and removed along with the
mount point directory during the prune leading to a mount fail.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/parse_subs.c | 9 +++++++--
2 files changed, 8 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -148,6 +148,7 @@
- add ioctlfd open helper.
- make open files limit configurable.
- fix some sss error return cases.
+- fix incorrect matching of cached wildcard key.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/parse_subs.c
+++ autofs-5.1.4/lib/parse_subs.c
@@ -532,8 +532,11 @@ struct mapent *match_cached_key(struct a
while ((me = cache_lookup_key_next(me)))
if (me->source == source)
break;
- if (!me)
+ if (!me) {
me = cache_lookup_distinct(mc, "*");
+ if (me && (me->source != source))
+ me = NULL;
+ }
}
if (!me)
@@ -545,7 +548,9 @@ struct mapent *match_cached_key(struct a
*/
if (!(ap->flags & MOUNT_FLAG_REMOUNT) &&
ap->type == LKP_INDIRECT && *me->key == '*') {
- ret = cache_update(mc, source, key, me->mapent, me->age);
+ time_t now = monotonic_time(NULL);
+
+ ret = cache_update(mc, source, key, me->mapent, now);
if (!(ret & (CHE_OK | CHE_UPDATED)))
me = NULL;
}

View File

@ -0,0 +1,63 @@
autofs-5.1.8 - fix incorrect path for is_mounted() in try_remount()
From: Ian Kent <raven@themaw.net>
A regression was introduced when the offset mount handling was rewritten.
It resulted in an incorrect path sometimes being used in an is_mounted()
check.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 26 +++++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -104,6 +104,7 @@
- fix memory leak in update_hosts_mounts().
- fix concat_options() error handling.
- fix minus only option handling in concat_options().
+- fix incorrect path for is_mounted() 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
@@ -2803,14 +2803,30 @@ int try_remount(struct autofs_point *ap,
ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
else
ap->flags |= MOUNT_FLAG_DIR_CREATED;
+ goto done;
+ }
+
+ me->flags &= ~MOUNT_FLAG_DIR_CREATED;
+ /* Direct or offset mount, key is full path */
+ if (MM_PARENT(me)->key[0] == '/') {
+ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
} else {
- me->flags &= ~MOUNT_FLAG_DIR_CREATED;
- if (type == t_offset) {
- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
- me->flags |= MOUNT_FLAG_DIR_CREATED;
+ char *p_key = MM_PARENT(me)->key;
+ char mp[PATH_MAX + 1];
+ int len;
+
+ len = mount_fullpath(mp, PATH_MAX, ap->path, ap->len, p_key);
+ if (len > PATH_MAX) {
+ /* This should never happen due to earlier checks */
+ error(ap->logopt, "mountpoint path too long");
+ return 0;
}
- }
+ if (!is_mounted(mp, MNTS_REAL))
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
+ }
+done:
/*
* Either we opened the mount or we're re-reading the map.
* If we opened the mount and ioctlfd is not -1 we have

View File

@ -0,0 +1,46 @@
autofs-5.1.8 - fix invalid tsv access
From: Ian Kent <raven@themaw.net>
When using the --dumpmaps option of automount(8) a SEGV can occur
because a thread specific data variable accessed in the code hasn't
yet been created.
The thread specific data doesn't need to be set to list the maps
so we can create the key and rely on pthread_getspecific() returning
NULL when the value hasn't been set as this case is handled correctly.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 9 +++++++++
2 files changed, 10 insertions(+)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -95,6 +95,7 @@
- remove nonstrict parameter from tree_mapent_umount_offsets().
- fix handling of incorrect return from umount_ent().
- dont use initgroups() at spawn.
+- fix invalid tsv access.
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
@@ -2510,6 +2510,15 @@ int main(int argc, char *argv[])
master = argv[2];
}
+ status = pthread_key_create(&key_thread_stdenv_vars,
+ key_thread_stdenv_vars_destroy);
+ if (status) {
+ logerr("%s: failed to create thread data key for std env vars!",
+ program);
+ macro_free_global_table();
+ exit(1);
+ }
+
if (master)
master_list = master_new(NULL, timeout, flags);
else

View File

@ -0,0 +1,135 @@
autofs-5.1.8 - fix kernel mount status notification
From: Ian Kent <raven@themaw.net>
The status return for attempted mount notification is not done
correctly in some cases leading to a status being sent to the
kernel multiple times or the send causing an error.
We must send a status to the kernel but it needs to be the correct
one. It definitely shouldn't be sent twice for the same mount attempt
and shouldn't be failing.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 19 +++++++++++--------
daemon/indirect.c | 19 +++++++++++--------
3 files changed, 23 insertions(+), 16 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -78,6 +78,7 @@
- fix empty mounts list return from unlink_mount_tree().
- fix nonstrict offset mount fail handling.
- remove intr hosts map mount option.
+- fix kernel mount status notification.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1143,12 +1143,18 @@ int handle_packet_expire_direct(struct a
return 0;
}
-static void mount_send_fail(void *arg)
+static void mount_send_status(void *arg)
{
struct ioctl_ops *ops = get_ioctl_ops();
struct pending_args *mt = arg;
struct autofs_point *ap = mt->ap;
- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
+
+ if (mt->status)
+ ops->send_fail(ap->logopt, mt->ioctlfd,
+ mt->wait_queue_token, mt->status);
+ else
+ ops->send_ready(ap->logopt,
+ mt->ioctlfd, mt->wait_queue_token);
ops->close(ap->logopt, mt->ioctlfd);
}
@@ -1177,7 +1183,8 @@ static void *do_mount_direct(void *arg)
pending_mutex_unlock(args);
- pthread_cleanup_push(mount_send_fail, &mt);
+ mt.status = 0;
+ pthread_cleanup_push(mount_send_status, &mt);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -1191,9 +1198,7 @@ static void *do_mount_direct(void *arg)
if (status == -1) {
error(ap->logopt,
"can't stat direct mount trigger %s", mt.name);
- ops->send_fail(ap->logopt,
- mt.ioctlfd, mt.wait_queue_token, -ENOENT);
- ops->close(ap->logopt, mt.ioctlfd);
+ mt.status = -ENOENT;
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}
@@ -1203,8 +1208,6 @@ static void *do_mount_direct(void *arg)
error(ap->logopt,
"direct trigger not valid or already mounted %s",
mt.name);
- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
- ops->close(ap->logopt, mt.ioctlfd);
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -674,13 +674,18 @@ int handle_packet_expire_indirect(struct
return 0;
}
-static void mount_send_fail(void *arg)
+static void mount_send_status(void *arg)
{
struct ioctl_ops *ops = get_ioctl_ops();
struct pending_args *mt = arg;
struct autofs_point *ap = mt->ap;
- ops->send_fail(ap->logopt,
- ap->ioctlfd, mt->wait_queue_token, -ENOENT);
+
+ if (mt->status)
+ ops->send_fail(ap->logopt, ap->ioctlfd,
+ mt->wait_queue_token, mt->status);
+ else
+ ops->send_ready(ap->logopt,
+ ap->ioctlfd, mt->wait_queue_token);
}
static void *do_mount_indirect(void *arg)
@@ -709,7 +714,8 @@ static void *do_mount_indirect(void *arg
pending_mutex_unlock(args);
- pthread_cleanup_push(mount_send_fail, &mt);
+ mt.status = 0;
+ pthread_cleanup_push(mount_send_status, &mt);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
@@ -722,9 +728,7 @@ static void *do_mount_indirect(void *arg
len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len);
if (!len) {
crit(ap->logopt, "path to be mounted is to long");
- ops->send_fail(ap->logopt,
- ap->ioctlfd, mt.wait_queue_token,
- -ENAMETOOLONG);
+ mt.status = -ENAMETOOLONG;
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}
@@ -733,7 +737,6 @@ static void *do_mount_indirect(void *arg
if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) {
error(ap->logopt,
"indirect trigger not valid or already mounted %s", buf);
- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}

View File

@ -0,0 +1,36 @@
autofs-5.1.8 - fix loop under run in cache_get_offset_parent()
From: Frank Sorenson <sorenson@redhat.com>
To avoid reading memory outside of the the string
allocated for parent, tail needs to stop when it
reaches or passes parent, even if it doesn't
actually equal parent.
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
CHANGELOG | 1 +
lib/cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -86,6 +86,7 @@
- fix root offset error handling.
- fix nonstrict fail handling of last offset mount.
- dont fail on duplicate offset entry tree add.
+- fix loop under run in cache_get_offset_parent().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -680,7 +680,7 @@ struct mapent *cache_get_offset_parent(s
*tail = 0;
tail--;
- if (tail == parent)
+ if (tail <= parent)
break;
me = cache_lookup_distinct(mc, parent);

View File

@ -0,0 +1,45 @@
autofs-5.1.8 - fix memory leak in sasl_do_kinit()
From: Ian Kent <raven@themaw.net>
In sasl_do_kinit() there is a failure case that omits freeing the local
variable tgs_princ, fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/cyrus-sasl.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -124,6 +124,7 @@
- get rid of unused field submnt_count.
- fix mount tree startup reconnect.
- fix unterminated read in handle_cmd_pipe_fifo_message().
+- fix memory leak in sasl_do_kinit()
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/cyrus-sasl.c
+++ autofs-5.1.4/modules/cyrus-sasl.c
@@ -497,7 +497,7 @@ sasl_do_kinit(unsigned logopt, struct lo
if (ret) {
error(logopt, "krb5_unparse_name failed with error %d",
ret);
- goto out_cleanup_client_princ;
+ goto out_cleanup_tgs_princ;
}
debug(logopt, "Using tgs name %s", tgs_name);
@@ -563,8 +563,9 @@ out_cleanup_creds:
krb5cc_in_use--;
krb5_free_cred_contents(ctxt->krb5ctxt, &my_creds);
out_cleanup_unparse:
- krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
krb5_free_unparsed_name(ctxt->krb5ctxt, tgs_name);
+out_cleanup_tgs_princ:
+ krb5_free_principal(ctxt->krb5ctxt, tgs_princ);
out_cleanup_client_princ:
krb5_free_principal(ctxt->krb5ctxt, krb5_client_princ);
out_cleanup_cc:

View File

@ -0,0 +1,53 @@
autofs-5.1.8 - fix memory leak in update_hosts_mounts()
From: Ian Kent <raven@themaw.net>
Coverity has reported a memory leak in update_hosts_mounts() introduced
by the map reload deadlock fix.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 13 +++++++------
2 files changed, 8 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -101,6 +101,7 @@
- coverity fix for invalid access.
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
+- fix memory leak in update_hosts_mounts().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_hosts.c
+++ autofs-5.1.4/modules/lookup_hosts.c
@@ -307,20 +307,21 @@ next:
}
pthread_cleanup_pop(1);
- while (head) {
+ entries = head;
+ while (entries) {
debug(ap->logopt, MODPREFIX
- "attempt to update exports for %s", head->key);
+ "attempt to update exports for %s", entries->key);
master_source_current_wait(ap->entry);
ap->entry->current = source;
ap->flags |= MOUNT_FLAG_REMOUNT;
- ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
- head->entry, ctxt->parse->context);
+ ret = ctxt->parse->parse_mount(ap, entries->key, strlen(entries->key),
+ entries->entry, ctxt->parse->context);
if (ret)
warn(ap->logopt, MODPREFIX
- "failed to parse mount %s", head->entry);
+ "failed to parse mount %s", entries->entry);
ap->flags &= ~MOUNT_FLAG_REMOUNT;
- head = head->next;
+ entries = entries->next;
}
pthread_cleanup_pop(1);
}

View File

@ -0,0 +1,40 @@
autofs-5.1.8 - fix memory leak in xdr_exports()
From: Ian Kent <raven@themaw.net>
Converting xdr_exports() to not be recursive introduced a memory leak
if an error is encountered, fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/rpc_subs.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -89,6 +89,7 @@
- fix loop under run in cache_get_offset_parent().
- simplify cache_add() a little.
- fix use after free in tree_mapent_delete_offset_tree().
+- fix memory leak in xdr_exports().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/rpc_subs.c
+++ autofs-5.1.4/lib/rpc_subs.c
@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exp
export = (char **) exports;
while (1) {
- if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export))
+ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) {
+ if (*exports) {
+ rpc_exports_free(*exports);
+ *exports = NULL;
+ }
return FALSE;
+ }
if (!*export)
break;
export = (char **) &((struct exportinfo *) *export)->next;

View File

@ -0,0 +1,88 @@
autofs-5.1.8 - fix minus only option handling in concat_options()
From: Ian Kent <raven@themaw.net>
While a '-' alone isn't strictly valid it hadn't previously cuased a
parse error. So commit 9047e91ffa69 (autofs-5.1.7 - fix concat_options()
error handling) introduced a regression by no longer allowing this.
Fix this regression by only failing if errno is set to a non-zero value
on return from concat_options() as well as returning NULL.
Fixes: 9047e91ffa69 (autofs-5.1.7 - fix concat_options() error handling)
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 25 +++++++++++++++++++------
2 files changed, 20 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -103,6 +103,7 @@
- fix deadlock with hosts map reload.
- fix memory leak in update_hosts_mounts().
- fix concat_options() error handling.
+- fix minus only option handling in concat_options().
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
@@ -376,10 +376,16 @@ static int do_init(int argc, const char
if (gbl_options) {
append_options = defaults_get_append_options();
if (append_options) {
- char *tmp = concat_options(gbl_options, ctxt->optstr);
+ char *tmp;
+
+ errno = 0;
+ tmp = concat_options(gbl_options, ctxt->optstr);
if (!tmp) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "concat_options: %s", estr);
+ /* Ignore non-error NULL return */
+ if (errno) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ logerr(MODPREFIX "concat_options: %s", estr);
+ }
/* freed in concat_options */
ctxt->optstr = NULL;
} else
@@ -996,9 +1002,12 @@ static int parse_mapent(const char *ent,
free(myoptions);
myoptions = newopt;
} else if (newopt) {
+ errno = 0;
tmp = concat_options(myoptions, newopt);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr;
+
estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(logopt, MODPREFIX
"concat_options: %s", estr);
@@ -1370,8 +1379,10 @@ dont_expand:
free(mnt_options);
mnt_options = noptions;
} else if (noptions) {
+ errno = 0;
tmp = concat_options(mnt_options, noptions);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt,
MODPREFIX "concat_options: %s", estr);
@@ -1395,8 +1406,10 @@ dont_expand:
free(options);
options = mnt_options;
} else if (mnt_options) {
+ errno = 0;
tmp = concat_options(options, mnt_options);
- if (!tmp) {
+ /* Ignore non-error NULL return */
+ if (!tmp && errno) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
error(ap->logopt, MODPREFIX "concat_options: %s", estr);
free(pmapent);

View File

@ -0,0 +1,54 @@
autofs-5.1.8 - fix mount tree startup reconnect
From: Ian Kent <raven@themaw.net>
When reconnecting to an existing mount tree at startup trying to work
out if we created the mountpoint directory uses the parent path of the
current map entry.
But if the current map entry has no parent we should use the map entry
path.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -122,6 +122,7 @@
- add command pipe handling functions.
- switch to application wide command pipe.
- get rid of unused field submnt_count.
+- fix mount tree startup reconnect.
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
@@ -2807,6 +2807,7 @@ static int remount_active_mount(struct a
int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
{
struct ioctl_ops *ops = get_ioctl_ops();
+ struct mapent *mapent;
const char *path;
int ret, fd;
dev_t devid;
@@ -2841,12 +2842,13 @@ int try_remount(struct autofs_point *ap,
}
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
+ mapent = IS_MM(me) ? MM_PARENT(me) : me;
/* Direct or offset mount, key is full path */
- if (MM_PARENT(me)->key[0] == '/') {
- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
+ if (mapent->key[0] == '/') {
+ if (!is_mounted(mapent->key, MNTS_REAL))
me->flags |= MOUNT_FLAG_DIR_CREATED;
} else {
- char *p_key = MM_PARENT(me)->key;
+ char *p_key = mapent->key;
char mp[PATH_MAX + 1];
int len;

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,38 @@
autofs-5.1.8 - fix nonstrict fail handling of last offset mount
From: Ian Kent <raven@themaw.net>
When mounting a list of multi-mount offsets the offset mount should
succeed even if there's a mount failure for the non-strict case (the
default).
But currently if the last offset mount fails the multi-mount fails
regardless of whether the mount is non-strict or not.
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
@@ -84,6 +84,7 @@
- fix double quoting in auto.smb.
- fix double quoting of ampersand in auto.smb as well.
- fix root offset error handling.
+- fix nonstrict fail handling of last offset mount.
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
@@ -1940,7 +1940,7 @@ static int tree_mapent_mount_offsets_wor
tree_mapent_mount_offsets(oe, !ctxt->strict);
}
- return ret;
+ return (ctxt->strict ? ret : 1);
}
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict)

View File

@ -0,0 +1,183 @@
autofs-5.1.8 - fix parse module instance mutex naming
From: Ian Kent <raven@themaw.net>
The naming used for parse module instance locks is the same as that
used for map lookup instances. Rename these to make it clear they
are being used in the parse modules.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_amd.c | 28 ++++++++++++++--------------
modules/parse_sun.c | 20 ++++++++++----------
3 files changed, 25 insertions(+), 24 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -96,6 +96,7 @@
- fix handling of incorrect return from umount_ent().
- dont use initgroups() at spawn.
- fix invalid tsv access.
+- fix parse module instance mutex naming.
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
@@ -39,18 +39,18 @@ int parse_version = AUTOFS_PARSE_VERSION
static struct mount_mod *mount_nfs = NULL;
static int init_ctr = 0;
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
-static void instance_mutex_lock(void)
+static void parse_instance_mutex_lock(void)
{
- int status = pthread_mutex_lock(&instance_mutex);
+ int status = pthread_mutex_lock(&parse_instance_mutex);
if (status)
fatal(status);
}
-static void instance_mutex_unlock(void)
+static void parse_instance_mutex_unlock(void)
{
- int status = pthread_mutex_unlock(&instance_mutex);
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
if (status)
fatal(status);
}
@@ -112,7 +112,7 @@ int parse_init(int argc, const char *con
/* We only need this once. NFS mounts are so common that we cache
this module. */
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (mount_nfs)
init_ctr++;
else {
@@ -121,11 +121,11 @@ int parse_init(int argc, const char *con
} else {
kill_context(ctxt);
*context = NULL;
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 1;
}
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 0;
}
@@ -1358,11 +1358,11 @@ static int do_host_mount(struct autofs_p
argc = 1;
}
- instance_mutex_lock();
+ parse_instance_mutex_lock();
status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
if (status != NSS_STATUS_SUCCESS) {
debug(ap->logopt, "open lookup module hosts failed");
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
goto out;
}
@@ -1374,13 +1374,13 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
close_lookup(lookup);
goto out;
}
}
instance->lookup = lookup;
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);
@@ -2373,12 +2373,12 @@ int parse_done(void *context)
int rv = 0;
struct parse_context *ctxt = (struct parse_context *) context;
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (--init_ctr == 0) {
rv = close_mount(mount_nfs);
mount_nfs = NULL;
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
if (ctxt)
kill_context(ctxt);
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -41,18 +41,18 @@ int parse_version = AUTOFS_PARSE_VERSION
static struct mount_mod *mount_nfs = NULL;
static int init_ctr = 0;
-static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t parse_instance_mutex = PTHREAD_MUTEX_INITIALIZER;
-static void instance_mutex_lock(void)
+static void parse_instance_mutex_lock(void)
{
- int status = pthread_mutex_lock(&instance_mutex);
+ int status = pthread_mutex_lock(&parse_instance_mutex);
if (status)
fatal(status);
}
-static void instance_mutex_unlock(void)
+static void parse_instance_mutex_unlock(void)
{
- int status = pthread_mutex_unlock(&instance_mutex);
+ int status = pthread_mutex_unlock(&parse_instance_mutex);
if (status)
fatal(status);
}
@@ -423,7 +423,7 @@ int parse_init(int argc, const char *con
/* We only need this once. NFS mounts are so common that we cache
this module. */
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (mount_nfs)
init_ctr++;
else {
@@ -431,11 +431,11 @@ int parse_init(int argc, const char *con
init_ctr++;
} else {
kill_context(ctxt);
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
return 1;
}
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
*context = (void *) ctxt;
@@ -1719,12 +1719,12 @@ int parse_done(void *context)
int rv = 0;
struct parse_context *ctxt = (struct parse_context *) context;
- instance_mutex_lock();
+ parse_instance_mutex_lock();
if (--init_ctr == 0) {
rv = close_mount(mount_nfs);
mount_nfs = NULL;
}
- instance_mutex_unlock();
+ parse_instance_mutex_unlock();
if (ctxt)
kill_context(ctxt);

View File

@ -0,0 +1,58 @@
autofs-5.1.8 - fix possible use after free in handle_mounts_exit()
From: Ian Kent <raven@themaw.net>
Don't free the submount map entry until it's no longer used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 20 ++++++++++----------
2 files changed, 11 insertions(+), 10 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -141,6 +141,7 @@
- dont call umount_subtree_mounts() on parent at umount.
- dont take parent source lock at mount shutdown.
- eliminate buffer usage from handle_mounts_cleanup().
+- fix possible use after free in handle_mounts_exit().
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
@@ -1753,16 +1753,6 @@ static void handle_mounts_cleanup(void *
info(logopt, "shut down path %s", ap->path);
- /*
- * Submounts are detached threads and don't belong to the
- * master map entry list so we need to free their resources
- * here.
- */
- if (submount) {
- master_free_mapent_sources(ap->entry, 1);
- master_free_mapent(ap->entry);
- }
-
if (clean) {
if (rmdir(ap->path) == -1) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
@@ -1775,6 +1765,16 @@ static void handle_mounts_cleanup(void *
master_source_unlock(ap->entry);
/*
+ * Submounts are detached threads and don't belong to the
+ * master map entry list so we need to free their resources
+ * here.
+ */
+ if (submount) {
+ master_free_mapent_sources(ap->entry, 1);
+ master_free_mapent(ap->entry);
+ }
+
+ /*
* If we are not a submount send a signal to the signal handler
* so it can join with any completed handle_mounts() threads and
* perform final cleanup.

View File

@ -0,0 +1,43 @@
autofs-5.1.8 - fix return status of mount_autofs()
From: Ian Kent <raven@themaw.net>
The function mount_autofs() collects the status of mounting an autofs
file system but doesn't actually return it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -108,6 +108,7 @@
- fail on empty replicated host name.
- improve handling of ENOENT in sss setautomntent().
- don't immediately call function when waiting.
+- fix return status of mount_autofs().
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
@@ -1217,7 +1217,7 @@ static int autofs_init_ap(struct autofs_
static int mount_autofs(struct autofs_point *ap, const char *root)
{
- int status = 0;
+ int status;
/* No need to create comms fds and command fifo if
* unlinking mounts and exiting.
@@ -1239,7 +1239,7 @@ static int mount_autofs(struct autofs_po
st_add_task(ap, ST_READY);
- return 0;
+ return status;
}
static int handle_packet(struct autofs_point *ap)

View File

@ -0,0 +1,86 @@
autofs-5.1.8 - fix root offset error handling
From: Ian Kent <raven@themaw.net>
If mounting the root or offsets of a multi-mount root fails any mounts
done so far need to be umounted and the multi-mount offset tree deleted
so it can be created cleanly and possibly mounted the next time it's
triggered.
Also, if a subtree that is not the multi-mount root fails the expire
alarm needs to be re-instated so other subtrees (at least the root)
will continue to expire.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 11 ++++++++++-
modules/parse_sun.c | 6 ++++++
3 files changed, 17 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -83,6 +83,7 @@
- improve descriptor open error reporting.
- fix double quoting in auto.smb.
- fix double quoting of ampersand in auto.smb as well.
+- fix root offset error handling.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1163,6 +1163,7 @@ static void *do_mount_direct(void *arg)
struct ioctl_ops *ops = get_ioctl_ops();
struct pending_args *args, mt;
struct autofs_point *ap;
+ struct mapent *me;
struct stat st;
int status, state;
@@ -1226,7 +1227,6 @@ static void *do_mount_direct(void *arg)
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status) {
struct mnt_list *sbmnt;
- struct mapent *me;
struct statfs fs;
unsigned int close_fd = 0;
unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED;
@@ -1267,6 +1267,15 @@ static void *do_mount_direct(void *arg)
mt.ioctlfd, mt.wait_queue_token, -ENOENT);
ops->close(ap->logopt, mt.ioctlfd);
info(ap->logopt, "failed to mount %s", mt.name);
+
+ /* If this is a multi-mount subtree mount failure
+ * ensure the tree continues to expire.
+ */
+ cache_readlock(mt.mc);
+ me = cache_lookup_distinct(mt.mc, mt.name);
+ if (me && IS_MM(me) && !IS_MM_ROOT(me))
+ conditional_alarm_add(ap, ap->exp_runfreq);
+ cache_unlock(mt.mc);
}
pthread_setcancelstate(state, NULL);
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -1125,6 +1125,9 @@ static int mount_subtree(struct autofs_p
if (!len) {
warn(ap->logopt, "path loo long");
cache_unlock(mc);
+ cache_writelock(mc);
+ tree_mapent_delete_offsets(mc, name);
+ cache_unlock(mc);
return 1;
}
key[len] = '/';
@@ -1169,6 +1172,9 @@ static int mount_subtree(struct autofs_p
cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
+ cache_writelock(mc);
+ tree_mapent_delete_offsets(mc, name);
+ cache_unlock(mc);
return 1;
}
}

View File

@ -0,0 +1,57 @@
autofs-5.1.8 - fix set open file limit
From: Ian Kent <raven@themaw.net>
The check of whether the open file limit needs to be changed is not
right, it checks the hard open file limit against what autofs wants
to set it to which is always less than this value. Consequently the
open file limit isn't changed.
autofs should be changing only the soft open file limit but it is
setting both the hard and soft limits. The system hard limit is much
higer than the autofs maximum open files so the hard limit should be
left alone.
While we are here increase the requested maximum soft open file limit
to 20k.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 ++++---
2 files changed, 5 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -79,6 +79,7 @@
- fix nonstrict offset mount fail handling.
- remove intr hosts map mount option.
- fix kernel mount status notification.
+- fix set open file limit.
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
@@ -95,7 +95,7 @@ struct startup_cond suc = {
pthread_key_t key_thread_stdenv_vars;
pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L;
-#define MAX_OPEN_FILES 10240
+#define MAX_OPEN_FILES 20480
int aquire_flag_file(void);
void release_flag_file(void);
@@ -2475,9 +2475,10 @@ int main(int argc, char *argv[])
}
res = getrlimit(RLIMIT_NOFILE, &rlim);
- if (res == -1 || rlim.rlim_max <= MAX_OPEN_FILES) {
+ if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) {
rlim.rlim_cur = MAX_OPEN_FILES;
- rlim.rlim_max = MAX_OPEN_FILES;
+ if (rlim.rlim_max < MAX_OPEN_FILES)
+ rlim.rlim_max = MAX_OPEN_FILES;
}
res = setrlimit(RLIMIT_NOFILE, &rlim);
if (res)

View File

@ -0,0 +1,78 @@
autofs-5.1.8 - fix some sss error return cases
From: Ian Kent <raven@themaw.net>
There are some cases where the error return handling isn't quite right,
fix them.
Also fix a typo. in configuration file comment.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_sss.c | 6 +++---
redhat/autofs.conf.default.in | 2 +-
samples/autofs.conf.default.in | 2 +-
4 files changed, 6 insertions(+), 5 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -147,6 +147,7 @@
- add soucre parameter to module functions.
- add ioctlfd open helper.
- make open files limit configurable.
+- fix some sss error return cases.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_sss.c
+++ autofs-5.1.4/modules/lookup_sss.c
@@ -368,7 +368,7 @@ static int setautomntent_wait(unsigned i
*sss_ctxt = NULL;
}
- if (proto_version(ctxt) == 0 && retry > retries)
+ if (proto_version(ctxt) == 0 && retry >= retries)
ret = ETIMEDOUT;
}
return ret;
@@ -496,7 +496,7 @@ static int getautomntent_wait(unsigned i
info(logopt,
"successfully contacted sssd to get map entry");
else {
- if (retry == retries)
+ if (proto_version(ctxt) == 0 && retry >= retries)
ret = ETIMEDOUT;
}
return ret;
@@ -621,7 +621,7 @@ static int getautomntbyname_wait(unsigne
info(logopt,
"successfully contacted sssd to lookup key value");
else {
- if (proto_version(ctxt) == 0 && retry > retries)
+ if (proto_version(ctxt) == 0 && retry >= retries)
ret = ETIMEDOUT;
}
return ret;
--- autofs-5.1.4.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.4/redhat/autofs.conf.default.in
@@ -209,7 +209,7 @@ mount_nfs_default_protocol = 4
# sss_master_map_wait - When sssd is starting up it can sometimes return
# "no such entry" for a short time until it has read
# in the LDAP map information. Internal default is 0
-# (don't wait) or 10 if sss supports returning EHSTDOWN.
+# (don't wait) or 10 if sss supports returning EHOSTDOWN.
# If there is a problem with autofs not finding the
# master map at startup (when it should) then try setting
# this to 10 or more. If the sss library supports returning
--- autofs-5.1.4.orig/samples/autofs.conf.default.in
+++ autofs-5.1.4/samples/autofs.conf.default.in
@@ -208,7 +208,7 @@ browse_mode = no
# sss_master_map_wait - When sssd is starting up it can sometimes return
# "no such entry" for a short time until it has read
# in the LDAP map information. Internal default is 0
-# (don't wait) or 10 if sss supports returning EHSTDOWN.
+# (don't wait) or 10 if sss supports returning EHOSTDOWN.
# If there is a problem with autofs not finding the
# master map at startup (when it should) then try setting
# this to 10 or more. If the sss library supports returning

View File

@ -0,0 +1,64 @@
autofs-5.1.8 - fix sysconf(3) return handling
From: Fabian Groffen <grobian@gentoo.org>
The sysconf(3) return handling doesn't handle a -1 return with errno
not changed which indicated a maximum or minimum limit that's not
known.
Add handling of this case.
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -91,6 +91,7 @@
- fix use after free in tree_mapent_delete_offset_tree().
- fix memory leak in xdr_exports().
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
+- fix sysconf(3) return handling.
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
@@ -2385,11 +2385,17 @@ void set_tsd_user_vars(unsigned int logo
/* Try to get passwd info */
+ /* sysconf may return -1 with unchanged errno to indicate unlimited
+ * size, same for the call for _SC_GETGR_R_SIZE_MAX below
+ */
+ errno = 0;
tmplen = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (tmplen < 0) {
+ if (tmplen < 0 && errno != 0) {
error(logopt, "failed to get buffer size for getpwuid_r");
goto free_tsv;
}
+ if (tmplen < 0)
+ tmplen = 1024; /* assume something reasonable */
pw_tmp = malloc(tmplen + 1);
if (!pw_tmp) {
@@ -2422,11 +2428,14 @@ void set_tsd_user_vars(unsigned int logo
/* Try to get group info */
+ errno = 0;
grplen = sysconf(_SC_GETGR_R_SIZE_MAX);
- if (grplen < 0) {
+ if (grplen < 0 && errno != 0) {
error(logopt, "failed to get buffer size for getgrgid_r");
goto free_tsv_home;
}
+ if (grplen < 0)
+ grplen = 1024;
gr_tmp = NULL;
status = ERANGE;

View File

@ -0,0 +1,46 @@
autofs-5.1.8 - fix unterminated read in handle_cmd_pipe_fifo_message()
From: Ian Kent <raven@themaw.net>
As Coverity points out the buffer in handle_cmd_pipe_fifo_message()
could be overflowed and end up not terminated so fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -123,6 +123,7 @@
- switch to application wide command pipe.
- get rid of unused field submnt_count.
- fix mount tree startup reconnect.
+- fix unterminated read in handle_cmd_pipe_fifo_message().
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
@@ -1415,7 +1415,6 @@ static void handle_cmd_pipe_fifo_message
int ret;
long pri;
- memset(buffer, 0, sizeof(buffer));
ret = read(fd, &buffer, sizeof(buffer));
if (ret < 0) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
@@ -1423,6 +1422,12 @@ static void handle_cmd_pipe_fifo_message
"read on command pipe returned error: %s", estr);
return;
}
+ if (ret >= sizeof(buffer)) {
+ error(LOGOPT_ANY,
+ "read overrun on command pipe message");
+ return;
+ }
+ buffer[ret] = 0;
sep = strrchr(buffer, ' ');
if (!sep) {

View File

@ -0,0 +1,55 @@
autofs-5.1.8 - fix use after free in tree_mapent_delete_offset_tree()
From: Ian Kent <raven@themaw.net>
The key field of the map entry of the root of the map entry tree to be
deleted can't be used for the key parameter, fix it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 16 +++++++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -88,6 +88,7 @@
- dont fail on duplicate offset entry tree add.
- fix loop under run in cache_get_offset_parent().
- simplify cache_add() a little.
+- fix use after free in tree_mapent_delete_offset_tree().
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
@@ -1666,16 +1666,26 @@ static int tree_mapent_delete_offset_tre
*/
if (MAPENT_ROOT(me) != MAPENT_NODE(me)) {
struct tree_node *root = MAPENT_ROOT(me);
+ char *key;
- debug(logopt, "deleting offset key %s", me->key);
+ key = strdup(me->key);
+ if (!key) {
+ char buf[MAX_ERR_BUF];
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(logopt, "strdup: %s", estr);
+ return 0;
+ }
+
+ debug(logopt, "deleting offset key %s", key);
/* cache_delete won't delete an active offset */
MAPENT_SET_ROOT(me, NULL);
- ret = cache_delete(me->mc, me->key);
+ ret = cache_delete(me->mc, key);
if (ret != CHE_OK) {
MAPENT_SET_ROOT(me, root);
- warn(logopt, "failed to delete offset %s", me->key);
+ warn(logopt, "failed to delete offset %s", key);
}
+ free(key);
} else {
MAPENT_SET_ROOT(me, NULL);
MAPENT_SET_PARENT(me, NULL);

View File

@ -0,0 +1,56 @@
autofs-5.1.8 - fix use_ignore_mount_option description
From: Ian Kent <raven@themaw.net>
Fix a couple of grammer problem with the configuration setting
use_ignore_mount_option description.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
redhat/autofs.conf.default.in | 4 ++--
samples/autofs.conf.default.in | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -126,6 +126,7 @@
- fix unterminated read in handle_cmd_pipe_fifo_message().
- fix memory leak in sasl_do_kinit()
- fix fix mount tree startup reconnect.
+- fix use_ignore_mount_option description.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.4/redhat/autofs.conf.default.in
@@ -187,11 +187,11 @@ mount_nfs_default_protocol = 4
#disable_not_found_message = "no"
#
# use_ignore_mount_option - This option is used to enable the use of autofs
-# pseudo option "disable". This option is used as a
+# pseudo option "ignore". This option is used as a
# hint to user space that the mount entry should be
# ommitted from mount table listings. The default is
# "no" to avoid unexpected changes in behaviour and
-# so is an opt-in setting.
+# is an opt-in setting.
#
#use_ignore_mount_option = no
#
--- autofs-5.1.4.orig/samples/autofs.conf.default.in
+++ autofs-5.1.4/samples/autofs.conf.default.in
@@ -186,11 +186,11 @@ browse_mode = no
#disable_not_found_message = "no"
#
# use_ignore_mount_option - This option is used to enable the use of autofs
-# pseudo option "disable". This option is used as a
+# pseudo option "ignore". This option is used as a
# hint to user space that the mount entry should be
# ommitted from mount table listings. The default is
# "no" to avoid unexpected changes in behaviour and
-# so is an opt-in setting.
+# is an opt-in setting.
#
#use_ignore_mount_option = no
#

View File

@ -0,0 +1,62 @@
autofs-5.1.8 - get rid entry thid field
From: Ian Kent <raven@themaw.net>
Use the autofs_point structure thid and get rid of the copy in struct
master_mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 5 ++---
include/master.h | 1 -
3 files changed, 3 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -129,6 +129,7 @@
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
- fix amd selector function matching.
+- get rid entry thid field.
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
@@ -831,7 +831,6 @@ struct master_mapent *master_new_mapent(
entry->path = tmp;
entry->len = strlen(tmp);
- entry->thid = 0;
entry->age = age;
entry->master = master;
entry->current = NULL;
@@ -1413,7 +1412,7 @@ static int master_do_mount(struct master
handle_mounts_startup_cond_destroy(&suc);
return 0;
}
- entry->thid = ap->thid = thid;
+ ap->thid = thid;
handle_mounts_startup_cond_destroy(&suc);
@@ -1969,7 +1968,7 @@ int master_done(struct master *master)
entry = list_entry(p, struct master_mapent, join);
p = p->next;
list_del(&entry->join);
- pthread_join(entry->thid, NULL);
+ pthread_join(entry->ap->thid, NULL);
master_free_mapent_sources(entry, 1);
master_free_mapent(entry);
}
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -46,7 +46,6 @@ struct map_source {
struct master_mapent {
char *path;
size_t len;
- pthread_t thid;
time_t age;
struct master *master;
pthread_rwlock_t source_lock;

View File

@ -0,0 +1,52 @@
autofs-5.1.8 - get rid of strlen call in handle_packet_missing_direct()
From: Ian Kent <raven@themaw.net>
There is a length field in struct mapent, use it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 7 +++----
2 files changed, 4 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -134,6 +134,7 @@
- add buffer length checks to autofs mount_mount().
- eliminate root param from autofs mount and umount.
- remove redundant fstat from do_mount_direct().
+- get rid of strlen call in handle_packet_missing_direct().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1288,7 +1288,7 @@ int handle_packet_missing_direct(struct
char buf[MAX_ERR_BUF];
int status = 0;
struct timespec wait;
- int ioctlfd, len, state;
+ int ioctlfd, state;
unsigned int kver_major = get_kver_major();
unsigned int kver_minor = get_kver_minor();
@@ -1390,8 +1390,7 @@ int handle_packet_missing_direct(struct
return 0;
}
- len = strlen(me->key);
- if (len >= PATH_MAX) {
+ if (me->len >= PATH_MAX) {
error(ap->logopt, "direct mount path too long %s", me->key);
ops->send_fail(ap->logopt,
ioctlfd, pkt->wait_queue_token, -ENAMETOOLONG);
@@ -1430,7 +1429,7 @@ int handle_packet_missing_direct(struct
mt->ioctlfd = ioctlfd;
mt->mc = mc;
strcpy(mt->name, me->key);
- mt->len = len;
+ mt->len = me->len;
mt->dev = me->dev;
mt->type = NFY_MOUNT;
mt->uid = pkt->uid;

View File

@ -0,0 +1,69 @@
autofs-5.1.8 - get rid of unused field submnt_count
From: Ian Kent <raven@themaw.net>
The autofs mount point struct field submnt_count is present but not
used, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 3 ---
daemon/master.c | 1 -
include/automount.h | 1 -
modules/mount_autofs.c | 2 --
5 files changed, 1 insertion(+), 7 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -121,6 +121,7 @@
- use device id to locate autofs_point when setting log priotity.
- add command pipe handling functions.
- switch to application wide command pipe.
+- get rid of unused field submnt_count.
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
@@ -1737,9 +1737,6 @@ static void handle_mounts_cleanup(void *
if (submount) {
struct mnt_list *mnt;
- /* We are finishing up */
- ap->parent->submnt_count--;
-
/* Submount at ap->path belongs to parent submount list. */
mnts_remove_submount(ap->path);
/* Also remove from parent mounted list */
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -152,7 +152,6 @@ int master_add_autofs_point(struct maste
ap->parent = NULL;
ap->thid = 0;
- ap->submnt_count = 0;
ap->submount = submount;
INIT_LIST_HEAD(&ap->mounts);
INIT_LIST_HEAD(&ap->submounts);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -565,7 +565,6 @@ struct autofs_point {
struct autofs_point *parent; /* Owner of mounts list for submount */
struct list_head mounts; /* List of autofs mounts at current level */
unsigned int submount; /* Is this a submount */
- unsigned int submnt_count; /* Number of submounts */
struct list_head submounts; /* List of child submounts */
struct list_head amdmounts; /* List of non submount amd mounts */
unsigned int shutdown; /* Shutdown notification */
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -358,8 +358,6 @@ int mount_mount(struct autofs_point *ap,
}
nap->thid = thid;
- ap->submnt_count++;
-
handle_mounts_startup_cond_destroy(&suc);
return 0;

View File

@ -0,0 +1,165 @@
autofs-5.1.8 - improve descriptor open error reporting
From: Ian Kent <raven@themaw.net>
Add error message reporting to the descriptor open functions.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 3 ---
daemon/spawn.c | 29 +++++++++++++++++++++++++++++
lib/mounts.c | 10 ++--------
modules/lookup_program.c | 5 +----
5 files changed, 33 insertions(+), 15 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -80,6 +80,7 @@
- remove intr hosts map mount option.
- fix kernel mount status notification.
- fix set open file limit.
+- improve descriptor open error reporting.
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
@@ -864,9 +864,6 @@ static int create_logpri_fifo(struct aut
fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK);
if (fd < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- crit(ap->logopt,
- "Failed to open %s: %s", fifo_name, estr);
unlink(fifo_name);
ret = -1;
goto out_free;
--- autofs-5.1.4.orig/daemon/spawn.c
+++ autofs-5.1.4/daemon/spawn.c
@@ -94,7 +94,12 @@ int open_fd(const char *path, int flags)
#endif
fd = open(path, flags);
if (fd == -1) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open file: %s", estr);
return -1;
}
check_cloexec(fd);
@@ -113,7 +118,12 @@ int open_fd_mode(const char *path, int f
#endif
fd = open(path, flags, mode);
if (fd == -1) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open file: %s", estr);
return -1;
}
check_cloexec(fd);
@@ -123,6 +133,8 @@ int open_fd_mode(const char *path, int f
int open_pipe(int pipefd[2])
{
+ char buf[MAX_ERR_BUF];
+ char *estr;
int ret;
open_mutex_lock();
@@ -145,6 +157,8 @@ done:
return 0;
err:
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open pipe: %s", estr);
return -1;
}
@@ -159,7 +173,12 @@ int open_sock(int domain, int type, int
#endif
fd = socket(domain, type, protocol);
if (fd == -1) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open socket: %s", estr);
return -1;
}
check_cloexec(fd);
@@ -184,7 +203,12 @@ FILE *open_fopen_r(const char *path)
#endif
f = fopen(path, "r");
if (f == NULL) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open file: %s", estr);
return NULL;
}
check_cloexec(fileno(f));
@@ -209,7 +233,12 @@ FILE *open_setmntent_r(const char *table
#endif
tab = fopen(table, "r");
if (tab == NULL) {
+ char buf[MAX_ERR_BUF];
+ char *estr;
+
open_mutex_unlock();
+ estr = strerror_r(errno, buf, sizeof(buf));
+ logerr("failed to open mount table: %s", estr);
return NULL;
}
check_cloexec(fileno(tab));
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2169,11 +2169,8 @@ struct mnt_list *get_mnt_list(const char
return NULL;
tab = open_fopen_r(_PROC_MOUNTS);
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
- logerr("fopen: %s", estr);
+ if (!tab)
return NULL;
- }
while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
len = strlen(mnt->mnt_dir);
@@ -2280,11 +2277,8 @@ static int table_is_mounted(const char *
return 0;
tab = open_fopen_r(_PROC_MOUNTS);
- if (!tab) {
- char *estr = strerror_r(errno, buf, PATH_MAX - 1);
- logerr("fopen: %s", estr);
+ if (!tab)
return 0;
- }
while ((mnt = local_getmntent_r(tab, &mnt_wrk, buf, PATH_MAX * 3))) {
size_t len = strlen(mnt->mnt_dir);
--- autofs-5.1.4.orig/modules/lookup_program.c
+++ autofs-5.1.4/modules/lookup_program.c
@@ -214,11 +214,8 @@ static char *lookup_one(struct autofs_po
* want to send stderr to the syslog, and we don't use spawnl()
* because we need the pipe hooks
*/
- if (open_pipe(pipefd)) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- logerr(MODPREFIX "pipe: %s", estr);
+ if (open_pipe(pipefd))
goto out_error;
- }
if (open_pipe(epipefd)) {
close(pipefd[0]);
close(pipefd[1]);

View File

@ -0,0 +1,59 @@
autofs-5.1.8 - improve handling of ENOENT in sss setautomntent()
From: Ian Kent <raven@themaw.net>
In the sss lookup module function setautomntent() a return of ENOENT
isn't handled quite right.
If ENOENT (rather than EHOSTDOWN) is returned from sss setautomntent()
we should assume the LDAP info. has been read by sss and the entry in
fact doesn't exist.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_sss.c | 16 +++++++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -106,6 +106,7 @@
- fix minus only option handling in concat_options().
- fix incorrect path for is_mounted() in try_remount().
- fail on empty replicated host name.
+- improve handling of ENOENT in sss setautomntent().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/modules/lookup_sss.c
+++ autofs-5.1.4/modules/lookup_sss.c
@@ -394,7 +394,17 @@ static int setautomntent(unsigned int lo
if (ret != ENOENT)
goto error;
} else {
- if (ret != ENOENT && ret != EHOSTDOWN)
+ /* If we get an ENOENT here assume it's accurrate
+ * and return the error.
+ */
+ if (ret == ENOENT) {
+ error(logopt, MODPREFIX
+ "setautomountent: entry for map %s not found",
+ ctxt->mapname);
+ err = NSS_STATUS_NOTFOUND;
+ goto free;
+ }
+ if (ret != EHOSTDOWN)
goto error;
}
@@ -410,6 +420,10 @@ static int setautomntent(unsigned int lo
if (ret == EINVAL)
goto free;
if (ret == ENOENT) {
+ /* Map info. not found after host became available */
+ error(logopt, MODPREFIX
+ "setautomountent: entry for map %s not found",
+ ctxt->mapname);
err = NSS_STATUS_NOTFOUND;
goto free;
}

View File

@ -0,0 +1,160 @@
autofs-5.1.8 - include addtional log info for mounts
From: Ian Kent <raven@themaw.net>
There has been a request to include some additional information when
logging mounts and umounts, specifically host and mount location path.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 7 +++++--
daemon/indirect.c | 2 +-
daemon/spawn.c | 6 +++---
modules/mount_bind.c | 4 ++--
modules/mount_ext2.c | 2 +-
modules/mount_generic.c | 2 +-
modules/mount_nfs.c | 4 +++-
8 files changed, 17 insertions(+), 11 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -127,6 +127,7 @@
- fix memory leak in sasl_do_kinit()
- fix fix mount tree startup reconnect.
- fix use_ignore_mount_option description.
+- include addtional log info for mounts.
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
@@ -857,14 +857,17 @@ static int get_pkt(struct autofs_point *
int do_expire(struct autofs_point *ap, const char *name, int namelen)
{
char buf[PATH_MAX];
+ const char *parent;
int len, ret;
if (*name != '/') {
len = ncat_path(buf, sizeof(buf), ap->path, name, namelen);
+ parent = ap->path;
} else {
len = snprintf(buf, PATH_MAX, "%s", name);
if (len >= PATH_MAX)
len = 0;
+ parent = name;
}
if (!len) {
@@ -872,13 +875,13 @@ int do_expire(struct autofs_point *ap, c
return 1;
}
- info(ap->logopt, "expiring path %s", buf);
+ info(ap->logopt, "expiring path %s on %s", buf, parent);
pthread_cleanup_push(master_source_lock_cleanup, ap->entry);
master_source_readlock(ap->entry);
ret = umount_multi(ap, buf, 1);
if (ret == 0)
- info(ap->logopt, "expired %s", buf);
+ info(ap->logopt, "umounting %s succeeded", buf);
else
warn(ap->logopt, "couldn't complete expire of %s", buf);
pthread_cleanup_pop(1);
--- autofs-5.1.4.orig/daemon/indirect.c
+++ autofs-5.1.4/daemon/indirect.c
@@ -326,7 +326,7 @@ force_umount:
"forcing umount of indirect mount %s", mountpoint);
rv = umount2(mountpoint, MNT_DETACH);
} else {
- info(ap->logopt, "umounted indirect mount %s", mountpoint);
+ info(ap->logopt, "umounting indirect mount %s succeeded", mountpoint);
if (ap->submount)
rm_unwanted(ap, mountpoint, 1);
}
--- autofs-5.1.4.orig/daemon/spawn.c
+++ autofs-5.1.4/daemon/spawn.c
@@ -541,7 +541,7 @@ done:
while (errp && (p = memchr(sp, '\n', errp))) {
*p++ = '\0';
if (sp[0]) /* Don't output empty lines */
- warn(logopt, ">> %s", sp);
+ debug(logopt, ">> %s", sp);
errp -= (p - sp);
sp = p;
}
@@ -552,7 +552,7 @@ done:
if (errp >= ERRBUFSIZ) {
/* Line too long, split */
errbuf[errp] = '\0';
- warn(logopt, ">> %s", errbuf);
+ debug(logopt, ">> %s", errbuf);
errp = 0;
}
}
@@ -566,7 +566,7 @@ done:
if (errp > 0) {
/* End of file without \n */
errbuf[errp] = '\0';
- warn(logopt, ">> %s", errbuf);
+ debug(logopt, ">> %s", errbuf);
}
if (waitpid(f, &ret, 0) != f)
--- autofs-5.1.4.orig/modules/mount_bind.c
+++ autofs-5.1.4/modules/mount_bind.c
@@ -177,7 +177,7 @@ int mount_mount(struct autofs_point *ap,
return err;
} else {
- debug(ap->logopt,
+ mountlog(ap->logopt,
MODPREFIX "mounted %s type %s on %s",
what, fstype, fullpath);
}
@@ -252,7 +252,7 @@ int mount_mount(struct autofs_point *ap,
}
return 1;
} else {
- debug(ap->logopt,
+ mountlog(ap->logopt,
MODPREFIX "symlinked %s -> %s", fullpath, what);
return 0;
}
--- autofs-5.1.4.orig/modules/mount_ext2.c
+++ autofs-5.1.4/modules/mount_ext2.c
@@ -140,7 +140,7 @@ int mount_mount(struct autofs_point *ap,
return 1;
} else {
- debug(ap->logopt,
+ mountlog(ap->logopt,
MODPREFIX "mounted %s type %s on %s",
what, fstype, fullpath);
return 0;
--- autofs-5.1.4.orig/modules/mount_generic.c
+++ autofs-5.1.4/modules/mount_generic.c
@@ -99,7 +99,7 @@ int mount_mount(struct autofs_point *ap,
return 1;
} else {
- debug(ap->logopt, MODPREFIX "mounted %s type %s on %s",
+ mountlog(ap->logopt, MODPREFIX "mounted %s type %s on %s",
what, fstype, fullpath);
return 0;
}
--- autofs-5.1.4.orig/modules/mount_nfs.c
+++ autofs-5.1.4/modules/mount_nfs.c
@@ -400,7 +400,9 @@ dont_probe:
}
if (!err) {
- debug(ap->logopt, MODPREFIX "mounted %s on %s", loc, fullpath);
+ mountlog(ap->logopt,
+ MODPREFIX "mounted %s type %s on %s",
+ loc, fstype, fullpath);
free(loc);
free_host_list(&hosts);
return 0;

View File

@ -0,0 +1,81 @@
autofs-5.1.8 - make amd mapent search function name clear
From: Ian Kent <raven@themaw.net>
When looking for amd sections in the configuration the function to
find mount entries is not named so it is clear what it's trying to
do so change its name. Also make it static since it is called only
once in the same source file.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 7 ++++---
include/master.h | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -112,6 +112,7 @@
- don't close lookup at umount.
- fix deadlock in lookups.
- dont delay expire.
+- make amd mapent search function name clear.
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
@@ -741,7 +741,7 @@ struct master_mapent *master_find_mapent
return NULL;
}
-unsigned int master_partial_match_mapent(struct master *master, const char *path)
+static unsigned int master_partial_match_amd_mapent(struct master *master, const char *path)
{
struct list_head *head, *p;
size_t path_len = strlen(path);
@@ -755,7 +755,7 @@ unsigned int master_partial_match_mapent
entry = list_entry(p, struct master_mapent, list);
- entry_len = strlen(entry->path);
+ entry_len = entry->len;
cmp_len = min(entry_len, path_len);
if (!strncmp(entry->path, path, cmp_len)) {
@@ -806,6 +806,7 @@ struct master_mapent *master_new_mapent(
return NULL;
}
entry->path = tmp;
+ entry->len = strlen(tmp);
entry->thid = 0;
entry->age = age;
@@ -1038,7 +1039,7 @@ static void master_add_amd_mount_section
char *map = NULL;
char *opts;
- ret = master_partial_match_mapent(master, path);
+ ret = master_partial_match_amd_mapent(master, path);
if (ret) {
/* If this amd entry is already present in the
* master map it's not a duplicate, don't issue
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -45,6 +45,7 @@ struct map_source {
struct master_mapent {
char *path;
+ size_t len;
pthread_t thid;
time_t age;
struct master *master;
@@ -109,7 +110,6 @@ void master_source_lock_cleanup(void *);
void master_source_current_wait(struct master_mapent *);
void master_source_current_signal(struct master_mapent *);
struct master_mapent *master_find_mapent(struct master *, const char *);
-unsigned int master_partial_match_mapent(struct master *, const char *);
struct master_mapent *master_new_mapent(struct master *, const char *, time_t);
void master_add_mapent(struct master *, struct master_mapent *);
void master_remove_mapent(struct master_mapent *);

View File

@ -0,0 +1,177 @@
autofs-5.1.8 - make open files limit configurable
From: Ian Kent <raven@themaw.net>
autofs can use quite a few file handles, particularly with very large
direct mount maps or many submounts as is often seen with amd maps.
So make the maximum number of open files configurable.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 13 +++++++------
include/defaults.h | 2 ++
lib/defaults.c | 17 +++++++++++++++++
man/autofs.conf.5.in | 7 +++++++
redhat/autofs.conf.default.in | 11 +++++++++++
samples/autofs.conf.default.in | 11 +++++++++++
7 files changed, 56 insertions(+), 6 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -146,6 +146,7 @@
- eliminate some more alloca usage.
- add soucre parameter to module functions.
- add ioctlfd open helper.
+- make open files limit configurable.
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
@@ -101,8 +101,6 @@ struct startup_cond suc = {
pthread_key_t key_thread_stdenv_vars;
pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L;
-#define MAX_OPEN_FILES 20480
-
int aquire_flag_file(void);
void release_flag_file(void);
@@ -2201,6 +2199,7 @@ int main(int argc, char *argv[])
time_t timeout;
time_t age = monotonic_time(NULL);
struct rlimit rlim;
+ unsigned long max_open_files;
const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM";
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
@@ -2401,11 +2400,13 @@ int main(int argc, char *argv[])
exit(1);
}
+ max_open_files = defaults_get_open_file_limit();
+
res = getrlimit(RLIMIT_NOFILE, &rlim);
- if (res == -1 || rlim.rlim_cur <= MAX_OPEN_FILES) {
- rlim.rlim_cur = MAX_OPEN_FILES;
- if (rlim.rlim_max < MAX_OPEN_FILES)
- rlim.rlim_max = MAX_OPEN_FILES;
+ if (res == -1 || rlim.rlim_cur <= max_open_files) {
+ rlim.rlim_cur = max_open_files;
+ if (rlim.rlim_max < max_open_files)
+ rlim.rlim_max = max_open_files;
}
res = setrlimit(RLIMIT_NOFILE, &rlim);
if (res)
--- autofs-5.1.4.orig/include/defaults.h
+++ autofs-5.1.4/include/defaults.h
@@ -24,6 +24,7 @@
#define DEFAULT_MASTER_MAP_NAME "auto.master"
+#define DEFAULT_OPEN_FILE_LIMIT "20480"
#define DEFAULT_TIMEOUT "600"
#define DEFAULT_MASTER_WAIT "10"
#define DEFAULT_NEGATIVE_TIMEOUT "60"
@@ -157,6 +158,7 @@ unsigned int defaults_read_config(unsign
void defaults_conf_release(void);
const char *defaults_get_master_map(void);
int defaults_master_set(void);
+unsigned long defaults_get_open_file_limit(void);
unsigned int defaults_get_timeout(void);
int defaults_get_master_wait(void);
unsigned int defaults_get_negative_timeout(void);
--- autofs-5.1.4.orig/lib/defaults.c
+++ autofs-5.1.4/lib/defaults.c
@@ -47,6 +47,7 @@
#define NAME_MASTER_MAP "master_map_name"
+#define NAME_OPEN_FILE_LIMIT "open_file_limit"
#define NAME_TIMEOUT "timeout"
#define NAME_MASTER_WAIT "master_wait"
#define NAME_NEGATIVE_TIMEOUT "negative_timeout"
@@ -290,6 +291,11 @@ static int conf_load_autofs_defaults(voi
const char *sec = autofs_gbl_sec;
int ret;
+ ret = conf_update(sec, NAME_OPEN_FILE_LIMIT,
+ DEFAULT_OPEN_FILE_LIMIT, CONF_ENV);
+ if (ret == CFG_FAIL)
+ goto error;
+
ret = conf_update(sec, NAME_TIMEOUT,
DEFAULT_TIMEOUT, CONF_ENV);
if (ret == CFG_FAIL)
@@ -1670,6 +1676,17 @@ int defaults_master_set(void)
return 0;
}
+unsigned long defaults_get_open_file_limit(void)
+{
+ long limit;
+
+ limit = conf_get_number(autofs_gbl_sec, NAME_OPEN_FILE_LIMIT);
+ if (limit < 0)
+ limit = atol(DEFAULT_OPEN_FILE_LIMIT);
+
+ return limit;
+}
+
unsigned int defaults_get_timeout(void)
{
long timeout;
--- autofs-5.1.4.orig/man/autofs.conf.5.in
+++ autofs-5.1.4/man/autofs.conf.5.in
@@ -23,6 +23,13 @@ configuration settings.
.P
Configuration settings available are:
.TP
++.B open_file_limit
++.br
++Set the maximum number of open files. Note there may be other limits
++within the system that prevent this from being set, systemd for example
++may need a setting in the unit file to increase its default. The autofs
++default is 20480.
++.TP
.B timeout
.br
Sets the default mount timeout in seconds. The internal program
--- autofs-5.1.4.orig/redhat/autofs.conf.default.in
+++ autofs-5.1.4/redhat/autofs.conf.default.in
@@ -1,4 +1,15 @@
#
+# Global configuration options.
+#
+# open_file_limit - set the maximum number of open files. Note there
+# may be other limits within the system that prevent
+# this from being set, systemd for example may need
+# a setting in the unit file to increase its default.
+# The autofs default is 20480.
+#
+#open_file_limit = 20480
+#
+#
# Define default options for autofs.
#
[ autofs ]
--- autofs-5.1.4.orig/samples/autofs.conf.default.in
+++ autofs-5.1.4/samples/autofs.conf.default.in
@@ -1,4 +1,15 @@
#
+# Global configuration options.
+#
+# open_file_limit - set the maximum number of open files. Note there
+# may be other limits within the system that prevent
+# this from being set, systemd for example may need
+# a setting in the unit file to increase its default.
+# The autofs default is 20480.
+#
+#open_file_limit = 20480
+#
+#
# Define default options for autofs.
#
[ autofs ]

View File

@ -0,0 +1,75 @@
autofs-5.1.8 - make signal handling consistent
From: Ian Kent <raven@themaw.net>
There's a mixture of usage of sigprocmask() and pthread_sigmask(), change
to use the pthread versions of this for correctness.
The only exception to this is reset_signals() which is done in a forked
process that is single threaded so it's valid to keep them as they are.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 8 ++++----
daemon/spawn.c | 1 -
3 files changed, 5 insertions(+), 5 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -114,6 +114,7 @@
- dont delay expire.
- make amd mapent search function name clear.
- rename statemachine() to signal_handler().
+- make signal handling consistent.
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
@@ -2210,7 +2210,7 @@ static void do_master_list_reset(struct
static int do_master_read_master(struct master *master, time_t *age, int wait)
{
- sigset_t signalset;
+ sigset_t signalset, savesigset;
/* Wait must be at least 1 second */
unsigned int retry_wait = 2;
unsigned int elapsed = 0;
@@ -2221,7 +2221,7 @@ static int do_master_read_master(struct
sigaddset(&signalset, SIGTERM);
sigaddset(&signalset, SIGINT);
sigaddset(&signalset, SIGHUP);
- sigprocmask(SIG_UNBLOCK, &signalset, NULL);
+ pthread_sigmask(SIG_UNBLOCK, &signalset, &savesigset);
while (1) {
struct timespec t = { retry_wait, 0 };
@@ -2247,7 +2247,7 @@ static int do_master_read_master(struct
}
}
- sigprocmask(SIG_BLOCK, &signalset, NULL);
+ pthread_sigmask(SIG_SETMASK, &savesigset, NULL);
return ret;
}
@@ -2294,7 +2294,7 @@ int main(int argc, char *argv[])
sigdelset(&block_sigs, SIGILL);
sigdelset(&block_sigs, SIGFPE);
sigdelset(&block_sigs, SIGTRAP);
- sigprocmask(SIG_BLOCK, &block_sigs, NULL);
+ pthread_sigmask(SIG_BLOCK, &block_sigs, NULL);
program = argv[0];
--- autofs-5.1.4.orig/daemon/spawn.c
+++ autofs-5.1.4/daemon/spawn.c
@@ -46,7 +46,6 @@ void dump_core(void)
sigemptyset(&segv);
sigaddset(&segv, SIGSEGV);
pthread_sigmask(SIG_UNBLOCK, &segv, NULL);
- sigprocmask(SIG_UNBLOCK, &segv, NULL);
raise(SIGSEGV);
}

View File

@ -0,0 +1,131 @@
autofs-5.1.8 - make submount cleanup the same as top level mounts
From: Ian Kent <raven@themaw.net>
We often see segfaults when cleaning up resources at submount shutdown
after changes are made to resolve problems. It's always really hard to
work out what's causing these to happen.
But changing submounts to use the same final cleanup method as top level
mounts eliminates the faulting, at least in the case of the most recent
changes, hopefully this change in proceedure will continue to work.
Admitedly there's some setting of fields to NULL after freeing but that
didn't fix the problem until the procedure change was also made.
In any case the result is a consistency improvement.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 17 +++--------------
daemon/master.c | 19 +++++++++++++++++--
modules/mount_autofs.c | 6 +++---
4 files changed, 24 insertions(+), 19 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -142,6 +142,7 @@
- dont take parent source lock at mount shutdown.
- eliminate buffer usage from handle_mounts_cleanup().
- fix possible use after free in handle_mounts_exit().
+- make submount cleanup the same as top level mounts.
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
@@ -1765,21 +1765,10 @@ static void handle_mounts_cleanup(void *
master_source_unlock(ap->entry);
/*
- * Submounts are detached threads and don't belong to the
- * master map entry list so we need to free their resources
- * here.
+ * Send a signal to the signal handler so it can join with any
+ * completed handle_mounts() threads and perform final cleanup.
*/
- if (submount) {
- master_free_mapent_sources(ap->entry, 1);
- master_free_mapent(ap->entry);
- }
-
- /*
- * If we are not a submount send a signal to the signal handler
- * so it can join with any completed handle_mounts() threads and
- * perform final cleanup.
- */
- if (!submount && !pending)
+ if (!pending)
pthread_kill(signal_handler_thid, SIGTERM);
master_mutex_unlock();
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -384,11 +384,14 @@ static void __master_free_map_source(str
instance = source->instance;
while (instance) {
- if (instance->lookup)
+ if (instance->lookup) {
close_lookup(instance->lookup);
+ instance->lookup = NULL;
+ }
instance = instance->next;
}
close_lookup(source->lookup);
+ source->lookup = NULL;
}
if (source->argv)
free_argv(source->argc, source->argv);
@@ -401,6 +404,7 @@ static void __master_free_map_source(str
__master_free_map_source(instance, 0);
instance = next;
}
+ source->instance = NULL;
}
status = pthread_rwlock_destroy(&source->module_lock);
@@ -863,9 +867,20 @@ void master_add_mapent(struct master *ma
void master_remove_mapent(struct master_mapent *entry)
{
struct master *master = entry->master;
+ struct autofs_point *ap = entry->ap;
+
+ if (ap->submount) {
+ struct mnt_list *mnt;
- if (entry->ap->submount)
+ mnt = mnts_find_submount(ap->path);
+ if (mnt) {
+ warn(ap->logopt,
+ "map entry %s in use at shutdown", ap->path);
+ mnts_put_mount(mnt);
+ }
+ list_add(&entry->join, &master->completed);
return;
+ }
if (!list_empty(&entry->list)) {
list_del_init(&entry->list);
--- autofs-5.1.4.orig/modules/mount_autofs.c
+++ autofs-5.1.4/modules/mount_autofs.c
@@ -28,8 +28,8 @@
#define MODPREFIX "mount(autofs): "
-/* Attribute to create detached thread */
-extern pthread_attr_t th_attr_detached;
+/* Attributes to create handle_mounts() thread */
+extern pthread_attr_t th_attr;
extern struct startup_cond suc;
int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
@@ -327,7 +327,7 @@ int mount_mount(struct autofs_point *ap,
suc.done = 0;
suc.status = 0;
- if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) {
+ if (pthread_create(&thid, &th_attr, handle_mounts, &suc)) {
crit(ap->logopt,
MODPREFIX
"failed to create mount handler thread for %s",

View File

@ -0,0 +1,77 @@
autofs-5.1.8 - remove nonstrict parameter from tree_mapent_umount_offsets()
From: Ian Kent <raven@themaw.net>
The nonstrict parameter of tree_mapent_umount_offsets() ins't useful
because if a real mount at the base of a sub-tree fails to umount all
we can do is re-instate the offset mounts under it which must succeed
for the mount tree to remain useful.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 2 +-
include/mounts.h | 2 +-
lib/mounts.c | 6 +++---
4 files changed, 6 insertions(+), 5 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -92,6 +92,7 @@
- fix memory leak in xdr_exports().
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
- fix sysconf(3) return handling.
+- remove nonstrict parameter from tree_mapent_umount_offsets().
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
@@ -555,7 +555,7 @@ static int umount_subtree_mounts(struct
struct mapent *tmp;
int ret;
- ret = tree_mapent_umount_offsets(me, 1);
+ ret = tree_mapent_umount_offsets(me);
if (!ret) {
warn(ap->logopt,
"some offset mounts still present under %s", path);
--- autofs-5.1.4.orig/include/mounts.h
+++ autofs-5.1.4/include/mounts.h
@@ -182,7 +182,7 @@ int tree_mapent_add_node(struct mapent_c
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
void tree_mapent_cleanup_offsets(struct mapent *oe);
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict);
+int tree_mapent_umount_offsets(struct mapent *oe);
int unlink_mount_tree(struct autofs_point *ap, const char *mp);
void free_mnt_list(struct mnt_list *list);
int is_mounted(const char *mp, unsigned int type);
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -1843,7 +1843,7 @@ static int tree_mapent_umount_offset(str
* Check for and umount subtree offsets resulting from
* nonstrict mount fail.
*/
- ret = tree_mapent_umount_offsets(oe, ctxt->strict);
+ ret = tree_mapent_umount_offsets(oe);
if (!ret)
return 0;
@@ -1975,14 +1975,14 @@ static int tree_mapent_umount_offsets_wo
return tree_mapent_umount_offset(oe, ptr);
}
-int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
+int tree_mapent_umount_offsets(struct mapent *oe)
{
struct tree_node *base = MAPENT_NODE(oe);
struct autofs_point *ap = oe->mc->ap;
struct traverse_subtree_context ctxt = {
.ap = ap,
.base = base,
- .strict = !nonstrict,
+ .strict = 1,
};
int ret;

View File

@ -0,0 +1,58 @@
autofs-5.1.8 - remove redundant stat call in lookup_ghost()
From: Ian Kent <raven@themaw.net>
There's nothing to be gained by checking for existence of the path
here, just trust the mkdir_path() call will return the correct error
if the path exists.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 24 ++++++------------------
2 files changed, 7 insertions(+), 18 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -135,6 +135,7 @@
- eliminate root param from autofs mount and umount.
- remove redundant fstat from do_mount_direct().
- get rid of strlen call in handle_packet_missing_direct().
+- remove redundant stat call in lookup_ghost().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -788,25 +788,13 @@ int lookup_ghost(struct autofs_point *ap
if (!fullpath)
goto next;
- ret = stat(fullpath, &st);
- if (ret == -1 && errno != ENOENT) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt, "stat error %s", estr);
- free(fullpath);
- goto next;
- }
-
- /* Directory already exists? */
- if (!ret) {
- free(fullpath);
- goto next;
- }
-
ret = mkdir_path(fullpath, mp_mode);
- if (ret < 0 && errno != EEXIST) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt,
- "mkdir_path %s failed: %s", fullpath, estr);
+ if (ret < 0) {
+ if (errno != EEXIST) {
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ warn(ap->logopt,
+ "mkdir_path %s failed: %s", fullpath, estr);
+ }
free(fullpath);
goto next;
}

View File

@ -0,0 +1,48 @@
autofs-5.1.8 - remove redundant stat from do_mount_direct()
From: Ian Kent <raven@themaw.net>
In do_mount_direct() a stat() call is used to check mount point
attributes but the fstat() of the ioctlfd is for the same path so
the lower overhead fstat() call can be used to do these checks as
well.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 10 +---------
2 files changed, 2 insertions(+), 9 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -133,6 +133,7 @@
- continue expire immediately after submount check.
- add buffer length checks to autofs mount_mount().
- eliminate root param from autofs mount and umount.
+- remove redundant fstat from do_mount_direct().
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -1197,19 +1197,11 @@ static void *do_mount_direct(void *arg)
}
status = fstat(mt.ioctlfd, &st);
- if (status == -1) {
- error(ap->logopt,
- "can't stat direct mount trigger %s", mt.name);
- mt.status = -ENOENT;
- pthread_setcancelstate(state, NULL);
- pthread_exit(NULL);
- }
-
- status = stat(mt.name, &st);
if (status != 0 || !S_ISDIR(st.st_mode) || st.st_dev != mt.dev) {
error(ap->logopt,
"direct trigger not valid or already mounted %s",
mt.name);
+ mt.status = -EINVAL;
pthread_setcancelstate(state, NULL);
pthread_exit(NULL);
}

View File

@ -0,0 +1,63 @@
autofs-5.1.8 - rename statemachine() to signal_handler()
From: Ian Kent <raven@themaw.net>
Rename function statemachine() to signal_handler() to align with what
the function actually does.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 10 +++++-----
2 files changed, 6 insertions(+), 5 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -113,6 +113,7 @@
- fix deadlock in lookups.
- dont delay expire.
- make amd mapent search function name clear.
+- rename statemachine() to signal_handler().
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
@@ -74,7 +74,7 @@ int do_force_unlink = 0; /* Forceably u
static int start_pipefd[2] = {-1, -1};
static int st_stat = 1;
static int *pst_stat = &st_stat;
-static pthread_t state_mach_thid;
+static pthread_t signal_handler_thid;
static sigset_t block_sigs;
@@ -1576,7 +1576,7 @@ static int do_hup_signal(struct master *
}
/* Deal with all the signal-driven events in the state machine */
-static void *statemachine(void *arg)
+static void *signal_handler(void *arg)
{
sigset_t signalset;
int sig;
@@ -1764,7 +1764,7 @@ static void handle_mounts_cleanup(void *
* perform final cleanup.
*/
if (!submount && !pending)
- pthread_kill(state_mach_thid, SIGTERM);
+ pthread_kill(signal_handler_thid, SIGTERM);
master_mutex_unlock();
@@ -2763,8 +2763,8 @@ int main(int argc, char *argv[])
sd_notify(1, "READY=1");
#endif
- state_mach_thid = pthread_self();
- statemachine(NULL);
+ signal_handler_thid = pthread_self();
+ signal_handler(NULL);
}
master_kill(master_list);

View File

@ -0,0 +1,272 @@
autofs-5.1.8 - serialise lookup module open and reinit
From: Ian Kent <raven@themaw.net>
Add a map source lock to serialise map setting and use of module
structure fields such as the context.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 35 +++++++++++++++++++++--------------
daemon/master.c | 43 +++++++++++++++++++++++++++++++++++++++++++
include/master.h | 5 +++++
modules/parse_amd.c | 26 +++++++++++++++-----------
5 files changed, 85 insertions(+), 25 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -97,6 +97,7 @@
- dont use initgroups() at spawn.
- fix invalid tsv access.
- fix parse module instance mutex naming.
+- serialise lookup module open and reinit.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/lookup.c
+++ autofs-5.1.4/daemon/lookup.c
@@ -318,28 +318,27 @@ static int do_read_map(struct autofs_poi
struct lookup_mod *lookup;
int status;
- lookup = NULL;
- master_source_writelock(ap->entry);
+ pthread_cleanup_push(map_module_lock_cleanup, map);
+ map_module_writelock(map);
if (!map->lookup) {
status = open_lookup(map->type, "", map->format,
map->argc, map->argv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- master_source_unlock(ap->entry);
+ if (status == NSS_STATUS_SUCCESS)
+ map->lookup = lookup;
+ else
debug(ap->logopt,
"lookup module %s open failed", map->type);
- return status;
- }
- map->lookup = lookup;
} else {
- lookup = map->lookup;
- status = lookup->lookup_reinit(map->format,
- map->argc, map->argv,
- &lookup->context);
+ status = map->lookup->lookup_reinit(map->format,
+ map->argc, map->argv,
+ &map->lookup->context);
if (status)
warn(ap->logopt,
"lookup module %s reinit failed", map->type);
}
- master_source_unlock(ap->entry);
+ pthread_cleanup_pop(1);
+ if (status != NSS_STATUS_SUCCESS)
+ return status;
if (!map->stale)
return NSS_STATUS_SUCCESS;
@@ -347,7 +346,11 @@ static int do_read_map(struct autofs_poi
master_source_current_wait(ap->entry);
ap->entry->current = map;
+ pthread_cleanup_push(map_module_lock_cleanup, map);
+ map_module_readlock(map);
+ lookup = map->lookup;
status = lookup->lookup_read_map(ap, age, lookup->context);
+ pthread_cleanup_pop(1);
if (status != NSS_STATUS_SUCCESS)
map->stale = 0;
@@ -812,23 +815,27 @@ int do_lookup_mount(struct autofs_point
struct lookup_mod *lookup;
int status;
+ map_module_writelock(map);
if (!map->lookup) {
status = open_lookup(map->type, "",
map->format, map->argc, map->argv, &lookup);
if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(map);
debug(ap->logopt,
"lookup module %s open failed", map->type);
return status;
}
map->lookup = lookup;
}
-
- lookup = map->lookup;
+ map_module_unlock(map);
master_source_current_wait(ap->entry);
ap->entry->current = map;
+ map_module_readlock(map);
+ lookup = map->lookup;
status = lookup->lookup_mount(ap, name, name_len, lookup->context);
+ map_module_unlock(map);
return status;
}
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -65,6 +65,34 @@ void master_mutex_lock_cleanup(void *arg
return;
}
+void map_module_writelock(struct map_source *map)
+{
+ int status = pthread_rwlock_wrlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_readlock(struct map_source *map)
+{
+ int status = pthread_rwlock_rdlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_unlock(struct map_source *map)
+{
+ int status = pthread_rwlock_unlock(&map->module_lock);
+ if (status)
+ fatal(status);
+}
+
+void map_module_lock_cleanup(void *arg)
+{
+ struct map_source *map = (struct map_source *) arg;
+
+ map_module_unlock(map);
+}
+
int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
unsigned nobind, unsigned ghost, int submount)
{
@@ -155,6 +183,7 @@ master_add_map_source(struct master_mape
struct map_source *source;
char *ntype, *nformat;
const char **tmpargv;
+ int status;
source = malloc(sizeof(struct map_source));
if (!source)
@@ -241,6 +270,10 @@ master_add_map_source(struct master_mape
master_source_unlock(entry);
+ status = pthread_rwlock_init(&source->module_lock, NULL);
+ if (status)
+ fatal(status);
+
return source;
}
@@ -330,6 +363,8 @@ master_get_map_source(struct master_mape
static void __master_free_map_source(struct map_source *source, unsigned int free_cache)
{
+ int status;
+
/* instance map sources are not ref counted */
if (source->ref && --source->ref)
return;
@@ -365,6 +400,10 @@ static void __master_free_map_source(str
}
}
+ status = pthread_rwlock_destroy(&source->module_lock);
+ if (status)
+ fatal(status);
+
free(source);
return;
@@ -496,6 +535,10 @@ master_add_source_instance(struct map_so
if (status)
fatal(status);
+ status = pthread_rwlock_init(&new->module_lock, NULL);
+ if (status)
+ fatal(status);
+
return new;
}
--- autofs-5.1.4.orig/include/master.h
+++ autofs-5.1.4/include/master.h
@@ -35,6 +35,7 @@ struct map_source {
unsigned int stale;
unsigned int recurse;
unsigned int depth;
+ pthread_rwlock_t module_lock;
struct lookup_mod *lookup;
int argc;
const char **argv;
@@ -126,5 +127,9 @@ int __master_list_empty(struct master *)
int master_list_empty(struct master *);
int master_done(struct master *);
int master_kill(struct master *);
+void map_module_writelock(struct map_source *map);
+void map_module_readlock(struct map_source *map);
+void map_module_unlock(struct map_source *map);
+void map_module_lock_cleanup(void *arg);
#endif
--- autofs-5.1.4.orig/modules/parse_amd.c
+++ autofs-5.1.4/modules/parse_amd.c
@@ -1358,14 +1358,6 @@ static int do_host_mount(struct autofs_p
argc = 1;
}
- parse_instance_mutex_lock();
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
- if (status != NSS_STATUS_SUCCESS) {
- debug(ap->logopt, "open lookup module hosts failed");
- parse_instance_mutex_unlock();
- goto out;
- }
-
instance = master_find_source_instance(source,
"hosts", "sun", argc, pargv);
if (!instance) {
@@ -1374,13 +1366,22 @@ static int do_host_mount(struct autofs_p
if (!instance) {
error(ap->logopt, MODPREFIX
"failed to create source instance for hosts map");
- parse_instance_mutex_unlock();
close_lookup(lookup);
goto out;
}
}
- instance->lookup = lookup;
- parse_instance_mutex_unlock();
+
+ map_module_writelock(instance);
+ if (!instance->lookup) {
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
+ if (status != NSS_STATUS_SUCCESS) {
+ map_module_unlock(instance);
+ debug(ap->logopt, "open lookup module hosts failed");
+ goto out;
+ }
+ instance->lookup = lookup;
+ }
+ map_module_unlock(instance);
cache_writelock(source->mc);
me = cache_lookup_distinct(source->mc, name);
@@ -1391,8 +1392,11 @@ static int do_host_mount(struct autofs_p
master_source_current_wait(ap->entry);
ap->entry->current = source;
+ map_module_readlock(instance);
+ lookup = instance->lookup;
ret = lookup->lookup_mount(ap, entry->rhost,
strlen(entry->rhost), lookup->context);
+ map_module_unlock(instance);
if (!strcmp(name, entry->rhost))
goto out;

View File

@ -0,0 +1,140 @@
autofs-5.1.8 - set mapent dev and ino before adding to index
From: Ian Kent <raven@themaw.net>
Set the struct fields dev and ino straight after getting them with
stat() or fstat() so they can be used in cache_set_ino_index() without
being passed in.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 8 ++++++--
daemon/state.c | 2 +-
include/automount.h | 3 +--
lib/cache.c | 11 ++---------
lib/mounts.c | 16 +++++++++++++---
6 files changed, 24 insertions(+), 17 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -136,6 +136,7 @@
- remove redundant fstat from do_mount_direct().
- get rid of strlen call in handle_packet_missing_direct().
- remove redundant stat call in lookup_ghost().
+- set mapent dev and ino before adding to index.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/daemon/direct.c
+++ autofs-5.1.4/daemon/direct.c
@@ -410,6 +410,8 @@ int do_mount_autofs_direct(struct autofs
"failed to stat direct mount trigger %s", me->key);
goto out_umount;
}
+ me->dev = st.st_dev;
+ me->ino = st.st_ino;
if (ap->mode && (err = chmod(me->key, ap->mode)))
warn(ap->logopt, "failed to change mode of %s", me->key);
@@ -422,7 +424,7 @@ int do_mount_autofs_direct(struct autofs
ops->timeout(ap->logopt, ioctlfd, timeout);
notify_mount_result(ap, me->key, timeout, str_direct);
- cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ cache_set_ino_index(me->mc, me);
ops->close(ap->logopt, ioctlfd);
debug(ap->logopt, "mounted trigger %s", me->key);
@@ -765,6 +767,8 @@ int mount_autofs_offset(struct autofs_po
goto out_umount;
goto out_err;
}
+ me->dev = st.st_dev;
+ me->ino = st.st_ino;
ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
if (ioctlfd < 0) {
@@ -773,7 +777,7 @@ int mount_autofs_offset(struct autofs_po
}
ops->timeout(ap->logopt, ioctlfd, timeout);
- cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
+ cache_set_ino_index(me->mc, me);
notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
--- autofs-5.1.4.orig/daemon/state.c
+++ autofs-5.1.4/daemon/state.c
@@ -386,7 +386,7 @@ static int do_readmap_mount(struct autof
valid->ioctlfd = me->ioctlfd;
me->ioctlfd = -1;
/* Set device and inode number of the new mapent */
- cache_set_ino_index(vmc, me->key, me->dev, me->ino);
+ cache_set_ino_index(vmc, me);
cache_unlock(vmc);
/* Set timeout and calculate the expire run frequency */
timeout = get_exp_timeout(ap, map);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -199,8 +199,7 @@ int cache_push_mapent(struct mapent *me,
int cache_pop_mapent(struct mapent *me);
struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map);
struct mapent_cache *cache_init_null_cache(struct master *master);
-int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino);
-/* void cache_set_ino(struct mapent *me, dev_t dev, ino_t ino); */
+int cache_set_ino_index(struct mapent_cache *mc, struct mapent *me);
struct mapent *cache_lookup_ino(struct mapent_cache *mc, dev_t dev, ino_t ino);
struct mapent *cache_lookup_first(struct mapent_cache *mc);
struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me);
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -290,20 +290,13 @@ static u_int32_t ino_hash(dev_t dev, ino
return hashval % size;
}
-int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino)
+int cache_set_ino_index(struct mapent_cache *mc, struct mapent *me)
{
- u_int32_t ino_index = ino_hash(dev, ino, mc->size);
- struct mapent *me;
-
- me = cache_lookup_distinct(mc, key);
- if (!me)
- return 0;
+ u_int32_t ino_index = ino_hash(me->dev, me->ino, mc->size);
ino_index_lock(mc);
list_del_init(&me->ino_index);
list_add(&me->ino_index, &mc->ino_index[ino_index]);
- me->dev = dev;
- me->ino = ino;
ino_index_unlock(mc);
return 1;
--- autofs-5.1.4.orig/lib/mounts.c
+++ autofs-5.1.4/lib/mounts.c
@@ -2761,10 +2761,20 @@ static int remount_active_mount(struct a
ops->close(ap->logopt, fd);
return REMOUNT_STAT_FAIL;
}
- if (type != t_indirect)
- cache_set_ino_index(me->mc, path, st.st_dev, st.st_ino);
- else
+ if (type == t_indirect)
ap->dev = st.st_dev;
+ else {
+ if (strcmp(path, me->key)) {
+ error(ap->logopt,
+ "mount point path mismatch, path %s mapent %s", path, me->key);
+ debug(ap->logopt, "couldn't re-connect to mount %s", path);
+ ops->close(ap->logopt, fd);
+ return REMOUNT_STAT_FAIL;
+ }
+ me->dev = st.st_dev;
+ me->ino = st.st_ino;
+ cache_set_ino_index(me->mc, me);
+ }
notify_mount_result(ap, path, timeout, str_type);
*ioctlfd = fd;

View File

@ -0,0 +1,44 @@
autofs-5.1.8 - simplify cache_add() a little
From: Ian Kent <raven@themaw.net>
If a map entry is being added to an existing hash chain there's an
unneccessarily complicted setting of ->next of the last entry.
Just initialize the map entry ->next field instead and remove the
confusing assignment.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -87,6 +87,7 @@
- fix nonstrict fail handling of last offset mount.
- dont fail on duplicate offset entry tree add.
- fix loop under run in cache_get_offset_parent().
+- simplify cache_add() a little.
xx/xx/2018 autofs-5.1.5
- fix flag file permission.
--- autofs-5.1.4.orig/lib/cache.c
+++ autofs-5.1.4/lib/cache.c
@@ -564,6 +564,7 @@ int cache_add(struct mapent_cache *mc, s
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
me->flags = 0;
+ me->next = NULL;
/*
* We need to add to the end if values exist in order to
@@ -583,7 +584,6 @@ int cache_add(struct mapent_cache *mc, s
existing = next;
}
- me->next = existing->next;
existing->next = me;
}
return CHE_OK;

View File

@ -0,0 +1,568 @@
autofs-5.1.8 - switch to application wide command pipe
From: Ian Kent <raven@themaw.net>
Switch to use the functions previously added to allow a single
application wide command pipe to be used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 426 +++++++++-------------------------------------------
daemon/master.c | 2
include/automount.h | 1
modules/parse_sun.c | 1
5 files changed, 80 insertions(+), 351 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -120,6 +120,7 @@
- add function master_find_mapent_by_devid().
- use device id to locate autofs_point when setting log priotity.
- add command pipe handling functions.
+- switch to application wide command pipe.
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
@@ -69,10 +69,6 @@ const char *cmd_pipe_name = AUTOFS_FIFO_
int start_cmd_pipe_handler(void);
void finish_cmd_pipe_handler(void);
-/* autofs fifo name prefix */
-#define FIFO_NAME_PREFIX "autofs.fifo"
-const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX;
-
const char *global_options; /* Global option, from command line */
static char *pid_file = NULL; /* File in which to keep pid */
@@ -801,319 +797,6 @@ static int fullread(int fd, void *ptr, s
return len;
}
-static char *automount_path_to_fifo(unsigned logopt, const char *path)
-{
- char *fifo_name, *p;
- int name_len = strlen(path) + strlen(fifodir) + 1;
- int ret;
-
- fifo_name = malloc(name_len);
- if (!fifo_name)
- return NULL;
- ret = snprintf(fifo_name, name_len, "%s%s", fifodir, path);
- if (ret >= name_len) {
- info(logopt,
- "fifo path for \"%s\" truncated to \"%s\". This may "
- "lead to --set-log-priority commands being sent to the "
- "wrong automount daemon.", path, fifo_name);
- }
-
- /*
- * An automount path can be made up of subdirectories. So, to
- * create the fifo name, we will just replace instances of '/' with
- * '-'.
- */
- p = fifo_name + strlen(fifodir);
- while (*p != '\0') {
- if (*p == '/')
- *p = '-';
- p++;
- }
-
- debug(logopt, "fifo name %s",fifo_name);
-
- return fifo_name;
-}
-
-static int create_logpri_fifo(struct autofs_point *ap)
-{
- int ret = -1;
- int fd;
- char *fifo_name;
- char buf[MAX_ERR_BUF];
-
- fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
- if (!fifo_name) {
- crit(ap->logopt, "Failed to allocate memory!");
- goto out_free; /* free(NULL) is okay */
- }
-
- ret = unlink(fifo_name);
- if (ret != 0 && errno != ENOENT) {
- crit(ap->logopt,
- "Failed to unlink FIFO. Is the automount daemon "
- "already running?");
- goto out_free;
- }
-
- ret = mkfifo(fifo_name, S_IRUSR|S_IWUSR);
- if (ret != 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- crit(ap->logopt,
- "mkfifo for %s failed: %s", fifo_name, estr);
- goto out_free;
- }
-
- fd = open_fd(fifo_name, O_RDWR|O_NONBLOCK);
- if (fd < 0) {
- unlink(fifo_name);
- ret = -1;
- goto out_free;
- }
-
- ap->logpri_fifo = fd;
-
-out_free:
- free(fifo_name);
- return ret;
-}
-
-int destroy_logpri_fifo(struct autofs_point *ap)
-{
- int ret = -1;
- int fd = ap->logpri_fifo;
- char *fifo_name;
- char buf[MAX_ERR_BUF];
-
- if (fd == -1)
- return 0;
-
- fifo_name = automount_path_to_fifo(ap->logopt, ap->path);
- if (!fifo_name) {
- crit(ap->logopt, "Failed to allocate memory!");
- goto out_free; /* free(NULL) is okay */
- }
-
- ap->logpri_fifo = -1;
-
- ret = close(fd);
- if (ret != 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt,
- "close for fifo %s: %s", fifo_name, estr);
- }
-
- ret = unlink(fifo_name);
- if (ret != 0) {
- warn(ap->logopt,
- "Failed to unlink FIFO. Was the fifo created OK?");
- }
-
-out_free:
- free(fifo_name);
- return ret;
-}
-
-static void cleanup_stale_logpri_fifo_pipes(void)
-{
- size_t prefix_len = strlen(FIFO_NAME_PREFIX);
- char *dir = AUTOFS_FIFO_DIR;
- size_t dir_len = strlen(dir);
- struct dirent *dent;
- DIR *dfd;
- int ret;
-
- dfd = opendir(dir);
- if (!dfd) {
- warn(LOGOPT_ANY, "failed to open fifo dir %s", dir);
- return;
- }
-
- while ((dent = readdir(dfd))) {
- char fifo_path[PATH_MAX];
-
- if (!(dent->d_type & DT_FIFO))
- continue;
- if (strncmp(FIFO_NAME_PREFIX, dent->d_name, prefix_len))
- continue;
- if ((dir_len + 1 + strlen(dent->d_name)) >= PATH_MAX) {
- warn(LOGOPT_ANY, "fifo path too long for buffer");
- continue;
- }
-
- strcpy(fifo_path, dir);
- strcat(fifo_path, "/");
- strcat(fifo_path, dent->d_name);
-
- ret = unlink(fifo_path);
- if (ret == -1) {
- char buf[MAX_ERR_BUF];
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(LOGOPT_ANY, "unlink of fifo failed: %s", estr);
- }
- }
-
- closedir(dfd);
-}
-
-static void handle_fifo_message(int fd)
-{
- struct autofs_point *ap;
- int ret;
- char buffer[PIPE_BUF];
- char *end, *sep;
- long pri;
- char buf[MAX_ERR_BUF];
- dev_t devid;
-
- memset(buffer, 0, sizeof(buffer));
- ret = read(fd, &buffer, sizeof(buffer));
- if (ret < 0) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(LOGOPT_ANY, "read on fifo returned error: %s", estr);
- return;
- }
-
- sep = strrchr(buffer, ' ');
- if (!sep) {
- error(LOGOPT_ANY, "Incorrect cmd message format %s.", buffer);
- return;
- }
- sep++;
-
- errno = 0;
- devid = strtol(buffer, &end, 10);
- if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) {
- debug(LOGOPT_ANY, "strtol reported a range error.");
- error(LOGOPT_ANY, "Invalid cmd message format %s.", buffer);
- return;
- }
- if ((devid == 0 && errno == EINVAL) || end == buffer) {
- debug(LOGOPT_ANY, "devid id is expected to be a integer.");
- return;
- }
-
- ap = master_find_mapent_by_devid(master_list, devid);
- if (!ap) {
- error(LOGOPT_ANY, "Can't locate autofs_point for device id %ld.", devid);
- return;
- }
-
- errno = 0;
- pri = strtol(sep, &end, 10);
- if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) {
- debug(ap->logopt, "strtol reported an %s. Failed to set "
- "log priority.", pri == LONG_MIN ? "underflow" : "overflow");
- return;
- }
- if ((pri == 0 && errno == EINVAL) || end == sep) {
- debug(ap->logopt, "priority is expected to be an integer "
- "in the range 0-7 inclusive.");
- return;
- }
-
- if (pri > LOG_DEBUG || pri < LOG_EMERG) {
- debug(ap->logopt, "invalid log priority (%ld) received "
- "on fifo", pri);
- return;
- }
-
- /*
- * OK, the message passed all of the sanity checks. The
- * automounter actually only supports three log priorities.
- * Everything is logged at log level debug, deamon messages
- * and everything except debug messages are logged with the
- * verbose setting and only error and critical messages are
- * logged when debugging isn't enabled.
- */
- if (pri >= LOG_WARNING) {
- if (pri == LOG_DEBUG) {
- set_log_debug_ap(ap);
- info(ap->logopt, "Debug logging set for %s", ap->path);
- } else {
- set_log_verbose_ap(ap);
- info(ap->logopt, "Verbose logging set for %s", ap->path);
- }
- } else {
- if (ap->logopt & LOGOPT_ANY)
- info(ap->logopt, "Basic logging set for %s", ap->path);
- set_log_norm_ap(ap);
- }
-}
-
-static int set_log_priority(const char *path, int priority)
-{
- struct ioctl_ops *ops = get_ioctl_ops();
- int fd;
- char *fifo_name;
- char buf[FIFO_BUF_SIZE];
- int ret;
- dev_t devid;
-
- if (!ops) {
- fprintf(stderr, "Could not get ioctl ops\n");
- return -1;
- } else {
- ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
- if (ret == -1 || ret == 0) {
- fprintf(stderr,
- "Could not find device id for mount %s\n", path);
- return -1;
- }
- }
-
- if (priority > LOG_DEBUG || priority < LOG_EMERG) {
- fprintf(stderr, "Log priority %d is invalid.\n", priority);
- fprintf(stderr, "Please specify a number in the range 0-7.\n");
- return -1;
- }
-
- /*
- * This is an ascii based protocol, so we want the string
- * representation of the integer log priority.
- */
- ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority);
- if (ret >= FIFO_BUF_SIZE) {
- fprintf(stderr, "Invalid device id or log priotity\n");
- return -1;
- }
-
- fifo_name = automount_path_to_fifo(LOGOPT_NONE, path);
- if (!fifo_name) {
- fprintf(stderr, "%s: Failed to allocate memory!\n",
- __FUNCTION__);
- return -1;
- }
-
- /*
- * Specify O_NONBLOCK so that the open will fail if there is no
- * daemon reading from the other side of the FIFO.
- */
- fd = open_fd(fifo_name, O_WRONLY|O_NONBLOCK);
- if (fd < 0) {
- fprintf(stderr, "%s: open of %s failed with %s\n",
- __FUNCTION__, fifo_name, strerror(errno));
- fprintf(stderr, "%s: perhaps the fifo wasn't setup,"
- " please check your log for more information\n", __FUNCTION__);
- free(fifo_name);
- return -1;
- }
-
- if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
- fprintf(stderr, "Failed to change logging priority. ");
- fprintf(stderr, "write to fifo failed: %s.\n",
- strerror(errno));
- close(fd);
- free(fifo_name);
- return -1;
- }
- close(fd);
- free(fifo_name);
- fprintf(stdout, "Successfully set log priority for %s.\n", path);
-
- return 0;
-}
-
static void dummy(int sig)
{
}
@@ -1122,18 +805,14 @@ static int get_pkt(struct autofs_point *
{
struct sigaction sa;
sigset_t signalset;
- struct pollfd fds[2];
- int pollfds = 2;
+ struct pollfd fds[1];
+ int pollfds = 1;
char buf[MAX_ERR_BUF];
size_t read;
char *estr;
fds[0].fd = ap->pipefd;
fds[0].events = POLLIN;
- fds[1].fd = ap->logpri_fifo;
- fds[1].events = POLLIN;
- if (fds[1].fd == -1)
- pollfds--;
sa.sa_handler = dummy;
sigemptyset(&sa.sa_mask);
@@ -1172,11 +851,6 @@ static int get_pkt(struct autofs_point *
}
return read;
}
-
- if (fds[1].fd != -1 && fds[1].revents & POLLIN) {
- debug(ap->logopt, "message pending on control fifo.");
- handle_fifo_message(fds[1].fd);
- }
}
}
@@ -1235,11 +909,6 @@ static int autofs_init_ap(struct autofs_
ap->pipefd = pipefd[0];
ap->kpipefd = pipefd[1];
- if (create_logpri_fifo(ap) < 0) {
- logmsg("could not create FIFO for path %s\n", ap->path);
- logmsg("dynamic log level changes not available for %s", ap->path);
- }
-
return 0;
}
@@ -1260,11 +929,6 @@ static int mount_autofs(struct autofs_po
else
status = mount_autofs_indirect(ap, root);
- if (status < 0) {
- destroy_logpri_fifo(ap);
- return -1;
- }
-
st_add_task(ap, ST_READY);
return status;
@@ -1831,6 +1495,68 @@ static void handle_cmd_pipe_fifo_message
}
}
+static int set_log_priority(const char *path, int priority)
+{
+ struct ioctl_ops *ops = get_ioctl_ops();
+ char buf[FIFO_BUF_SIZE];
+ dev_t devid;
+ int fd;
+ int ret;
+
+ if (!ops) {
+ fprintf(stderr, "Could not get ioctl ops\n");
+ return -1;
+ } else {
+ ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
+ if (ret == -1 || ret == 0) {
+ fprintf(stderr,
+ "Could not find device id for mount %s\n", path);
+ return -1;
+ }
+ }
+
+ if (priority > LOG_DEBUG || priority < LOG_EMERG) {
+ fprintf(stderr, "Log priority %d is invalid.\n", priority);
+ fprintf(stderr, "Please specify a number in the range 0-7.\n");
+ return -1;
+ }
+
+ /*
+ * This is an ascii based protocol, so we want the string
+ * representation of the integer log priority.
+ */
+ ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority);
+ if (ret >= FIFO_BUF_SIZE) {
+ fprintf(stderr, "Invalid device id or log priotity\n");
+ return -1;
+ }
+
+ /*
+ * Specify O_NONBLOCK so that the open will fail if there is no
+ * daemon reading from the other side of the FIFO.
+ */
+ fd = open_fd(cmd_pipe_name, O_WRONLY|O_NONBLOCK);
+ if (fd < 0) {
+ fprintf(stderr, "%s: open of %s failed with %s\n",
+ __FUNCTION__, cmd_pipe_name, strerror(errno));
+ fprintf(stderr, "%s: perhaps the fifo wasn't setup,"
+ " please check your log for more information\n", __FUNCTION__);
+ return -1;
+ }
+
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
+ fprintf(stderr, "Failed to change logging priority. ");
+ fprintf(stderr, "write to fifo failed: %s.\n",
+ strerror(errno));
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ fprintf(stdout, "Successfully set log priority for %s.\n", path);
+
+ return 0;
+}
+
static void cmd_pipe_dummy(int sig)
{
}
@@ -2031,8 +1757,6 @@ static void handle_mounts_cleanup(void *
master_remove_mapent(ap->entry);
master_source_unlock(ap->entry);
- destroy_logpri_fifo(ap);
-
/*
* Submounts are detached threads and don't belong to the
* master map entry list so we need to free their resources
@@ -2970,6 +2694,18 @@ int main(int argc, char *argv[])
init_ioctl_ctl();
+ if (!start_cmd_pipe_handler()) {
+ logerr("%s: failed to create command pipe handler thread!", program);
+ master_kill(master_list);
+ if (start_pipefd[1] != -1) {
+ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
+ close(start_pipefd[1]);
+ }
+ release_flag_file();
+ macro_free_global_table();
+ exit(1);
+ }
+
if (!alarm_start_handler()) {
logerr("%s: failed to create alarm handler thread!", program);
master_kill(master_list);
@@ -3035,13 +2771,7 @@ int main(int argc, char *argv[])
}
}
- /* If the option to unlink all autofs mounts and exit has
- * been given remove logpri fifo files as all the mounts
- * will be detached leaving them stale.
- */
- if (do_force_unlink & UNLINK_AND_EXIT)
- cleanup_stale_logpri_fifo_pipes();
- else {
+ if (!(do_force_unlink & UNLINK_AND_EXIT)) {
/*
* Mmm ... reset force unlink umount so we don't also do
* this in future when we receive a HUP signal.
@@ -3065,6 +2795,8 @@ int main(int argc, char *argv[])
master_kill(master_list);
+ finish_cmd_pipe_handler();
+
if (pid_file) {
unlink(pid_file);
pid_file = NULL;
--- autofs-5.1.4.orig/daemon/master.c
+++ autofs-5.1.4/daemon/master.c
@@ -112,8 +112,6 @@ int master_add_autofs_point(struct maste
ap->state = ST_INIT;
- ap->logpri_fifo = -1;
-
ap->path = strdup(entry->path);
if (!ap->path) {
free(ap);
--- autofs-5.1.4.orig/include/automount.h
+++ autofs-5.1.4/include/automount.h
@@ -551,7 +551,6 @@ struct autofs_point {
int pipefd; /* File descriptor for pipe */
int kpipefd; /* Kernel end descriptor for pipe */
int ioctlfd; /* File descriptor for ioctls */
- int logpri_fifo; /* FIFO used for changing log levels */
dev_t dev; /* "Device" number assigned by kernel */
struct master_mapent *entry; /* Master map entry for this mount */
unsigned int type; /* Type of map direct or indirect */
--- autofs-5.1.4.orig/modules/parse_sun.c
+++ autofs-5.1.4/modules/parse_sun.c
@@ -82,7 +82,6 @@ static struct parse_context default_cont
1 /* Do slashify_colons */
};
-int destroy_logpri_fifo(struct autofs_point *ap);
static char *concat_options(char *left, char *right);
/* Free all storage associated with this context */

View File

@ -0,0 +1,155 @@
autofs-5.1.8 - use device id to locate autofs_point when setting log priotity
From: Ian Kent <raven@themaw.net>
Using a fifo pipe for every autofs mount to dynamically set the log
priority is expensive in terms of the number of file handles used.
It would be better to use a single file handle and locate the autofs
mount point by it's id to set the log priority.
Start by making the communication pipe send the device id as well as
the log priority to be set and use the newly added helper function
master_find_mapent_by_devid() to locate the autofs mount to change the
log priority.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 63 ++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 54 insertions(+), 10 deletions(-)
--- autofs-5.1.4.orig/CHANGELOG
+++ autofs-5.1.4/CHANGELOG
@@ -118,6 +118,7 @@
- fix incorrect print format specifiers in get_pkt().
- eliminate last remaining state_pipe usage.
- add function master_find_mapent_by_devid().
+- use device id to locate autofs_point when setting log priotity.
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
@@ -59,6 +59,8 @@ unsigned int mp_mode = 0755;
unsigned int nfs_mount_uses_string_options = 0;
static struct nfs_mount_vers vers, check = {1, 1, 1};
+#define FIFO_BUF_SIZE 25
+
/* autofs fifo name prefix */
#define FIFO_NAME_PREFIX "autofs.fifo"
const char *fifodir = AUTOFS_FIFO_DIR "/" FIFO_NAME_PREFIX;
@@ -946,35 +948,57 @@ static void cleanup_stale_logpri_fifo_pi
closedir(dfd);
}
-static void handle_fifo_message(struct autofs_point *ap, int fd)
+static void handle_fifo_message(int fd)
{
+ struct autofs_point *ap;
int ret;
char buffer[PIPE_BUF];
- char *end;
+ char *end, *sep;
long pri;
char buf[MAX_ERR_BUF];
+ dev_t devid;
memset(buffer, 0, sizeof(buffer));
ret = read(fd, &buffer, sizeof(buffer));
if (ret < 0) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- warn(ap->logopt, "read on fifo returned error: %s", estr);
+ warn(LOGOPT_ANY, "read on fifo returned error: %s", estr);
+ return;
+ }
+
+ sep = strrchr(buffer, ' ');
+ if (!sep) {
+ error(LOGOPT_ANY, "Incorrect cmd message format %s.", buffer);
+ return;
+ }
+ sep++;
+
+ errno = 0;
+ devid = strtol(buffer, &end, 10);
+ if ((devid == LONG_MIN || devid == LONG_MAX) && errno == ERANGE) {
+ debug(LOGOPT_ANY, "strtol reported a range error.");
+ error(LOGOPT_ANY, "Invalid cmd message format %s.", buffer);
+ return;
+ }
+ if ((devid == 0 && errno == EINVAL) || end == buffer) {
+ debug(LOGOPT_ANY, "devid id is expected to be a integer.");
return;
}
- if (ret != 2) {
- debug(ap->logopt, "expected 2 bytes, received %d.", ret);
+ ap = master_find_mapent_by_devid(master_list, devid);
+ if (!ap) {
+ error(LOGOPT_ANY, "Can't locate autofs_point for device id %ld.", devid);
return;
}
errno = 0;
- pri = strtol(buffer, &end, 10);
+ pri = strtol(sep, &end, 10);
if ((pri == LONG_MIN || pri == LONG_MAX) && errno == ERANGE) {
debug(ap->logopt, "strtol reported an %s. Failed to set "
"log priority.", pri == LONG_MIN ? "underflow" : "overflow");
return;
}
- if ((pri == 0 && errno == EINVAL) || end == buffer) {
+ if ((pri == 0 && errno == EINVAL) || end == sep) {
debug(ap->logopt, "priority is expected to be an integer "
"in the range 0-7 inclusive.");
return;
@@ -1011,9 +1035,24 @@ static void handle_fifo_message(struct a
static int set_log_priority(const char *path, int priority)
{
+ struct ioctl_ops *ops = get_ioctl_ops();
int fd;
char *fifo_name;
- char buf[2];
+ char buf[FIFO_BUF_SIZE];
+ int ret;
+ dev_t devid;
+
+ if (!ops) {
+ fprintf(stderr, "Could not get ioctl ops\n");
+ return -1;
+ } else {
+ ret = ops->mount_device(LOGOPT_ANY, path, 0, &devid);
+ if (ret == -1 || ret == 0) {
+ fprintf(stderr,
+ "Could not find device id for mount %s\n", path);
+ return -1;
+ }
+ }
if (priority > LOG_DEBUG || priority < LOG_EMERG) {
fprintf(stderr, "Log priority %d is invalid.\n", priority);
@@ -1025,7 +1064,11 @@ static int set_log_priority(const char *
* This is an ascii based protocol, so we want the string
* representation of the integer log priority.
*/
- snprintf(buf, sizeof(buf), "%d", priority);
+ ret = snprintf(buf, sizeof(buf), "%ld %d", devid, priority);
+ if (ret >= FIFO_BUF_SIZE) {
+ fprintf(stderr, "Invalid device id or log priotity\n");
+ return -1;
+ }
fifo_name = automount_path_to_fifo(LOGOPT_NONE, path);
if (!fifo_name) {
@@ -1124,7 +1167,7 @@ static int get_pkt(struct autofs_point *
if (fds[1].fd != -1 && fds[1].revents & POLLIN) {
debug(ap->logopt, "message pending on control fifo.");
- handle_fifo_message(ap, fds[1].fd);
+ handle_fifo_message(fds[1].fd);
}
}
}

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

@ -8,7 +8,7 @@
Summary: A tool for automatically mounting and unmounting filesystems
Name: autofs
Version: 5.1.4
Release: 68%{?dist}
Release: 113%{?dist}
Epoch: 1
License: GPLv2+
Group: System Environment/Daemons
@ -234,6 +234,103 @@ Patch211: autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch
Patch212: autofs-5.1.7-fix-amd-section-mounts-map-reload.patch
Patch213: autofs-5.1.7-fix-amd-hosts-mount-expire.patch
Patch214: autofs-5.1.7-fix-offset-entries-order.patch
Patch215: autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch
Patch216: autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch
Patch217: autofs-5.1.7-fix-hosts-map-offset-order.patch
Patch218: autofs-5.1.7-fix-direct-mount-deadlock.patch
Patch219: autofs-5.1.7-fix-lookup_prune_one_cache-refactoring-change.patch
Patch220: autofs-5.1.7-add-missing-description-of-null-map-option.patch
Patch221: autofs-5.1.6-fix-empty-mounts-list-return-from-unlink_mount_tree.patch
Patch222: autofs-5.1.7-fix-nonstrict-offset-mount-fail-handling.patch
Patch223: autofs-5.1.6-remove-intr-hosts-map-mount-option.patch
Patch224: autofs-5.1.8-fix-kernel-mount-status-notification.patch
Patch225: autofs-5.1.8-fix-set-open-file-limit.patch
Patch226: autofs-5.1.8-improve-descriptor-open-error-reporting.patch
Patch227: autofs-5.1.6-fix-double-quoting-in-auto.smb.patch
Patch228: autofs-5.1.6-fix-double-quoting-of-ampersand-in-auto.smb-as-well.patch
Patch229: autofs-5.1.8-fix-root-offset-error-handling.patch
Patch230: autofs-5.1.8-fix-nonstrict-fail-handling-of-last-offset-mount.patch
Patch231: autofs-5.1.8-dont-fail-on-duplicate-host-export-entry.patch
Patch232: autofs-5.1.8-fix-loop-under-run-in-cache_get_offset_parent.patch
Patch233: autofs-5.1.8-simplify-cache_add-a-little.patch
Patch234: autofs-5.1.8-fix-use-after-free-in-tree_mapent_delete_offset_tree.patch
Patch235: autofs-5.1.8-fix-memory-leak-in-xdr_exports.patch
Patch236: autofs-5.1.8-avoid-calling-pthread_getspecific-with-NULL-key_thread_attempt_id.patch
Patch237: autofs-5.1.8-fix-sysconf-return-handling.patch
Patch238: autofs-5.1.4-make-umount_ent-recognise-forced-umount.patch
Patch239: autofs-5.1.8-remove-nonstrict-parameter-from-tree_mapent_umount_offsets.patch
Patch240: autofs-5.1.8-fix-handling-of-incorrect-return-from-umount_ent.patch
Patch241: autofs-5.1.8-dont-use-initgroups-at-spawn.patch
Patch242: autofs-5.1.8-fix-invalid-tsv-access.patch
Patch243: autofs-5.1.8-fix-parse-module-instance-mutex-naming.patch
Patch244: autofs-5.1.8-serialise-lookup-module-open-and-reinit.patch
Patch245: autofs-5.1.8-coverity-fix-for-invalid-access.patch
Patch246: autofs-5.1.8-fix-hosts-map-deadlock-on-restart.patch
Patch247: autofs-5.1.8-fix-deadlock-with-hosts-map-reload.patch
Patch248: autofs-5.1.8-fix-memory-leak-in-update_hosts_mounts.patch
Patch249: autofs-5.1.7-fix-concat_options-error-handling.patch
Patch250: autofs-5.1.8-fix-minus-only-option-handling-in-concat_options.patch
Patch251: autofs-5.1.8-fix-incorrect-path-for-is_mounted-in-try_remount.patch
Patch252: autofs-5.1.8-fail-on-empty-replicated-host-name.patch
Patch253: autofs-5.1.8-improve-handling-of-ENOENT-in-sss-setautomntent.patch
Patch254: autofs-5.1.8-dont-immediately-call-function-when-waiting.patch
Patch260: autofs-5.1.8-fix-return-status-of-mount_autofs.patch
Patch261: autofs-5.1.8-dont-close-lookup-at-umount.patch
Patch262: autofs-5.1.8-fix-deadlock-in-lookups.patch
Patch263: autofs-5.1.8-dont-delay-expire.patch
Patch264: autofs-5.1.8-make-amd-mapent-search-function-name-clear.patch
Patch265: autofs-5.1.8-rename-statemachine-to-signal_handler.patch
Patch266: autofs-5.1.8-make-signal-handling-consistent.patch
Patch267: autofs-5.1.7-fix-incorrect-print-format-specifiers.patch
Patch268: autofs-5.1.8-eliminate-last-remaining-state_pipe-usage.patch
Patch269: autofs-5.1.8-add-function-master_find_mapent_by_devid.patch
Patch270: autofs-5.1.8-use-device-id-to-locate-autofs_point-when-setting-log-priotity.patch
Patch271: autofs-5.1.8-add-command-pipe-handling-functions.patch
Patch272: autofs-5.1.8-switch-to-application-wide-command-pipe.patch
Patch273: autofs-5.1.8-get-rid-of-unused-field-submnt_count.patch
Patch274: autofs-5.1.8-fix-mount-tree-startup-reconnect.patch
Patch275: autofs-5.1.8-fix-unterminated-read-in-handle_cmd_pipe_fifo_message.patch
Patch300: autofs-5.1.8-fix-memory-leak-in-sasl_do_kinit.patch
Patch301: autofs-5.1.8-fix-fix-mount-tree-startup-reconnect.patch
Patch302: autofs-5.1.8-fix-use_ignore_mount_option-description.patch
Patch303: autofs-5.1.8-include-addtional-log-info-for-mounts.patch
Patch304: autofs-5.1.8-fix-amd-selector-function-matching.patch
Patch305: autofs-5.1.8-get-rid-entry-thid-field.patch
Patch306: autofs-5.1.8-continue-expire-immediately-after-submount-check.patch
Patch307: autofs-5.1.7-add-buffer-length-checks-to-autofs-mount_mount.patch
Patch308: autofs-5.1.8-eliminate-realpath-from-mount-of-submount.patch
Patch309: autofs-5.1.8-eliminate-root-param-from-autofs-mount-and-umount.patch
Patch310: autofs-5.1.8-remove-redundant-stat-from-do_mount_direct.patch
Patch311: autofs-5.1.8-get-rid-of-strlen-call-in-handle_packet_missing_direct.patch
Patch312: autofs-5.1.8-remove-redundant-stat-call-in-lookup_ghost.patch
Patch313: autofs-5.1.8-set-mapent-dev-and-ino-before-adding-to-index.patch
Patch314: autofs-5.1.8-change-to-use-printf-functions-in-amd-parser.patch
Patch315: autofs-5.1.8-dont-call-umount_subtree_mounts-on-parent-at-umount.patch
Patch316: autofs-5.1.8-dont-take-parent-source-lock-at-mount-shutdown.patch
Patch317: autofs-5.1.7-eliminate-buffer-usage-from-handle_mounts_cleanup.patch
Patch318: autofs-5.1.8-fix-possible-use-after-free-in-handle_mounts_exit.patch
Patch319: autofs-5.1.8-make-submount-cleanup-the-same-as-top-level-mounts.patch
Patch320: autofs-5.1.7-eliminate-some-more-alloca-usage.patch
Patch321: autofs-5.1.8-add-soucre-parameter-to-module-functions.patch
Patch322: autofs-5.1.8-add-ioctlfd-open-helper.patch
Patch323: autofs-5.1.8-make-open-files-limit-configurable.patch
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
%if %{with_systemd}
BuildRequires: systemd-units
@ -510,6 +607,102 @@ echo %{version}-%{release} > .version
%patch212 -p1
%patch213 -p1
%patch214 -p1
%patch215 -p1
%patch216 -p1
%patch217 -p1
%patch218 -p1
%patch219 -p1
%patch220 -p1
%patch221 -p1
%patch222 -p1
%patch223 -p1
%patch224 -p1
%patch225 -p1
%patch226 -p1
%patch227 -p1
%patch228 -p1
%patch229 -p1
%patch230 -p1
%patch231 -p1
%patch232 -p1
%patch233 -p1
%patch234 -p1
%patch235 -p1
%patch236 -p1
%patch237 -p1
%patch238 -p1
%patch239 -p1
%patch240 -p1
%patch241 -p1
%patch242 -p1
%patch243 -p1
%patch244 -p1
%patch245 -p1
%patch246 -p1
%patch247 -p1
%patch248 -p1
%patch249 -p1
%patch250 -p1
%patch251 -p1
%patch252 -p1
%patch253 -p1
%patch254 -p1
%patch260 -p1
%patch261 -p1
%patch262 -p1
%patch263 -p1
%patch264 -p1
%patch265 -p1
%patch266 -p1
%patch267 -p1
%patch268 -p1
%patch269 -p1
%patch270 -p1
%patch271 -p1
%patch272 -p1
%patch273 -p1
%patch274 -p1
%patch275 -p1
%patch300 -p1
%patch301 -p1
%patch302 -p1
%patch303 -p1
%patch304 -p1
%patch305 -p1
%patch306 -p1
%patch307 -p1
%patch308 -p1
%patch309 -p1
%patch310 -p1
%patch311 -p1
%patch312 -p1
%patch313 -p1
%patch314 -p1
%patch315 -p1
%patch316 -p1
%patch317 -p1
%patch318 -p1
%patch319 -p1
%patch320 -p1
%patch321 -p1
%patch322 -p1
%patch323 -p1
%patch324 -p1
%patch325 -p1
%patch326 -p1
%patch327 -p1
%patch328 -p1
%patch329 -p1
%patch330 -p1
%build
LDFLAGS=-Wl,-z,now
@ -605,6 +798,255 @@ fi
%dir /etc/auto.master.d
%changelog
* 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.
- Resolves: rhbz#2213267
* Wed Jul 12 2023 Ian Kent <ikent@redhat.com> - 5.1.4-108
- bz2216877 - When looking up included maps, sometimes autofs does not
consult all the included files in order
- fix the "fix incorrect matching of cached wildcard key" patch.
- Related: rhbz#2216877
* Wed Jul 05 2023 Ian Kent <ikent@redhat.com> - 5.1.4-107
- bz2216877 - When looking up included maps, sometimes autofs does not
consult all the included files in order
- fix incorrect matching of cached wildcard key
- Resolves: rhbz#2216877
* Fri Jun 16 2023 Ian Kent <ikent@redhat.com> - 5.1.4-106
- bz2214444 - The sss lookup modules handles error return incorrectly
in some cases
- fix some sss error return cases.
- Resolves: rhbz#2214444
* Mon Jun 12 2023 Ian Kent <ikent@redhat.com> - 5.1.4-105
- bz2207801 - amd map format netgoup selector function not working
- fix date for revision 104 changelog entry.
- fix use_ignore_mount_option description.
- include addtional log info for mounts.
- fix amd selector function matching.
- get rid entry thid field.
- continue expire immediately after submount check.
- add buffer length checks to autofs mount_mount().
- eliminate realpath from mount of submount.
- eliminate root param from autofs mount and umount.
- remove redundant fstat from do_mount_direct().
- get rid of strlen call in handle_packet_missing_direct().
- remove redundant stat call in lookup_ghost().
- set mapent dev and ino before adding to index.
- change to use printf functions in amd parser.
- dont call umount_subtree_mounts() on parent at umount.
- dont take parent source lock at mount shutdown.
- eliminate buffer usage from handle_mounts_cleanup().
- fix possible use after free in handle_mounts_exit().
- make submount cleanup the same as top level mounts.
- eliminate some more alloca usage.
- add soucre parameter to module functions.
- add ioctlfd open helper.
- make open files limit configurable.
- Resolves: rhbz#2207801
* Fri May 19 2023 Ian Kent <ikent@redhat.com> - 5.1.4-104
- bz2208408 - autofs fails to start with combination of +auto.master and
local direct map lookups after upgrading to 5.1.4-93.el8
- fix memory leak in sasl_do_kinit() (Coverity).
- fix fix mount tree startup reconnect.
- Resolves: rhbz#2208408
* Mon Mar 20 2023 Ian Kent <ikent@redhat.com> - 5.1.4-103
- bz2177998 - deadlock while reading amd maps
- rebuild to avoid possible NVR problems.
- Related: rhbz#2177998
* Mon Mar 20 2023 Ian Kent <ikent@redhat.com> - 5.1.4-102
- bz2177998 - deadlock while reading amd maps
- fix return status of mount_autofs().
- don't close lookup at umount.
- fix deadlock in lookups.
- dont delay expire.
- make amd mapent search function name clear.
- rename statemachine() to signal_handler().
- make signal handling consistent.
- fix incorrect print format specifiers in get_pkt().
- eliminate last remaining state_pipe usage.
- add function master_find_mapent_by_devid().
- use device id to locate autofs_point when setting log priotity.
- add command pipe handling functions.
- switch to application wide command pipe.
- get rid of unused field submnt_count.
- fix mount tree startup reconnect.
- fix unterminated read in handle_cmd_pipe_fifo_message() (Coverity).
- Resolves: rhbz#2177998
* Wed Feb 08 2023 Ian Kent <ikent@redhat.com> - 5.1.4-93
- bz2165143 - Autofs reports can't connect to sssd, retry for 10 seconds when
real problem is empty LDAP object
- improve handling of ENOENT in sss setautomntent().
- dont immediately call function when waiting.
- Resolves: rhbz#2165143
* Tue Jan 24 2023 Ian Kent <ikent@redhat.com> - 5.1.4-92
- bz2161336 - Users can trigger a simple autofs DoS with wildcard automounter maps
- fail on empty trailing replicated host name.
- Resolves: rhbz#2161336
* Mon Dec 05 2022 Ian Kent <ikent@redhat.com> - 5.1.4-91
- bz2148872 - autofs: errors in autofs-5.1.4-83.el8.x86_64 when restarting
autofs with busy directories
- fix incorrect path for is_mounted() in try_remount().
- Resolves: rhbz#2148872
* Mon Dec 05 2022 Ian Kent <ikent@redhat.com> - 5.1.4-90
- bz2149206 - RHEL9: automount does not handle null option string after
"-" anymore
- fix changelog entry.
- Related: rhbz#2149206
* Mon Dec 05 2022 Ian Kent <ikent@redhat.com> - 5.1.4-89
- bz2149206 - RHEL9: automount does not handle null option string after
"-" anymore
- fix concat_options() error handling.
- fix minus only option handling in concat_options().
- Resolves: rhbz#2149206
* Tue Nov 29 2022 Ian Kent <ikent@redhat.com> - 5.1.4-88
- bz2139504 - segfault due to lookup_mod->context address being freed
and reused while multiple threads were using it
- fix memory leak in update_hosts_mounts().
- Related: rhbz#2139504
* Sun Nov 27 2022 Ian Kent <ikent@redhat.com> - 5.1.4-87
- bz2139504 - segfault due to lookup_mod->context address being freed
and reused while multiple threads were using it
- fix hosts map deadlock on restart.
- fix deadlock with hosts map reload.
- Related: rhbz#2139504
* Wed Nov 23 2022 Ian Kent <ikent@redhat.com> - 5.1.4-86
- bz2139504 - segfault due to lookup_mod->context address being freed
and reused while multiple threads were using it
- coverity fix for invalid access.
- Related: rhbz#2139504
* Wed Nov 09 2022 Ian Kent <ikent@redhat.com> - 5.1.4-85
- bz2139504 - segfault due to lookup_mod->context address being freed
and reused while multiple threads were using it
- fix parse module instance mutex naming.
- serialise lookup module open and reinit.
- Resolves: rhbz#2139504
* Tue Oct 04 2022 Ian Kent <ikent@redhat.com> - 5.1.4-84
- bz2130034 - automount -m crashes with Segmentation fault (core dumped)
- fix invalid tsv access.
- Resolves: rhbz#2130034
* Wed May 18 2022 Ian Kent <ikent@redhat.com> - 5.1.4-83
- bz2069097 - libnss_sss: threads stuck at sss_nss_lock from initgroups
- dont use initgroups() at spawn.
- Resolves: rhbz#2069097
* Tue Feb 15 2022 Ian Kent <ikent@redhat.com> - 5.1.4-82
- bz2052122 - autofs attempts unmount on directory in use
- make umount_ent() recognise forced umount.
- remove nonstrict parameter from tree_mapent_umount_offsets().
- fix handling of incorrect return from umount_ent().
- Resolves: rhbz#2052122
* Mon Feb 14 2022 Ian Kent <ikent@redhat.com> - 5.1.4-81
- bz2033552 - Using -hosts option does not work after upgrading from 8.4 to 8.5
- fix root offset error handling.
- fix nonstrict fail handling of last offset mount.
- dont fail on duplicate offset entry tree add.
- fix loop under run in cache_get_offset_parent().
- simplify cache_add() a little.
- fix use after free in tree_mapent_delete_offset_tree().
- fix memory leak in xdr_exports().
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
- fix sysconf(3) return handling.
- Resolves: rhbz#2033552
* Fri Dec 03 2021 Ian Kent <ikent@redhat.com> - 5.1.4-77
- bz2025509 - Autofs auto.smb awk script fails on shares with dollar signs
- fix double quoting in auto.smb.
- fix double quoting of ampersand in auto.smb as well.
- Resolves: rhbz#2025509
* Thu Dec 02 2021 Ian Kent <ikent@redhat.com> - 5.1.4-76
- bz2025963 - autofs service has not proper limits set to be able to handle many mounts
- fix set open file limit.
- improve descriptor open error reporting.
- Resolves: rhbz#2025963
* Wed Dec 01 2021 Ian Kent <ikent@redhat.com> - 5.1.4-75
- bz2023740 - autofs: send FAIL cmd/ioctl mess when encountering problems
with mount trigger
- fix kernel mount status notification.
- Resolves: rhbz#2023740
* Tue Jun 22 2021 Ian Kent <ikent@redhat.com> - 5.1.4-74
- bz1974309 - Removal of default intr mount option while using -hosts
and host.net
- remove intr hosts map mount option.
- fix previous changelog entry revision.
- Resolves: rhbz#1974309
* Fri Jun 18 2021 Ian Kent <ikent@redhat.com> - 5.1.4-73
- bz1973025 - /net mount being not cleanly mounted and unmounted
- correct patch, fix nonstrict offset mount fail handling.
- Related: rhbz#1973025
* Fri Jun 18 2021 Ian Kent <ikent@redhat.com> - 5.1.4-72
- bz1973025 - /net mount being not cleanly mounted and unmounted
- fix nonstrict offset mount fail handling.
- Resolves: rhbz#1973025
* Tue Jun 08 2021 Ian Kent <ikent@redhat.com> - 5.1.4-71
- bz1969210 - autofs: already mounted as other than autofs or failed to unlink
entry in tree
- fix empty mounts list return from unlink_mount_tree().
- Resolves: rhbz#1969210
* Tue Jun 01 2021 Ian Kent <ikent@redhat.com> - 5.1.4-70
- bz1965862 - A recent Coverity change can cause an infinit loop on map reload
- fix lookup_prune_one_cache() refactoring change.
- bz1963129 - auto.master manpage doesn't mention -null or other built-in maps
- add missing desciption of null map option.
- Resolves: rhbz#1965862 rhbz#1963129
* Wed May 19 2021 Ian Kent <ikent@redhat.com> - 5.1.4-69
- bz1961492 - autofs: regression in offset ordering
- fix offset entries order.
- use mapent tree root for tree_mapent_add_node().
- eliminate redundant cache lookup in tree_mapent_add_node().
- fix hosts map offset order.
- fix direct mount deadlock.
- Resolves: rhbz#1961492
* Mon May 10 2021 Ian Kent <ikent@redhat.com> - 5.1.4-68
- bz1958487 - autofs amd mounts present in the configuration get umounted
on reload