vanhofen
3 years ago
29 changed files with 2089 additions and 0 deletions
@ -0,0 +1,104 @@ |
|||
autofs-5.1.7 - add ext_mount_hash_mutex lock helpers |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: check_return: Calling "pthread_mutex_lock" without checking |
|||
return value. |
|||
|
|||
Well, I use helpers to do this in many places so can't really disagree. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 26 ++++++++++++++++++++------ |
|||
2 files changed, 21 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b1b28888..ff44ac25 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -65,6 +65,7 @@
|
|||
- fix double free in parse_mapent(). |
|||
- refactor lookup_prune_one_cache() a bit. |
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
+- add ext_mount_hash_mutex lock helpers.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 3996eb5e..c24d1a88 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path)
|
|||
return mnt_name; |
|||
} |
|||
|
|||
+static void ext_mount_hash_mutex_lock(void)
|
|||
+{
|
|||
+ int status = pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ if (status)
|
|||
+ fatal(status);
|
|||
+}
|
|||
+
|
|||
+static void ext_mount_hash_mutex_unlock(void)
|
|||
+{
|
|||
+ int status = pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ if (status)
|
|||
+ fatal(status);
|
|||
+}
|
|||
+
|
|||
static struct ext_mount *ext_mount_lookup(const char *mp) |
|||
{ |
|||
uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash)); |
|||
@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, const char *umount)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
|
|||
em = ext_mount_lookup(path); |
|||
if (em) { |
|||
@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, const char *umount)
|
|||
|
|||
ret = 1; |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
|||
@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
|
|||
em = ext_mount_lookup(path); |
|||
if (!em) |
|||
@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path)
|
|||
ret = 1; |
|||
} |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
|||
@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path)
|
|||
struct ext_mount *em; |
|||
int ret = 0; |
|||
|
|||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_lock();
|
|||
em = ext_mount_lookup(path); |
|||
if (!em) |
|||
goto done; |
|||
ret = em->ref; |
|||
done: |
|||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
|||
+ ext_mount_hash_mutex_unlock();
|
|||
return ret; |
|||
} |
|||
|
@ -0,0 +1,42 @@ |
|||
autofs-5.1.7 - add length check in umount_subtree_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: fixed_size_dest: You might overrun the 4097-character |
|||
fixed-size string "key" by copying "me->key" without |
|||
checking the length. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 5 +++++ |
|||
2 files changed, 6 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 224f58d6..9e385ba9 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -55,6 +55,7 @@
|
|||
- fix possible memory leak in master_parse(). |
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
- fix double unlock in parse_mount(). |
|||
+- add length check in umount_subtree_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 48472d5f..70506d83 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
|||
left++; |
|||
} |
|||
|
|||
+ if (me->len > PATH_MAX) {
|
|||
+ crit(ap->logopt, "me->key too long for buffer");
|
|||
+ return 1;
|
|||
+ }
|
|||
+
|
|||
strcpy(key, me->key); |
|||
|
|||
cache_unlock(mc); |
@ -0,0 +1,55 @@ |
|||
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(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b29d2ed8..f5f0da76 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -76,6 +76,7 @@
|
|||
- eliminate redundant cache lookup in tree_mapent_add_node(). |
|||
- fix hosts map offset order. |
|||
- fix direct mount deadlock. |
|||
+- add missing description of null map option.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|||
index 72fbfd23..16717015 100644
|
|||
--- a/man/auto.master.5.in
|
|||
+++ b/man/auto.master.5.in
|
|||
@@ -265,6 +265,25 @@ accessing /net/myserver will mount exports from myserver on directories below
|
|||
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
|
|||
+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 |
@ -0,0 +1,42 @@ |
|||
autofs-5.1.7 - add missing free in handle_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice |
|||
|
|||
No it's not, but root isn't freed before the fatal call which crashes |
|||
automount so add a free() before the fatal() call. |
|||
|
|||
It appears Coverity doesn't recognise pthread_exit() as an exit condition. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9c3ede45..62a918a9 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -50,6 +50,7 @@
|
|||
- check for offset with no mount location. |
|||
- remove mounts_mutex. |
|||
- remove unused variable from get_exports(). |
|||
+- add missing free in handle_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 28c4d1ee..48472d5f 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -1922,6 +1922,8 @@ 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); |
|||
} |
|||
|
@ -0,0 +1,44 @@ |
|||
autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: var_deref_model: Passing null pointer "tree" to |
|||
"tree_traverse_inorder", which dereferences it. |
|||
|
|||
This obviously can't happen but deal with it anyway to quiet Coverity. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 6 ++++-- |
|||
2 files changed, 5 insertions(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b79aebc8..b1b28888 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -64,6 +64,7 @@
|
|||
- fix missing lock release in mount_subtree(). |
|||
- fix double free in parse_mapent(). |
|||
- refactor lookup_prune_one_cache() a bit. |
|||
+- cater for empty mounts list in mnts_get_expire_list().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 883e3743..3996eb5e 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
|||
} |
|||
} |
|||
|
|||
- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
|||
- tree_free(tree);
|
|||
+ if (tree) {
|
|||
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
|||
+ tree_free(tree);
|
|||
+ }
|
|||
done: |
|||
mnts_hash_mutex_unlock(); |
|||
} |
@ -0,0 +1,45 @@ |
|||
autofs-5.1.7 - dont try umount after stat() ENOENT fail |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: Calling function "umount" that uses "me->key" after a check |
|||
function. This can cause a time-of-check, time-of-use race |
|||
condition. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 6 +++++- |
|||
2 files changed, 6 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 7add6c55..c7bc0c39 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -57,6 +57,7 @@
|
|||
- fix double unlock in parse_mount(). |
|||
- add length check in umount_subtree_mounts(). |
|||
- fix flags check in umount_multi(). |
|||
+- dont try umount after stat() ENOENT fail.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index a33f9f91..3bd714e6 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
ret = stat(me->key, &st); |
|||
if (ret == -1) { |
|||
+ int save_errno = errno;
|
|||
+
|
|||
error(ap->logopt, |
|||
"failed to stat direct mount trigger %s", me->key); |
|||
- goto out_umount;
|
|||
+ if (save_errno != ENOENT)
|
|||
+ goto out_umount;
|
|||
+ goto out_err;
|
|||
} |
|||
|
|||
ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key); |
@ -0,0 +1,47 @@ |
|||
autofs-5.1.7 - dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Using an ioctl (AUTOFS_DEV_IOCTL_CLOSEMOUNT) to close an autofs mount |
|||
file handle can race with copy_to_user() so the file handle needs to |
|||
be closed using close(2) instead. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/dev-ioctl-lib.c | 10 +--------- |
|||
2 files changed, 2 insertions(+), 9 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 06bf24b8..51e7767e 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -68,6 +68,7 @@
|
|||
- add ext_mount_hash_mutex lock helpers. |
|||
- fix amd section mounts map reload. |
|||
- fix dandling symlink creation if nis support is not available. |
|||
+- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
|
|||
index e7a1b42a..6b549d73 100644
|
|||
--- a/lib/dev-ioctl-lib.c
|
|||
+++ b/lib/dev-ioctl-lib.c
|
|||
@@ -404,15 +404,7 @@ err:
|
|||
/* Close */ |
|||
static int dev_ioctl_close(unsigned int logopt, int ioctlfd) |
|||
{ |
|||
- struct autofs_dev_ioctl param;
|
|||
-
|
|||
- init_autofs_dev_ioctl(¶m);
|
|||
- param.ioctlfd = ioctlfd;
|
|||
-
|
|||
- if (ioctl(ctl.devfd, AUTOFS_DEV_IOCTL_CLOSEMOUNT, ¶m) == -1)
|
|||
- return -1;
|
|||
-
|
|||
- return 0;
|
|||
+ return close(ioctlfd);
|
|||
} |
|||
|
|||
static int ioctl_close(unsigned int logopt, int ioctlfd) |
@ -0,0 +1,90 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 5a767360..81b6ce6a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -73,6 +73,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().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index f7768ce5..5a7a0b89 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -170,7 +170,7 @@ 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_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); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 9ec547ea..6b24a6c2 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree_node *n)
|
|||
} |
|||
|
|||
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_cache *mc,
|
|||
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 |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index c75bcc8e..12844a30 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1546,7 +1546,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); |
|||
} |
@ -0,0 +1,52 @@ |
|||
autofs-5.1.7 - fix amd hosts mount expire |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
When swicthing to use the mnt_list to track mounts for expire, if the |
|||
amd hosts map entry name is for the host short name, the amd mount |
|||
entry for the short name gets removed. This causes a subsequent mounts |
|||
for host exports to fail. |
|||
|
|||
What should happen is the short name amd entry not be removed and a |
|||
mounted mount entry for the symlinked FQDN mount added so it expires. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_amd.c | 9 +++++---- |
|||
2 files changed, 6 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 698cc27a..94eb6a2c 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -70,6 +70,7 @@
|
|||
- fix dandling symlink creation if nis support is not available. |
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
- fix lookup_prune_one_cache() refactoring change. |
|||
+- fix amd hosts mount expire.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
|
|||
index 64c1ce63..163174cd 100644
|
|||
--- a/modules/parse_amd.c
|
|||
+++ b/modules/parse_amd.c
|
|||
@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|||
if (!rv) { |
|||
/* |
|||
* If entry->path doesn't match the mnt->mp then |
|||
- * the mount point path has changed and a new
|
|||
- * mnt_list entry added for it, so remove the
|
|||
- * original.
|
|||
+ * it's a "host" map and the mount point path is
|
|||
+ * different to the lookup name. Add a new mnt_list
|
|||
+ * entry so that both the symlinked name and the
|
|||
+ * mount expire.
|
|||
*/ |
|||
if (strcmp(this->path, mnt->mp)) |
|||
- mnts_remove_amdmount(this->path);
|
|||
+ mnts_add_mount(ap, this->rhost, MNTS_INDIRECT|MNTS_MOUNTED);
|
|||
break; |
|||
} |
|||
/* Not mounted, remove the mnt_list entry from amdmount list */ |
@ -0,0 +1,124 @@ |
|||
autofs-5.1.7 - fix amd section mounts map reload |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Master map section mounts (amd format mounts) get umounted on reload. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
|||
2 files changed, 81 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ff44ac25..ddc07912 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -66,6 +66,7 @@
|
|||
- refactor lookup_prune_one_cache() a bit. |
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
- add ext_mount_hash_mutex lock helpers. |
|||
+- fix amd section mounts map reload.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master.c b/daemon/master.c
|
|||
index 84743f80..f99359c5 100644
|
|||
--- a/daemon/master.c
|
|||
+++ b/daemon/master.c
|
|||
@@ -882,6 +882,83 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int f
|
|||
return master; |
|||
} |
|||
|
|||
+static void master_update_amd_mount_section_mount(struct master *master,
|
|||
+ const char *path, time_t age)
|
|||
+{
|
|||
+ unsigned int m_logopt = master->logopt;
|
|||
+ struct master_mapent *entry;
|
|||
+ struct map_source *source;
|
|||
+ unsigned int loglevel;
|
|||
+ unsigned int logopt;
|
|||
+ unsigned int flags;
|
|||
+ time_t timeout;
|
|||
+ char *map;
|
|||
+ char *opts;
|
|||
+
|
|||
+ entry = master_find_mapent(master, path);
|
|||
+ if (!entry)
|
|||
+ return;
|
|||
+
|
|||
+ map = conf_amd_get_map_name(path);
|
|||
+ if (!map)
|
|||
+ return;
|
|||
+
|
|||
+ /* amd top level mounts have only one map */
|
|||
+ source = entry->maps;
|
|||
+ if (strcmp(source->name, map) != 0) {
|
|||
+ struct map_source *new;
|
|||
+ char *type;
|
|||
+ char *argv[2];
|
|||
+
|
|||
+ type = conf_amd_get_map_type(path);
|
|||
+ argv[0] = map;
|
|||
+ argv[1] = NULL;
|
|||
+
|
|||
+ new = master_add_map_source(entry, type, "amd",
|
|||
+ age, 1, (const char **) argv);
|
|||
+ if (!new) {
|
|||
+ error(m_logopt,
|
|||
+ "failed to add source for amd section mount %s",
|
|||
+ path);
|
|||
+ if (type)
|
|||
+ free(type);
|
|||
+ goto out;
|
|||
+ }
|
|||
+ master_free_map_source(source, 0);
|
|||
+ entry->maps = new;
|
|||
+ source = new;
|
|||
+ if (type)
|
|||
+ free(type);
|
|||
+ }
|
|||
+
|
|||
+ loglevel = conf_amd_get_log_options();
|
|||
+ logopt = m_logopt;
|
|||
+ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO)
|
|||
+ logopt = LOGOPT_DEBUG;
|
|||
+ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR)
|
|||
+ logopt = LOGOPT_VERBOSE;
|
|||
+
|
|||
+ flags = conf_amd_get_flags(path);
|
|||
+ if (flags & CONF_BROWSABLE_DIRS)
|
|||
+ entry->ap->flags |= MOUNT_FLAG_GHOST;
|
|||
+
|
|||
+ opts = conf_amd_get_map_options(path);
|
|||
+ if (opts) {
|
|||
+ if (strstr(opts, "cache:=all"))
|
|||
+ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL;
|
|||
+ free(opts);
|
|||
+ }
|
|||
+
|
|||
+ entry->ap->logopt = logopt;
|
|||
+
|
|||
+ timeout = conf_amd_get_dismount_interval(path);
|
|||
+ set_exp_timeout(entry->ap, source, timeout);
|
|||
+ source->master_line = 0;
|
|||
+ entry->age = age;
|
|||
+out:
|
|||
+ free(map);
|
|||
+}
|
|||
+
|
|||
static void master_add_amd_mount_section_mounts(struct master *master, time_t age) |
|||
{ |
|||
unsigned int m_logopt = master->logopt; |
|||
@@ -916,8 +993,10 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag
|
|||
* master map it's not a duplicate, don't issue |
|||
* an error message. |
|||
*/ |
|||
- if (ret == 1)
|
|||
+ if (ret == 1) {
|
|||
+ master_update_amd_mount_section_mount(master, path, age);
|
|||
goto next; |
|||
+ }
|
|||
info(m_logopt, |
|||
"amd section mount path conflict, %s ignored", |
|||
path); |
@ -0,0 +1,40 @@ |
|||
autofs-5.1.7 - fix arg not used in error print |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: extra_argument: This argument was not used by the format |
|||
string: "key". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 4 +--- |
|||
2 files changed, 2 insertions(+), 3 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f11aa1c7..1d56c96f 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -60,6 +60,7 @@
|
|||
- dont try umount after stat() ENOENT fail. |
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
- fix dead code in mnts_add_mount(). |
|||
+- fix arg not used in error print.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 018b9c80..883e3743 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
|||
} |
|||
|
|||
if (MAPENT_ROOT(base) != MAPENT_NODE(base)) { |
|||
- error(logopt,
|
|||
- "failed to find multi-mount root of offset tree",
|
|||
- key);
|
|||
+ error(logopt, "key %s is not multi-mount root", root);
|
|||
return 0; |
|||
} |
|||
tree = MAPENT_ROOT(base); |
@ -0,0 +1,39 @@ |
|||
autofs-5.1.7 - fix dandling symlink creation if nis support is not available |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
If NIS support is not available a dangling symlink is created pointing |
|||
from lookup_nis.so to (a non-existent) lookup_yp.so. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/Makefile | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ddc07912..06bf24b8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -67,6 +67,7 @@
|
|||
- cater for empty mounts list in mnts_get_expire_list(). |
|||
- add ext_mount_hash_mutex lock helpers. |
|||
- fix amd section mounts map reload. |
|||
+- fix dandling symlink creation if nis support is not available.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/Makefile b/modules/Makefile
|
|||
index 91dc20ab..6908da06 100644
|
|||
--- a/modules/Makefile
|
|||
+++ b/modules/Makefile
|
|||
@@ -77,7 +77,9 @@ install: all
|
|||
install -c $(MODS) -m 755 $(INSTALLROOT)$(autofslibdir) |
|||
-rm -f $(INSTALLROOT)$(autofslibdir)/mount_smbfs.so |
|||
ln -fs lookup_file.so $(INSTALLROOT)$(autofslibdir)/lookup_files.so |
|||
+ifeq ($(YPCLNT), 1)
|
|||
ln -fs lookup_yp.so $(INSTALLROOT)$(autofslibdir)/lookup_nis.so |
|||
+endif
|
|||
ifeq ($(LDAP), 1) |
|||
ln -fs lookup_ldap.so $(INSTALLROOT)$(autofslibdir)/lookup_ldaps.so |
|||
endif |
@ -0,0 +1,55 @@ |
|||
autofs-5.1.7 - fix dead code in mnts_add_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 8 ++------ |
|||
2 files changed, 3 insertions(+), 6 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f95b1aa6..f11aa1c7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -59,6 +59,7 @@
|
|||
- fix flags check in umount_multi(). |
|||
- dont try umount after stat() ENOENT fail. |
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
+- fix dead code in mnts_add_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index ef69cec1..018b9c80 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
if (*name == '/') { |
|||
mp = strdup(name); |
|||
if (!mp) |
|||
- goto fail;
|
|||
+ return NULL;
|
|||
} else { |
|||
int len = ap->len + strlen(name) + 2; |
|||
|
|||
mp = malloc(len); |
|||
if (!mp) |
|||
- goto fail;
|
|||
+ return NULL;
|
|||
strcpy(mp, ap->path); |
|||
strcat(mp, "/"); |
|||
strcat(mp, name); |
|||
@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
|||
free(mp); |
|||
|
|||
return this; |
|||
-fail:
|
|||
- if (mp)
|
|||
- free(mp);
|
|||
- return NULL;
|
|||
} |
|||
|
|||
void mnts_remove_mount(const char *mp, unsigned int flags) |
@ -0,0 +1,135 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9e341e06..b29d2ed8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -75,6 +75,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.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 3bd714e6..d37dd676 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/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_point *ap)
|
|||
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_point *ap)
|
|||
* failed umount. |
|||
*/ |
|||
error = do_umount_autofs_direct(ap, me); |
|||
+ /* cache became invalid, restart */
|
|||
+ if (error == -1)
|
|||
+ goto restart;
|
|||
if (!error) |
|||
goto done; |
|||
|
|||
diff --git a/daemon/state.c b/daemon/state.c
|
|||
index 091210a5..5156bb21 100644
|
|||
--- a/daemon/state.c
|
|||
+++ b/daemon/state.c
|
|||
@@ -324,11 +324,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; |
|||
|
|||
@@ -387,7 +388,7 @@ static void do_readmap_mount(struct autofs_point *ap,
|
|||
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; |
|||
@@ -406,14 +407,14 @@ static void do_readmap_mount(struct autofs_point *ap,
|
|||
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) |
|||
@@ -480,9 +481,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); |
@ -0,0 +1,39 @@ |
|||
autofs-5.1.7 - fix double free in parse_mapent() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: |
|||
in parse_mapent(): double_free: Calling "free" frees pointer "newopt" |
|||
which has already been freed. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 2 -- |
|||
2 files changed, 1 insertion(+), 2 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index ff3d88eb..81461978 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -62,6 +62,7 @@
|
|||
- fix dead code in mnts_add_mount(). |
|||
- fix arg not used in error print. |
|||
- fix missing lock release in mount_subtree(). |
|||
+- fix double free in parse_mapent().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 5d15f892..03a63290 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
|
|||
estr = strerror_r(errno, buf, MAX_ERR_BUF); |
|||
error(logopt, MODPREFIX |
|||
"concat_options: %s", estr); |
|||
- if (newopt)
|
|||
- free(newopt);
|
|||
free(myoptions); |
|||
return 0; |
|||
} |
@ -0,0 +1,37 @@ |
|||
autofs-5.1.7 - fix double unlock in parse_mount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it |
|||
is unlocked. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 1 - |
|||
2 files changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2e3b9fd7..224f58d6 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -54,6 +54,7 @@
|
|||
- remove redundant if check. |
|||
- fix possible memory leak in master_parse(). |
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
+- fix double unlock in parse_mount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index a81d4028..05f53fc2 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1526,7 +1526,6 @@ dont_expand:
|
|||
if (!loc) { |
|||
free(options); |
|||
free(pmapent); |
|||
- cache_unlock(mc);
|
|||
warn(ap->logopt, MODPREFIX "out of memory"); |
|||
return 1; |
|||
} |
@ -0,0 +1,38 @@ |
|||
autofs-5.1.7 - fix flags check in umount_multi() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: operator_confusion: "ap->flags | 1" is always 1/true |
|||
regardless of the values of its operand. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/automount.c | 2 +- |
|||
2 files changed, 2 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 9e385ba9..7add6c55 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -56,6 +56,7 @@
|
|||
- fix possible memory leak in mnts_add_amdmount(). |
|||
- fix double unlock in parse_mount(). |
|||
- add length check in umount_subtree_mounts(). |
|||
+- fix flags check in umount_multi().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/automount.c b/daemon/automount.c
|
|||
index 70506d83..23235a7d 100644
|
|||
--- a/daemon/automount.c
|
|||
+++ b/daemon/automount.c
|
|||
@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
|||
/* Check if the autofs mount has browse mode enabled. |
|||
* If so re-create the directory entry. |
|||
*/ |
|||
- if (ap->flags | MOUNT_FLAG_GHOST) {
|
|||
+ if (ap->flags & MOUNT_FLAG_GHOST) {
|
|||
int ret; |
|||
|
|||
/* If the browse directory create fails log an |
@ -0,0 +1,300 @@ |
|||
autofs-5.1.7 - fix hosts map offset order |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Map entry offset paths need 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 used to mount the offset during parsing |
|||
since the path length of exports can vary 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 | 69 ++++++++++++++++++++++++++++++++++++++---------- |
|||
6 files changed, 123 insertions(+), 17 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 81b6ce6a..9e341e06 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -74,6 +74,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.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index d279744d..947ed16d 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/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" |
|||
|
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index 5a7a0b89..ddb7e4c5 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/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 autofs_point *ap, const char *name, unsig
|
|||
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); |
|||
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
|
|||
index 080f19d9..debf2df0 100644
|
|||
--- a/include/rpc_subs.h
|
|||
+++ b/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 { |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 6b24a6c2..5a4602e3 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/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(struct tree_node *root, void *ptr)
|
|||
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 *root)
|
|||
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_head *mnts)
|
|||
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); |
|||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
|||
index 24edf00c..26c224f6 100644
|
|||
--- a/modules/lookup_hosts.c
|
|||
+++ b/modules/lookup_hosts.c
|
|||
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|||
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_point *ap, const char *host)
|
|||
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_point *ap, const char *host)
|
|||
} |
|||
*mapent = 0; |
|||
|
|||
- pos = 0;
|
|||
- this = exp;
|
|||
- if (this) {
|
|||
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
|
|||
- this->dir, host, this->dir);
|
|||
- pos += len;
|
|||
- this = this->next;
|
|||
- }
|
|||
+ wi.mapent = mapent;
|
|||
+ wi.host = host;
|
|||
+ wi.pos = 0;
|
|||
|
|||
- while (this) {
|
|||
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
|
|||
- this->dir, host, this->dir);
|
|||
- pos += len;
|
|||
- this = this->next;
|
|||
+ if (!tree) {
|
|||
+ free(mapent);
|
|||
+ mapent = NULL;
|
|||
+ } else {
|
|||
+ tree_traverse_inorder(tree, tree_host_work, &wi);
|
|||
+ tree_free(tree);
|
|||
} |
|||
rpc_exports_free(exp); |
|||
|
@ -0,0 +1,60 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 51e7767e..698cc27a 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -69,6 +69,7 @@
|
|||
- fix amd section mounts map reload. |
|||
- fix dandling symlink creation if nis support is not available. |
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
+- fix lookup_prune_one_cache() refactoring change.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 3e9722e4..0b281f83 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
if (!key || strchr(key, '*')) { |
|||
if (key) |
|||
free(key); |
|||
+ me = cache_enumerate(mc, me);
|
|||
continue; |
|||
} |
|||
|
|||
@@ -1386,6 +1387,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
if (!path) { |
|||
warn(ap->logopt, "can't malloc storage for path"); |
|||
free(key); |
|||
+ me = cache_enumerate(mc, me);
|
|||
continue; |
|||
} |
|||
|
|||
@@ -1413,9 +1415,10 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
} |
|||
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) |
@ -0,0 +1,36 @@ |
|||
autofs-5.1.7 - fix missing lock release in mount_subtree() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Covarity: missing_unlock: Returning without unlocking "mc->rwlock". |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
modules/parse_sun.c | 1 + |
|||
2 files changed, 2 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 1d56c96f..ff3d88eb 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -61,6 +61,7 @@
|
|||
- remove redundant assignment in master_add_amd_mount_section_mounts(). |
|||
- fix dead code in mnts_add_mount(). |
|||
- fix arg not used in error print. |
|||
+- fix missing lock release in mount_subtree().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 05f53fc2..5d15f892 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key); |
|||
if (!len) { |
|||
warn(ap->logopt, "path loo long"); |
|||
+ cache_unlock(mc);
|
|||
return 1; |
|||
} |
|||
key[len] = '/'; |
@ -0,0 +1,60 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index f5f0da76..ecffa933 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -77,6 +77,7 @@
|
|||
- fix hosts map offset order. |
|||
- fix direct mount deadlock. |
|||
- add missing description of null map option. |
|||
+- fix nonstrict offset mount fail handling.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index 5a4602e3..4c866885 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1616,7 +1616,7 @@ static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work
|
|||
{ |
|||
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); |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 12844a30..cdf515c6 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1181,7 +1181,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
|||
* 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); |
@ -0,0 +1,207 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 94eb6a2c..7b360f52 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -71,6 +71,7 @@
|
|||
- dont use AUTOFS_DEV_IOCTL_CLOSEMOUNT. |
|||
- fix lookup_prune_one_cache() refactoring change. |
|||
- fix amd hosts mount expire. |
|||
+- fix offset entries order.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/automount.h b/include/automount.h
|
|||
index 51a0bf0e..d279744d 100644
|
|||
--- a/include/automount.h
|
|||
+++ b/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; |
|||
diff --git a/lib/cache.c b/lib/cache.c
|
|||
index ef761739..66dda5d9 100644
|
|||
--- a/lib/cache.c
|
|||
+++ b/lib/cache.c
|
|||
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
|
|||
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; |
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index 03a63290..b206a326 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -789,14 +789,15 @@ static int check_is_multi(const char *mapent)
|
|||
|
|||
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); |
|||
@@ -862,8 +863,29 @@ update_offset_entry(struct autofs_point *ap,
|
|||
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) { |
|||
@@ -1209,6 +1231,25 @@ static char *do_expandsunent(const char *src, const char *key,
|
|||
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] ... |
|||
@@ -1228,7 +1269,8 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
|||
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; |
|||
@@ -1444,9 +1486,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); |
|||
@@ -1461,9 +1501,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); |
|||
@@ -1474,15 +1512,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); |
|||
@@ -1499,6 +1535,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); |
@ -0,0 +1,38 @@ |
|||
autofs-5.1.7 - fix possible memory leak in master_parse() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)" |
|||
leaks the storage that "path" points to. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master_parse.y | 2 ++ |
|||
2 files changed, 3 insertions(+) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 2186cbe3..b797f6dc 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -52,6 +52,7 @@
|
|||
- remove unused variable from get_exports(). |
|||
- add missing free in handle_mounts(). |
|||
- remove redundant if check. |
|||
+- fix possible memory leak in master_parse().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
|
|||
index 08e44b57..7480c36a 100644
|
|||
--- a/daemon/master_parse.y
|
|||
+++ b/daemon/master_parse.y
|
|||
@@ -155,6 +155,8 @@ file: {
|
|||
line: |
|||
| PATH mapspec |
|||
{ |
|||
+ if (path)
|
|||
+ free(path);
|
|||
path = master_strdup($1); |
|||
if (!path) { |
|||
local_free_vars(); |
@ -0,0 +1,58 @@ |
|||
autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks |
|||
the storage it points to. |
|||
|
|||
Same applies to the other duped fields destined for the mnt_list struct. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
lib/mounts.c | 20 ++++++++++---------- |
|||
2 files changed, 11 insertions(+), 10 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index b797f6dc..2e3b9fd7 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -53,6 +53,7 @@
|
|||
- add missing free in handle_mounts(). |
|||
- remove redundant if check. |
|||
- fix possible memory leak in master_parse(). |
|||
+- fix possible memory leak in mnts_add_amdmount().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index c8a7bf00..ef69cec1 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en
|
|||
|
|||
mnts_hash_mutex_lock(); |
|||
this = mnts_get_mount(entry->path); |
|||
- if (this) {
|
|||
- this->ext_mp = ext_mp;
|
|||
- this->amd_pref = pref;
|
|||
- this->amd_type = type;
|
|||
- this->amd_opts = opts;
|
|||
- this->amd_cache_opts = entry->cache_opts;
|
|||
- this->flags |= MNTS_AMD_MOUNT;
|
|||
- if (list_empty(&this->amdmount))
|
|||
- list_add_tail(&this->amdmount, &ap->amdmounts);
|
|||
- }
|
|||
+ if (!this)
|
|||
+ goto fail;
|
|||
+ this->ext_mp = ext_mp;
|
|||
+ this->amd_pref = pref;
|
|||
+ this->amd_type = type;
|
|||
+ this->amd_opts = opts;
|
|||
+ this->amd_cache_opts = entry->cache_opts;
|
|||
+ this->flags |= MNTS_AMD_MOUNT;
|
|||
+ if (list_empty(&this->amdmount))
|
|||
+ list_add_tail(&this->amdmount, &ap->amdmounts);
|
|||
mnts_hash_mutex_unlock(); |
|||
|
|||
return this; |
@ -0,0 +1,75 @@ |
|||
autofs-5.1.7 - refactor lookup_prune_one_cache() a bit |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: use: Using an unreliable value of "me" inside the second locked |
|||
section. |
|||
|
|||
Change lookup_prune_one_cache() a little, move the location the next |
|||
key is set (before releasing the lock) and add a comment explaining |
|||
why we don't care about the side effects of the read lock release/ |
|||
write lock aquire/write lock release/read lock reaquire. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/lookup.c | 20 +++++++++++++++++++- |
|||
2 files changed, 20 insertions(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 81461978..b79aebc8 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -63,6 +63,7 @@
|
|||
- fix arg not used in error print. |
|||
- fix missing lock release in mount_subtree(). |
|||
- fix double free in parse_mapent(). |
|||
+- refactor lookup_prune_one_cache() a bit.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|||
index 32dbc24d..3e9722e4 100644
|
|||
--- a/daemon/lookup.c
|
|||
+++ b/daemon/lookup.c
|
|||
@@ -1375,7 +1375,6 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
} |
|||
|
|||
key = strdup(me->key); |
|||
- me = cache_enumerate(mc, me);
|
|||
/* Don't consider any entries with a wildcard */ |
|||
if (!key || strchr(key, '*')) { |
|||
if (key) |
|||
@@ -1422,6 +1421,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
if (valid) |
|||
cache_unlock(valid->mc); |
|||
|
|||
+ me = cache_enumerate(mc, me);
|
|||
if (me) |
|||
next_key = strdup(me->key); |
|||
|
|||
@@ -1456,6 +1456,24 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
|||
next: |
|||
cache_readlock(mc); |
|||
if (next_key) { |
|||
+ /* The lock release and reaquire above can mean
|
|||
+ * a number of things could happen.
|
|||
+ *
|
|||
+ * First, mapents could be added between the
|
|||
+ * current mapent and the mapent of next_key.
|
|||
+ * Don't care about that because there's no
|
|||
+ * need to prune newly added entries.
|
|||
+ *
|
|||
+ * Second, the next mapent data could have
|
|||
+ * changed. Don't care about that either since
|
|||
+ * we are looking to prune stale map entries
|
|||
+ * and don't care when they become stale.
|
|||
+ *
|
|||
+ * Finally, the mapent of next_key could have
|
|||
+ * gone away. Again don't care about this either,
|
|||
+ * the loop will exit prematurely so just wait
|
|||
+ * until the next prune and try again.
|
|||
+ */
|
|||
me = cache_lookup_distinct(mc, next_key); |
|||
free(next_key); |
|||
} |
@ -0,0 +1,40 @@ |
|||
autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts() |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: missing_lock: Accessing "entry->current" without holding lock |
|||
"master_mapent.current_mutex". |
|||
|
|||
This is initialization not clearing current source. But the field has |
|||
already been initialized in the master_new_mapent() call. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/master.c | 1 - |
|||
2 files changed, 1 insertion(+), 1 deletion(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index c7bc0c39..f95b1aa6 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -58,6 +58,7 @@
|
|||
- add length check in umount_subtree_mounts(). |
|||
- fix flags check in umount_multi(). |
|||
- dont try umount after stat() ENOENT fail. |
|||
+- remove redundant assignment in master_add_amd_mount_section_mounts().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/master.c b/daemon/master.c
|
|||
index 30d7cf98..84743f80 100644
|
|||
--- a/daemon/master.c
|
|||
+++ b/daemon/master.c
|
|||
@@ -996,7 +996,6 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag
|
|||
source->master_line = 0; |
|||
|
|||
entry->age = age; |
|||
- entry->current = NULL;
|
|||
|
|||
master_add_mapent(master, entry); |
|||
next: |
@ -0,0 +1,40 @@ |
|||
autofs-5.1.7 - remove redundant if check |
|||
|
|||
From: Ian Kent <raven@themaw.net> |
|||
|
|||
Coverity: identical code in if condition branches. |
|||
|
|||
Signed-off-by: Ian Kent <raven@themaw.net> |
|||
---
|
|||
CHANGELOG | 1 + |
|||
daemon/direct.c | 5 +---- |
|||
2 files changed, 2 insertions(+), 4 deletions(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 62a918a9..2186cbe3 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -51,6 +51,7 @@
|
|||
- remove mounts_mutex. |
|||
- remove unused variable from get_exports(). |
|||
- add missing free in handle_mounts(). |
|||
+- remove redundant if check.
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/daemon/direct.c b/daemon/direct.c
|
|||
index 3f4f5704..a33f9f91 100644
|
|||
--- a/daemon/direct.c
|
|||
+++ b/daemon/direct.c
|
|||
@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
|||
|
|||
ops->timeout(ap->logopt, ioctlfd, timeout); |
|||
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino); |
|||
- if (ap->logopt & LOGOPT_DEBUG)
|
|||
- notify_mount_result(ap, me->key, timeout, str_offset);
|
|||
- else
|
|||
- notify_mount_result(ap, me->key, timeout, str_offset);
|
|||
+ notify_mount_result(ap, me->key, timeout, str_offset);
|
|||
ops->close(ap->logopt, ioctlfd); |
|||
|
|||
debug(ap->logopt, "mounted trigger %s", me->key); |
@ -0,0 +1,119 @@ |
|||
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(-) |
|||
|
|||
diff --git a/CHANGELOG b/CHANGELOG
|
|||
index 7b360f52..5a767360 100644
|
|||
--- a/CHANGELOG
|
|||
+++ b/CHANGELOG
|
|||
@@ -72,6 +72,7 @@
|
|||
- fix lookup_prune_one_cache() refactoring change. |
|||
- fix amd hosts mount expire. |
|||
- fix offset entries order. |
|||
+- use mapent tree root for tree_mapent_add_node().
|
|||
|
|||
25/01/2021 autofs-5.1.7 |
|||
- make bind mounts propagation slave by default. |
|||
diff --git a/include/mounts.h b/include/mounts.h
|
|||
index 1b376b3d..f7768ce5 100644
|
|||
--- a/include/mounts.h
|
|||
+++ b/include/mounts.h
|
|||
@@ -170,7 +170,7 @@ 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_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); |
|||
diff --git a/lib/mounts.c b/lib/mounts.c
|
|||
index c24d1a88..9ec547ea 100644
|
|||
--- a/lib/mounts.c
|
|||
+++ b/lib/mounts.c
|
|||
@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree_node *n)
|
|||
} |
|||
|
|||
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_cache *mc,
|
|||
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)) |
|||
|
|||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
|||
index b206a326..c75bcc8e 100644
|
|||
--- a/modules/parse_sun.c
|
|||
+++ b/modules/parse_sun.c
|
|||
@@ -1536,8 +1536,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); |
|||
} |
Loading…
Reference in new issue