import autofs-5.1.7-24.el9

This commit is contained in:
CentOS Sources 2021-11-03 20:41:29 -04:00 committed by Stepan Oksanichenko
commit 0d112ed46f
84 changed files with 13423 additions and 0 deletions

1
.autofs.metadata Normal file
View File

@ -0,0 +1 @@
086c327711a7f76692c582264c0742842f3570ba SOURCES/autofs-5.1.7-2.tar.gz

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/autofs-5.1.7-2.tar.gz

View File

@ -0,0 +1,48 @@
autofs-5.1.7 - Fix option for master read wait
From: Goldwyn Rodrigues <rgoldwyn@suse.de>
The master-wait program option expects a value, and if provided
automount crashes with the following trace:
#0 __GI_____strtoul_l_internal (nptr=0x0, endptr=0x7fffffffe120, base=0, group=<optimized out>,
loc=0x7ffff77a63a0 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
#1 0x0000555555562c52 in getnumopt ()
#2 0x0000555555564ec0 in main ()
This is because the options string is not correct and does not expect
an argument for master-wait (M), which sets optarg to NULL.
Fixes: e68f07f ("autofs-5.1.2 - add master read wait option")
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
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 fe49740e..0b577909 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
- dont use realloc in host exports list processing.
- use sprintf() when constructing hosts mapent.
- fix mnts_remove_amdmount() uses wrong list.
+- Fix option for master read wait.
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 e476f6b2..7fa92877 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -2274,7 +2274,7 @@ int main(int argc, char *argv[])
time_t timeout;
time_t age = monotonic_time(NULL);
struct rlimit rlim;
- const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM";
+ const char *options = "+hp:t:vmdD:SfVrO:l:n:CFUM:";
static const struct option long_options[] = {
{"help", 0, 0, 'h'},
{"pid-file", 1, 0, 'p'},

View File

@ -0,0 +1,136 @@
autofs-5.1.7 - add a len field to struct autofs_point
From: Ian Kent <raven@themaw.net>
Add a path length field to struct autofs_point since the path length
is needed at various times avoiding additional strlen() calls.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/lookup.c | 2 +-
daemon/master.c | 1 +
include/automount.h | 1 +
lib/mounts.c | 6 +++---
modules/parse_amd.c | 4 ++--
modules/parse_sun.c | 4 ++--
7 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 60924b3f..0dae6761 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@
- rename tree implementation functions.
- add some multi-mount macros.
- remove unused functions cache_dump_multi() and cache_dump_cache().
+- add a len field to struct autofs_point.
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 8c9a82b5..5116b927 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
return NSS_STATUS_UNKNOWN;
}
- m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2);
+ m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2);
if (!m_key) {
error(ap->logopt,
"failed to allocate storage for search key");
diff --git a/daemon/master.c b/daemon/master.c
index da527a61..022fb9dd 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -86,6 +86,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
free(ap);
return 0;
}
+ ap->len = strlen(ap->path);
ap->pref = NULL;
ap->entry = entry;
diff --git a/include/automount.h b/include/automount.h
index e917515b..34485859 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -548,6 +548,7 @@ struct kernel_mod_version {
struct autofs_point {
pthread_t thid;
char *path; /* Mount point name */
+ size_t len; /* Length of mount point name */
mode_t mode; /* Mount point mode */
char *pref; /* amd prefix */
int pipefd; /* File descriptor for pipe */
diff --git a/lib/mounts.c b/lib/mounts.c
index f6f20fc0..b478ecb4 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1158,7 +1158,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
if (!mp)
goto fail;
} else {
- int len = strlen(ap->path) + strlen(name) + 2;
+ int len = ap->len + strlen(name) + 2;
mp = malloc(len);
if (!mp)
@@ -2495,9 +2495,9 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
dir = strdup(oe->key);
if (ap->flags & MOUNT_FLAG_GHOST)
- split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1;
+ split = ap->len + strlen(MM_ROOT(oe)->key) + 1;
else
- split = strlen(ap->path);
+ split = ap->len;
dir[split] = '\0';
path = &dir[split + 1];
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index d3e8a450..5a9079d6 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -147,7 +147,7 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap,
struct mapent *me;
int len;
- len = strlen(ap->path) + 1 + key_len + 1;
+ len = ap->len + 1 + key_len + 1;
if (len > PATH_MAX) {
error(ap->logopt, MODPREFIX
"error: lookup key is greater than PATH_MAX");
@@ -1319,7 +1319,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name,
char *target;
size_t len;
- len = strlen(ap->path) + strlen(entry->rhost) + 2;
+ len = ap->len + strlen(entry->rhost) + 2;
target = malloc(len);
if (!target) {
warn(ap->logopt, MODPREFIX
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b11c6693..b1f64ca0 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1154,7 +1154,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
mm_root = mm_key;
start = strlen(mm_key);
} else {
- start = strlen(ap->path) + strlen(mm_key) + 1;
+ start = ap->len + strlen(mm_key) + 1;
mm_root = alloca(start + 3);
strcpy(mm_root, ap->path);
strcat(mm_root, "/");
@@ -1477,7 +1477,7 @@ dont_expand:
}
strcpy(m_root, name);
} else {
- m_root_len = strlen(ap->path) + name_len + 1;
+ m_root_len = ap->len + name_len + 1;
m_root = alloca(m_root_len + 1);
if (!m_root) {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);

View File

@ -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;
}

View File

@ -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);

View File

@ -0,0 +1,177 @@
autofs-5.1.7 - add mapent tree implementation
From: Ian Kent <raven@themaw.net>
Add a struct mapent basic tree implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 4 ++++
include/mounts.h | 8 ++++++++
lib/cache.c | 9 ++++++++-
lib/mounts.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 74571570..8841f72f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,7 @@
- remove unused functions cache_dump_multi() and cache_dump_cache().
- add a len field to struct autofs_point.
- make tree implementation data independent.
+- add mapent tree implementation.
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 34485859..ebc2007f 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -166,10 +166,14 @@ struct mapent {
struct mapent_cache *mc;
struct map_source *source;
/* Need to know owner if we're a multi-mount */
+ struct tree_node *mm_root;
+ struct tree_node *mm_parent;
+ struct tree_node node;
struct mapent *multi;
/* Parent nesting point within multi-mount */
struct mapent *parent;
char *key;
+ size_t len;
char *mapent;
struct stack *stack;
time_t age;
diff --git a/include/mounts.h b/include/mounts.h
index 71d29566..fd7c6183 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -66,6 +66,13 @@ 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 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)
+#define MAPENT_PARENT(p) ((struct tree_node *) ((struct mapent *) p)->mm_parent)
+#define MAPENT_SET_ROOT(p, r) { (((struct mapent *) p)->mm_root = (struct tree_node *) r); }
+#define MAPENT_SET_PARENT(p, n) { (((struct mapent *) p)->mm_parent = (struct tree_node *) n); }
+
typedef struct tree_node *(*tree_new_t) (void *ptr);
typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr);
typedef void (*tree_free_t) (struct tree_node *n);
@@ -161,6 +168,7 @@ unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
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 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);
diff --git a/lib/cache.c b/lib/cache.c
index 629c4d0a..6dfaeff5 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -546,17 +546,21 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
struct mapent *me, *existing = NULL;
char *pkey, *pent;
u_int32_t hashval = hash(key, mc->size);
+ size_t len;
me = (struct mapent *) malloc(sizeof(struct mapent));
if (!me)
return CHE_FAIL;
- pkey = malloc(strlen(key) + 1);
+ len = strlen(key);
+
+ pkey = malloc(len + 1);
if (!pkey) {
free(me);
return CHE_FAIL;
}
me->key = strcpy(pkey, key);
+ me->len = len;
if (mapent) {
pent = malloc(strlen(mapent) + 1);
@@ -575,6 +579,9 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
me->status = 0;
me->mc = mc;
me->source = ms;
+ me->mm_root = NULL;
+ me->mm_parent = NULL;
+ INIT_TREE_NODE(&me->node);
INIT_LIST_HEAD(&me->ino_index);
INIT_LIST_HEAD(&me->multi_list);
me->multi = NULL;
diff --git a/lib/mounts.c b/lib/mounts.c
index a6d1c5a7..40ebf9cf 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_mapent_new(void *ptr);
+static int tree_mapent_cmp(struct tree_node *n, void *ptr);
+static void tree_mapent_free(struct tree_node *n);
+
+static struct tree_ops mapent_ops = {
+ .new = tree_mapent_new,
+ .cmp = tree_mapent_cmp,
+ .free = tree_mapent_free,
+};
+static struct tree_ops *tree_mapent_ops = &mapent_ops;
+
unsigned int linux_version_code(void)
{
struct utsname my_utsname;
@@ -1431,6 +1442,45 @@ void mnts_put_expire_list(struct list_head *mnts)
mnts_hash_mutex_unlock();
}
+struct tree_node *tree_mapent_root(struct mapent *me)
+{
+ return tree_root(tree_mapent_ops, me);
+}
+
+static struct tree_node *tree_mapent_new(void *ptr)
+{
+ struct tree_node *n = MAPENT_NODE(ptr);
+
+ n->ops = tree_mapent_ops;
+ n->left = NULL;
+ n->right = NULL;
+
+ return n;
+}
+
+static int tree_mapent_cmp(struct tree_node *n, void *ptr)
+{
+ struct mapent *n_me = MAPENT(n);
+ size_t n_me_len = n_me->len;
+ struct mapent *me = ptr;
+ size_t me_len = me->len;
+
+ if (strncmp(me->key, n_me->key, n_me_len) == 0) {
+ if (me_len < n_me_len)
+ return -1;
+ else if (me_len > n_me_len)
+ return 1;
+ }
+ return strcmp(me->key, n_me->key);
+}
+
+static void tree_mapent_free(struct tree_node *n)
+{
+ n->ops = NULL;
+ n->left = NULL;
+ n->right = NULL;
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -75,6 +75,7 @@
- fix hosts map offset order.
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
+- add missing description of null map option.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/man/auto.master.5.in
+++ autofs-5.1.7/man/auto.master.5.in
@@ -265,6 +265,25 @@ accessing /net/myserver will mount expor
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

View File

@ -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);
}

View File

@ -0,0 +1,310 @@
autofs-5.1.7 - add mount and umount offsets functions
From: Ian Kent <raven@themaw.net>
Add tree_mapent_mount_offsets() and tree_mapent_umount_offsets() to
the mapent tree handling implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 2
lib/mounts.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 0bd6f181..892f7581 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -39,6 +39,7 @@
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
- add set_offset_tree_catatonic().
+- add mount and umount offsets functions.
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 5441ee0e..e56f80ba 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -172,6 +172,8 @@ 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_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 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);
diff --git a/lib/mounts.c b/lib/mounts.c
index f075a27e..f7c29475 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1692,6 +1692,266 @@ void tree_mapent_cleanup_offsets(struct mapent *oe)
}
}
+static int tree_mapent_rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
+{
+ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe));
+ char *dir, *path;
+ unsigned int split;
+ int ret;
+
+ if (ap->type == LKP_DIRECT)
+ return rmdir_path(ap, oe->key, mm_root->dev);
+
+ dir = strdup(oe->key);
+
+ if (ap->flags & MOUNT_FLAG_GHOST)
+ split = ap->len + mm_root->len + 1;
+ else
+ split = ap->len;
+
+ dir[split] = '\0';
+ path = &dir[split + 1];
+
+ if (chdir(dir) == -1) {
+ error(ap->logopt, "failed to chdir to %s", dir);
+ free(dir);
+ return -1;
+ }
+
+ ret = rmdir_path(ap, path, ap->dev);
+
+ free(dir);
+
+ if (chdir("/") == -1)
+ error(ap->logopt, "failed to chdir to /");
+
+ return ret;
+}
+
+static int tree_mapent_mount_offset(struct mapent *oe, void *ptr)
+{
+ struct traverse_subtree_context *ctxt = ptr;
+ struct autofs_point *ap = ctxt->ap;
+ int ret;
+
+ debug(ap->logopt, "mount offset %s", oe->key);
+
+ ret = mount_autofs_offset(ap, oe);
+ if (ret < MOUNT_OFFSET_OK) {
+ if (ret != MOUNT_OFFSET_IGNORE) {
+ warn(ap->logopt, "failed to mount offset");
+ return 0;
+ } else {
+ debug(ap->logopt,
+ "ignoring \"nohide\" trigger %s", oe->key);
+ /*
+ * Ok, so we shouldn't modify the mapent but
+ * mount requests are blocked at a point above
+ * this and expire only uses the mapent key or
+ * holds the cache write lock.
+ */
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ }
+
+ return 1;
+}
+
+static int tree_mapent_umount_offset(struct mapent *oe, void *ptr)
+{
+ struct traverse_subtree_context *ctxt = ptr;
+ struct autofs_point *ap = ctxt->ap;
+ int ret = 1;
+
+ /*
+ * Check for and umount subtree offsets resulting from
+ * nonstrict mount fail.
+ */
+ ret = tree_mapent_umount_offsets(oe, ctxt->strict);
+ if (!ret)
+ return 0;
+
+ /*
+ * If an offset that has an active mount has been removed
+ * from the multi-mount we don't want to attempt to trigger
+ * mounts for it. Obviously this is because it has been
+ * removed, but less obvious is the potential strange
+ * behaviour that can result if we do try and mount it
+ * again after it's been expired. For example, if an NFS
+ * file system is no longer exported and is later umounted
+ * it can be mounted again without any error message but
+ * shows as an empty directory. That's going to confuse
+ * people for sure.
+ *
+ * If the mount cannot be umounted (the process is now
+ * using a stale mount) the offset needs to be invalidated
+ * so no further mounts will be attempted but the offset
+ * cache entry must remain so expires can continue to
+ * attempt to umount it. If the mount can be umounted and
+ * the offset is removed, at least for NFS we will get
+ * ESTALE errors when attempting list the directory.
+ */
+ if (oe->ioctlfd != -1 ||
+ is_mounted(oe->key, MNTS_REAL)) {
+ if (umount_ent(ap, oe->key) &&
+ is_mounted(oe->key, MNTS_REAL)) {
+ debug(ap->logopt,
+ "offset %s has active mount, invalidate",
+ oe->key);
+ /*
+ * Ok, so we shouldn't modify the mapent but
+ * mount requests are blocked at a point above
+ * this and expire only uses the mapent key or
+ * holds the cache write lock.
+ */
+ if (oe->mapent) {
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ return 0;
+ }
+ }
+
+ /* Don't bother if there's noting to umount. */
+ if (!is_mounted(oe->key, MNTS_AUTOFS))
+ goto done;
+
+ debug(ap->logopt, "umount offset %s", oe->key);
+
+ if (umount_autofs_offset(ap, oe)) {
+ warn(ap->logopt, "failed to umount offset");
+ ret = 0;
+ } else {
+ struct stat st;
+ int ret;
+
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+ goto done;
+
+ /*
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
+ */
+ ret = tree_mapent_rmdir_path_offset(ap, oe);
+ if (ret == -1 && !stat(oe->key, &st)) {
+ ret = tree_mapent_mount_offset(oe, ctxt);
+ /* But we did origianlly create this */
+ oe->flags |= MOUNT_FLAG_DIR_CREATED;
+ }
+ }
+done:
+ return ret;
+}
+
+static int tree_mapent_mount_offsets_work(struct tree_node *n, void *ptr)
+{
+ struct traverse_subtree_context *ctxt = ptr;
+ struct mapent *oe = MAPENT(n);
+ struct mapent *mm_root = MAPENT(MAPENT_ROOT(oe));
+ struct autofs_point *ap = ctxt->ap;
+ int ret;
+
+ if (!oe->mapent)
+ return 1;
+
+ /* Stale offset, no longer present in the mapent */
+ if (oe->age != mm_root->age) {
+ /* Best effort */
+ tree_mapent_umount_offset(oe, ctxt);
+ return 1;
+ }
+
+ ret = tree_mapent_mount_offset(oe, ctxt);
+
+ /*
+ * If re-constructing a multi-mount it's necessary to walk
+ * into nested mounts, unlike the usual "mount only what's
+ * needed as you go" behavior.
+ */
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
+ if (oe->ioctlfd != -1 ||
+ is_mounted(oe->key, MNTS_REAL))
+ /* Best effort */
+ tree_mapent_mount_offsets(oe, !ctxt->strict);
+ }
+
+ return ret;
+}
+
+int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict)
+{
+ struct tree_node *base = MAPENT_NODE(oe);
+ struct traverse_subtree_context ctxt = {
+ .ap = oe->mc->ap,
+ .base = base,
+ .strict = !nonstrict,
+ };
+
+ return tree_mapent_traverse_subtree(base,
+ tree_mapent_mount_offsets_work, &ctxt);
+}
+
+static int tree_mapent_umount_offsets_work(struct tree_node *n, void *ptr)
+{
+ struct mapent *oe = MAPENT(n);
+
+ return tree_mapent_umount_offset(oe, ptr);
+}
+
+int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
+{
+ 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,
+ };
+ int ret;
+
+ ret = tree_mapent_traverse_subtree(base,
+ tree_mapent_umount_offsets_work, &ctxt);
+ if (ret && tree_mapent_is_root(oe)) {
+ char mp[PATH_MAX + 1];
+
+ /*
+ * The map entry cache stores mapent keys. For indirect
+ * mount maps they are single direcory components so when
+ * one of these keys is the root of a multi-mount the mount
+ * path must be constructed.
+ */
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) {
+ error(ap->logopt, "mount path is too long");
+ return 0;
+ }
+
+ /*
+ * Special case.
+ * If we can't umount the root container then we can't
+ * delete the offsets from the cache and we need to put
+ * the offset triggers back.
+ */
+ if (is_mounted(mp, MNTS_REAL)) {
+ info(ap->logopt, "unmounting dir = %s", mp);
+ if (umount_ent(ap, mp) &&
+ is_mounted(mp, MNTS_REAL)) {
+ if (!tree_mapent_mount_offsets(oe, 1))
+ warn(ap->logopt,
+ "failed to remount offset triggers");
+ return 0;
+ }
+ }
+
+ /* check for mounted mount entry and remove it if found */
+ mnts_remove_mount(mp, MNTS_MOUNTED);
+
+ }
+
+ return ret;
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names

View File

@ -0,0 +1,50 @@
autofs-5.1.7 - add set_offset_tree_catatonic()
From: Ian Kent <raven@themaw.net>
Add tree mapent support function set_offset_tree_catatonic().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 89d4cfa0..0bd6f181 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -38,6 +38,7 @@
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
- add tree_mapent_cleanup_offsets().
+- add set_offset_tree_catatonic().
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 ba573b9a..f075a27e 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2578,6 +2578,21 @@ static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int i
return 0;
}
+static int set_offset_tree_catatonic_work(struct tree_node *n, void *ptr)
+{
+ struct mapent *me = MAPENT(n);
+ struct autofs_point *ap = me->mc->ap;
+
+ set_mount_catatonic(ap, me, me->ioctlfd);
+
+ return 1;
+}
+
+static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me)
+{
+ tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL);
+}
+
static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
{
if (!list_empty(&me->multi_list)) {

View File

@ -0,0 +1,552 @@
autofs-5.1.7 - add some multi-mount macros
From: Ian Kent <raven@themaw.net>
Add convienience macros IS_MM() to check is a mapent is part of a
multi-mount, IS_MM_ROOT() to check if a mapent is the root of a
multi-mount tree and MM_ROOT() to return the multi-mount root mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 14 +++++++-------
daemon/direct.c | 6 +++---
daemon/lookup.c | 10 +++++-----
include/automount.h | 5 +++++
lib/cache.c | 30 +++++++++++++++---------------
lib/mounts.c | 14 +++++++-------
modules/lookup_file.c | 4 ++--
modules/lookup_hosts.c | 4 ++--
modules/lookup_ldap.c | 4 ++--
modules/lookup_nisplus.c | 4 ++--
modules/lookup_program.c | 4 ++--
modules/lookup_sss.c | 4 ++--
modules/lookup_yp.c | 4 ++--
modules/parse_sun.c | 12 ++++++------
15 files changed, 63 insertions(+), 57 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1bf20699..3ba748d7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,7 @@
- rename path to m_offset in update_offset_entry().
- don't pass root to do_mount_autofs_offset().
- rename tree implementation functions.
+- add some multi-mount macros.
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 62530b6b..f4608fc9 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -545,27 +545,27 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
if (me) {
mc = me->mc;
- is_mm_root = (me->multi == me);
+ is_mm_root = IS_MM_ROOT(me);
}
left = 0;
- if (me && me->multi) {
+ if (me && IS_MM(me)) {
char root[PATH_MAX + 1];
char key[PATH_MAX + 1];
struct mapent *tmp;
int status;
char *base;
- if (!strchr(me->multi->key, '/'))
+ if (!strchr(MM_ROOT(me)->key, '/'))
/* Indirect multi-mount root */
/* sprintf okay - if it's mounted, it's
* PATH_MAX or less bytes */
- sprintf(root, "%s/%s", ap->path, me->multi->key);
+ sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key);
else
- strcpy(root, me->multi->key);
+ strcpy(root, MM_ROOT(me)->key);
- if (is_mm_root)
+ if (IS_MM_ROOT(me))
base = NULL;
else
base = me->key + strlen(root);
@@ -588,7 +588,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
return 0;
}
- if (!left && is_mm_root) {
+ if (!left && IS_MM_ROOT(me)) {
status = cache_delete_offset_list(mc, me->key);
if (status != CHE_OK) {
warn(ap->logopt, "couldn't delete offset list");
diff --git a/daemon/direct.c b/daemon/direct.c
index 5c1146a7..3f4f5704 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -686,7 +686,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
* a mount that has been automatically mounted by
* the kernel NFS client.
*/
- if (me->multi != me &&
+ if (!IS_MM_ROOT(me) &&
is_mounted(me->key, MNTS_REAL))
return MOUNT_OFFSET_IGNORE;
@@ -1220,11 +1220,11 @@ static void *do_mount_direct(void *arg)
* for direct mount multi-mounts with no real mount at
* their base so they will be expired.
*/
- if (close_fd && me == me->multi)
+ if (close_fd && IS_MM_ROOT(me))
close_fd = 0;
if (!close_fd)
me->ioctlfd = mt.ioctlfd;
- if (me->multi && me->multi != me)
+ if (IS_MM(me) && !IS_MM_ROOT(me))
flags |= MNTS_OFFSET;
}
ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 2fea0c0b..8c9a82b5 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -748,7 +748,7 @@ int lookup_ghost(struct autofs_point *ap, const char *root)
goto next;
/* It's a busy multi-mount - leave till next time */
- if (list_empty(&me->multi_list))
+ if (IS_MM(me))
error(ap->logopt,
"invalid key %s", me->key);
goto next;
@@ -838,12 +838,12 @@ static int lookup_amd_instance(struct autofs_point *ap,
char *m_key;
me = cache_lookup_distinct(map->mc, name);
- if (!me || !me->multi) {
+ if (!me || !IS_MM(me)) {
error(ap->logopt, "expected multi mount entry not found");
return NSS_STATUS_UNKNOWN;
}
- m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 2);
+ m_key = malloc(strlen(ap->path) + strlen(MM_ROOT(me)->key) + 2);
if (!m_key) {
error(ap->logopt,
"failed to allocate storage for search key");
@@ -852,7 +852,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
strcpy(m_key, ap->path);
strcat(m_key, "/");
- strcat(m_key, me->multi->key);
+ strcat(m_key, MM_ROOT(me)->key);
mnt = mnts_find_amdmount(m_key);
free(m_key);
@@ -1355,7 +1355,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
* created on demand and managed by expire and don't
* prune the multi-map owner map entry.
*/
- if (*me->key == '/' || me->multi == me) {
+ if (*me->key == '/' || IS_MM_ROOT(me)) {
me = cache_enumerate(mc, me);
continue;
}
diff --git a/include/automount.h b/include/automount.h
index fa6f5d63..e917515b 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -183,6 +183,11 @@ struct mapent {
ino_t ino;
};
+#define IS_MM(me) (me->multi)
+#define IS_MM_ROOT(me) (me->multi == me)
+#define MM_ROOT(me) (me->multi)
+#define MM_PARENT(me) (me->parent)
+
void cache_lock_cleanup(void *arg);
void cache_readlock(struct mapent_cache *mc);
void cache_writelock(struct mapent_cache *mc);
diff --git a/lib/cache.c b/lib/cache.c
index a90bbb1d..1d9f5cc7 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -374,7 +374,7 @@ struct mapent *cache_lookup_first(struct mapent_cache *mc)
while (me) {
/* Multi mount entries are not primary */
- if (me->multi && me->multi != me) {
+ if (IS_MM(me) && !IS_MM_ROOT(me)) {
me = me->next;
continue;
}
@@ -397,7 +397,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
this = me->next;
while (this) {
/* Multi mount entries are not primary */
- if (this->multi && this->multi != this) {
+ if (IS_MM(this) && !IS_MM_ROOT(this)) {
this = this->next;
continue;
}
@@ -413,7 +413,7 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me)
while (this) {
/* Multi mount entries are not primary */
- if (this->multi && this->multi != this) {
+ if (IS_MM(this) && !IS_MM_ROOT(this)) {
this = this->next;
continue;
}
@@ -435,7 +435,7 @@ struct mapent *cache_lookup_key_next(struct mapent *me)
next = me->next;
while (next) {
/* Multi mount entries are not primary */
- if (me->multi && me->multi != me)
+ if (IS_MM(me) && !IS_MM_ROOT(me))
continue;
if (!strcmp(me->key, next->key))
return next;
@@ -706,7 +706,7 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k
me = cache_lookup_distinct(mc, key);
if (me) {
cache_add_ordered_offset(me, &owner->multi_list);
- me->multi = owner;
+ MM_ROOT(me) = owner;
goto done;
}
ret = CHE_FAIL;
@@ -814,14 +814,14 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
this = cache_lookup_distinct(mc, offset);
if (!this)
return 0;
- if (!this->multi)
+ if (!IS_MM(this))
return 0;
parent = get_offset_parent(mc, offset);
if (parent)
this->parent = parent;
else
- this->parent = this->multi;
+ this->parent = MM_ROOT(this);
return 1;
}
@@ -879,7 +879,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
return CHE_FAIL;
if (strcmp(key, me->key) == 0) {
- if (me->multi && me->multi == me)
+ if (IS_MM(me) && IS_MM_ROOT(me))
return CHE_FAIL;
mc->hash[hashval] = me->next;
goto delete;
@@ -889,7 +889,7 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
pred = me;
me = me->next;
if (strcmp(key, me->key) == 0) {
- if (me->multi && me->multi == me)
+ if (IS_MM(me) && IS_MM_ROOT(me))
return CHE_FAIL;
pred->next = me->next;
goto delete;
@@ -927,7 +927,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
me = me->next;
if (strcmp(key, me->key) == 0) {
struct stack *s = me->stack;
- if (me->multi && !list_empty(&me->multi_list)) {
+ if (IS_MM(me)) {
ret = CHE_FAIL;
goto done;
}
@@ -956,7 +956,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
if (strcmp(key, me->key) == 0) {
struct stack *s = me->stack;
- if (me->multi && !list_empty(&me->multi_list)) {
+ if (IS_MM(me)) {
ret = CHE_FAIL;
goto done;
}
@@ -995,7 +995,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
return CHE_FAIL;
/* Not offset list owner */
- if (me->multi != me)
+ if (!IS_MM_ROOT(me))
return CHE_FAIL;
head = &me->multi_list;
@@ -1016,13 +1016,13 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
this = list_entry(next, struct mapent, multi_list);
next = next->next;
list_del_init(&this->multi_list);
- this->multi = NULL;
+ MM_ROOT(this) = NULL;
debug(logopt, "deleting offset key %s", this->key);
status = cache_delete(mc, this->key);
if (status == CHE_FAIL) {
warn(logopt,
"failed to delete offset %s", this->key);
- this->multi = me;
+ MM_ROOT(this) = me;
/* TODO: add list back in */
remain++;
}
@@ -1030,7 +1030,7 @@ int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
if (!remain) {
list_del_init(&me->multi_list);
- me->multi = NULL;
+ MM_ROOT(me) = NULL;
}
if (remain)
diff --git a/lib/mounts.c b/lib/mounts.c
index f5b905a6..f6f20fc0 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2163,7 +2163,7 @@ int try_remount(struct autofs_point *ap, struct mapent *me, unsigned int type)
} else {
me->flags &= ~MOUNT_FLAG_DIR_CREATED;
if (type == t_offset) {
- if (!is_mounted(me->parent->key, MNTS_REAL))
+ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
me->flags |= MOUNT_FLAG_DIR_CREATED;
}
}
@@ -2310,7 +2310,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
goto next;
/* Only need to set offset mounts catatonic */
- if (me->multi && me->multi == me)
+ if (IS_MM(me) && IS_MM_ROOT(me))
set_multi_mount_tree_catatonic(ap, me);
next:
me = cache_enumerate(mc, me);
@@ -2330,7 +2330,7 @@ next:
void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
{
/* Set offset mounts catatonic for this mapent */
- if (me->multi && me->multi == me)
+ if (IS_MM(me) && IS_MM_ROOT(me))
set_multi_mount_tree_catatonic(ap, me);
set_mount_catatonic(ap, me, me->ioctlfd);
}
@@ -2490,12 +2490,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
int ret;
if (ap->type == LKP_DIRECT)
- return rmdir_path(ap, oe->key, oe->multi->dev);
+ return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev);
dir = strdup(oe->key);
if (ap->flags & MOUNT_FLAG_GHOST)
- split = strlen(ap->path) + strlen(oe->multi->key) + 1;
+ split = strlen(ap->path) + strlen(MM_ROOT(oe)->key) + 1;
else
split = strlen(ap->path);
@@ -2690,7 +2690,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
oe = cache_lookup_distinct(me->mc, key);
if (!oe || !oe->mapent)
goto cont;
- if (oe->age != me->multi->age) {
+ if (oe->age != MM_ROOT(me)->age) {
/* Best effort */
do_umount_offset(ap, oe, root, start);
goto cont;
@@ -2724,7 +2724,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
left = do_umount_multi_triggers(ap, me, root, start, base);
- if (!left && me->multi == me) {
+ if (!left && IS_MM_ROOT(me)) {
/*
* Special case.
* If we can't umount the root container then we can't
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index f46a04f0..6afc5587 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1199,8 +1199,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->multi)
- lkp_key = strdup(me->multi->key);
+ if (me && IS_MM(me))
+ lkp_key = strdup(MM_ROOT(me)->key);
else if (!ap->pref)
lkp_key = strdup(key);
else {
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index c1ebb7f6..7e101ddb 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -177,7 +177,7 @@ static void update_hosts_mounts(struct autofs_point *ap,
me = cache_lookup_first(mc);
while (me) {
/* Hosts map entry not yet expanded or already expired */
- if (!me->multi)
+ if (!IS_MM(me))
goto next;
debug(ap->logopt, MODPREFIX "get list of exports for %s", me->key);
@@ -200,7 +200,7 @@ next:
* Hosts map entry not yet expanded, already expired
* or not the base of the tree
*/
- if (!me->multi || me->multi != me)
+ if (!IS_MM(me) || !IS_MM_ROOT(me))
goto cont;
debug(ap->logopt, MODPREFIX
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index 3624dd86..3e43fc01 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -3700,8 +3700,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (ap->type == LKP_INDIRECT && *key != '/') {
cache_readlock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->multi)
- lkp_key = strdup(me->multi->key);
+ if (me && IS_MM(me))
+ lkp_key = strdup(MM_ROOT(me)->key);
else if (!ap->pref)
lkp_key = strdup(key);
else {
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index cbd03cdb..6e9a85d1 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -722,8 +722,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (ap->type == LKP_INDIRECT && *key != '/') {
cache_readlock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->multi)
- lkp_key = strdup(me->multi->key);
+ if (me && IS_MM(me))
+ lkp_key = strdup(MM_ROOT(me)->key);
else if (!ap->pref)
lkp_key = strdup(key);
else {
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index ca209488..70f27545 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -646,7 +646,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
name_len, ent, ctxt->parse->context);
goto out_free;
} else {
- if (me->multi && me->multi != me) {
+ if (IS_MM(me) && !IS_MM_ROOT(me)) {
cache_unlock(mc);
warn(ap->logopt, MODPREFIX
"unexpected lookup for active multi-mount"
@@ -657,7 +657,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_writelock(mc);
me = cache_lookup_distinct(mc, name);
if (me) {
- if (me->multi)
+ if (IS_MM(me))
cache_delete_offset_list(mc, name);
cache_delete(mc, name);
}
diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c
index ccd605af..ad834626 100644
--- a/modules/lookup_sss.c
+++ b/modules/lookup_sss.c
@@ -1055,8 +1055,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
cache_readlock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->multi)
- lkp_key = strdup(me->multi->key);
+ if (me && IS_MM(me))
+ lkp_key = strdup(MM_ROOT(me)->key);
else
lkp_key = strdup(key);
cache_unlock(mc);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 38f75497..8bccb72f 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -826,8 +826,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
if (ap->type == LKP_INDIRECT && *key != '/') {
cache_readlock(mc);
me = cache_lookup_distinct(mc, key);
- if (me && me->multi)
- lkp_key = strdup(me->multi->key);
+ if (me && IS_MM(me))
+ lkp_key = strdup(MM_ROOT(me)->key);
else if (!ap->pref)
lkp_key = strdup(key);
else {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 34d4441e..b11c6693 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1148,7 +1148,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
rv = 0;
- mm_key = me->multi->key;
+ mm_key = MM_ROOT(me)->key;
if (*mm_key == '/') {
mm_root = mm_key;
@@ -1162,7 +1162,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
}
mm_root_len = strlen(mm_root);
- if (me == me->multi) {
+ if (IS_MM_ROOT(me)) {
char key[PATH_MAX + 1];
if (mm_root_len + 1 > PATH_MAX) {
@@ -1179,7 +1179,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
/* Mount root offset if it exists */
ro = cache_lookup_distinct(me->mc, key);
- if (ro && ro->age == me->multi->age) {
+ if (ro && ro->age == MM_ROOT(me)->age) {
char *myoptions, *ro_loc;
int namelen = name ? strlen(name) : 0;
int ro_len;
@@ -1350,7 +1350,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
if (*name == '/') {
cache_readlock(mc);
me = cache_lookup_distinct(mc, name);
- if (me && me->multi && me->multi != me) {
+ if (me && IS_MM(me) && !IS_MM_ROOT(me)) {
cache_unlock(mc);
mapent_len = strlen(mapent) + 1;
pmapent = malloc(mapent_len + 1);
@@ -1505,7 +1505,7 @@ dont_expand:
}
/* So we know we're the multi-mount root */
- if (!me->multi)
+ if (!IS_MM(me))
me->multi = me;
else {
/*
@@ -1630,7 +1630,7 @@ dont_expand:
*/
cache_readlock(mc);
if (*name == '/' &&
- (me = cache_lookup_distinct(mc, name)) && me->multi) {
+ (me = cache_lookup_distinct(mc, name)) && IS_MM(me)) {
cache_unlock(mc);
loc = strdup(p);
if (!loc) {

View File

@ -0,0 +1,133 @@
autofs-5.1.7 - add tree_mapent_add_node()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_add_node() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 1 +
include/mounts.h | 1 +
lib/cache.c | 5 ++---
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8841f72f..85730eda 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -33,6 +33,7 @@
- add a len field to struct autofs_point.
- make tree implementation data independent.
- add mapent tree implementation.
+- add tree_mapent_add_node().
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 ebc2007f..f6023e27 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -216,6 +216,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
int cache_lookup_negative(struct mapent *me, const char *key);
void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout);
+struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key);
int cache_set_offset_parent(struct mapent_cache *mc, const char *offset);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
diff --git a/include/mounts.h b/include/mounts.h
index fd7c6183..a0e60e24 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -169,6 +169,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 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);
diff --git a/lib/cache.c b/lib/cache.c
index 6dfaeff5..7c409a56 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -749,8 +749,7 @@ void cache_update_negative(struct mapent_cache *mc,
}
-static struct mapent *get_offset_parent(struct mapent_cache *mc,
- const char *key)
+struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key)
{
struct mapent *me;
char *parent, *tail;
@@ -796,7 +795,7 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
if (!IS_MM(this))
return 0;
- parent = get_offset_parent(mc, offset);
+ parent = cache_get_offset_parent(mc, offset);
if (parent)
this->parent = parent;
else
diff --git a/lib/mounts.c b/lib/mounts.c
index 40ebf9cf..a0bf3d52 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1481,6 +1481,53 @@ static void tree_mapent_free(struct tree_node *n)
n->right = NULL;
}
+int tree_mapent_add_node(struct mapent_cache *mc,
+ const char *root, const char *key)
+{
+ unsigned int logopt = mc->ap->logopt;
+ struct tree_node *tree, *n;
+ struct mapent *base;
+ 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,
+ "failed to find multi-mount root of offset tree",
+ key);
+ return 0;
+ }
+ tree = MAPENT_ROOT(base);
+
+ 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(tree, me);
+ if (!n)
+ return 0;
+
+ MAPENT_SET_ROOT(me, tree)
+
+ /* Set the subtree parent */
+ parent = cache_get_offset_parent(mc, key);
+ if (!parent)
+ MAPENT_SET_PARENT(me, tree)
+ else
+ MAPENT_SET_PARENT(me, MAPENT_NODE(parent))
+
+ return 1;
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names

View File

@ -0,0 +1,94 @@
autofs-5.1.7 - add tree_mapent_cleanup_offsets()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_cleanup_offsets() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 1 +
lib/mounts.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index e2fd532c..89d4cfa0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -37,6 +37,7 @@
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
- fix mount_fullpath().
+- add tree_mapent_cleanup_offsets().
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 b5a1193b..5441ee0e 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -171,6 +171,7 @@ void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned
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_delete_offsets(struct mapent_cache *mc, const char *key);
+void tree_mapent_cleanup_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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 497c28c9..ba573b9a 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1647,6 +1647,51 @@ int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key)
return 1;
}
+static void tree_mapent_umount_mount(struct autofs_point *ap, const char *mp)
+{
+ if (is_mounted(mp, MNTS_ALL)) {
+ if (umount(mp)) {
+ error(ap->logopt, "error recovering from mount fail");
+ error(ap->logopt, "cannot umount %s", mp);
+ }
+ }
+}
+
+static int tree_mapent_cleanup_offsets_work(struct tree_node *n, void *ptr)
+{
+ struct mapent *oe = MAPENT(n);
+ struct traverse_subtree_context *ctxt = ptr;
+
+ tree_mapent_umount_mount(ctxt->ap, oe->key);
+
+ return 1;
+}
+
+void tree_mapent_cleanup_offsets(struct mapent *oe)
+{
+ struct tree_node *base = MAPENT_NODE(oe);
+ struct traverse_subtree_context ctxt = {
+ .ap = oe->mc->ap,
+ .base = base,
+ .strict = 0,
+ };
+ struct autofs_point *ap = oe->mc->ap;
+
+ tree_mapent_traverse_subtree(base, tree_mapent_cleanup_offsets_work, &ctxt);
+
+ /* Cleanup base mount after offsets have been cleaned up */
+ if (*oe->key == '/')
+ tree_mapent_umount_mount(ap, oe->key);
+ else {
+ char mp[PATH_MAX + 1];
+
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key))
+ error(ap->logopt, "mount path is too long");
+ else
+ tree_mapent_umount_mount(ap, mp);
+ }
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names

View File

@ -0,0 +1,119 @@
autofs-5.1.7 - add tree_mapent_delete_offsets()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_delete_offsets() to the mapent tree handling
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 1 +
lib/mounts.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 85730eda..488b4996 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -34,6 +34,7 @@
- make tree implementation data independent.
- add mapent tree implementation.
- add tree_mapent_add_node().
+- add tree_mapent_delete_offsets().
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 a0e60e24..b5a1193b 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -170,6 +170,7 @@ 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_delete_offsets(struct mapent_cache *mc, const char *key);
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);
diff --git a/lib/mounts.c b/lib/mounts.c
index a0bf3d52..eb700c79 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1528,6 +1528,76 @@ int tree_mapent_add_node(struct mapent_cache *mc,
return 1;
}
+static int tree_mapent_delete_offset_tree(struct tree_node *root)
+{
+ struct mapent *me = MAPENT(root);
+ unsigned int logopt = me->mc->ap->logopt;
+ int ret = CHE_OK;
+
+ if (root->left) {
+ ret = tree_mapent_delete_offset_tree(root->left);
+ if (!ret)
+ return 0;
+ root->left = NULL;
+ }
+ if (root->right) {
+ ret = tree_mapent_delete_offset_tree(root->right);
+ if (!ret)
+ return 0;
+ root->right = NULL;
+ }
+
+ /* Keep the owner of the multi-mount offset tree and clear
+ * the root and parent when done.
+ */
+ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) {
+ struct tree_node *root = MAPENT_ROOT(me);
+
+ debug(logopt, "deleting offset key %s", me->key);
+
+ /* cache_delete won't delete an active offset */
+ MAPENT_SET_ROOT(me, NULL);
+ ret = cache_delete(me->mc, me->key);
+ if (ret != CHE_OK) {
+ MAPENT_SET_ROOT(me, root);
+ warn(logopt, "failed to delete offset %s", me->key);
+ }
+ } else {
+ MAPENT_SET_ROOT(me, NULL);
+ MAPENT_SET_PARENT(me, NULL);
+ }
+
+ return ret == CHE_OK ? 1 : 0;
+}
+
+int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key)
+{
+ unsigned int logopt = mc->ap->logopt;
+ struct mapent *me;
+
+ me = cache_lookup_distinct(mc, key);
+ if (!me) {
+ error(logopt,
+ "failed to find multi-mount root for key %s", key);
+ return 0;
+ }
+
+ /* Not offset list owner */
+ if (MAPENT_ROOT(me) != MAPENT_NODE(me)) {
+ error(logopt,
+ "mapent for key %s is not multi-mount owner", key);
+ return 0;
+ }
+
+ if (!tree_mapent_delete_offset_tree(MAPENT_ROOT(me))) {
+ error(logopt,
+ "could not delete map entry offsets for key %s", key);
+ return 0;
+ }
+
+ return 1;
+}
+
/* From glibc decode_name() */
/* Since the values in a line are separated by spaces, a name cannot
* contain a space. Therefore some programs encode spaces in names

View File

@ -0,0 +1,83 @@
autofs-5.1.7 - add tree_mapent_traverse_subtree()
From: Ian Kent <raven@themaw.net>
Add function tree_mapent_traverse_subtree() that enumerates offsets from
a given base node bounded by subtree nesting points.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index 488b4996..390028ac 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,6 +35,7 @@
- add mapent tree implementation.
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
+- add tree_mapent_traverse_subtree().
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 eb700c79..fded4c09 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1528,6 +1528,53 @@ int tree_mapent_add_node(struct mapent_cache *mc,
return 1;
}
+static inline int tree_mapent_is_root(struct mapent *oe)
+{
+ /* Offset "/" is a special case, it's looked up and mounted
+ * seperately because the offset tree may or may not have a
+ * real mount at the base and the triggers inside it need to
+ * be mounted in either case. Also the order requires the
+ * offset at the top of the (sub)tree to be handled after
+ * the traversal.
+ */
+ return (oe->key[oe->len - 1] == '/' ||
+ MAPENT_ROOT(oe) == MAPENT_NODE(oe));
+}
+
+struct traverse_subtree_context {
+ struct autofs_point *ap;
+ struct tree_node *base;
+ int strict;
+};
+
+static int tree_mapent_traverse_subtree(struct tree_node *n, tree_work_fn_t work, void *ptr)
+{
+ struct traverse_subtree_context *ctxt = ptr;
+ struct mapent *oe = MAPENT(n);
+ int ret = 1;
+
+ if (n->left) {
+ ret = tree_mapent_traverse_subtree(n->left, work, ctxt);
+ if (!ret && ctxt->strict)
+ goto done;
+ }
+
+ /* Node is not multi-mount root and is part of current subtree */
+ if (!tree_mapent_is_root(oe) && MAPENT_PARENT(oe) == ctxt->base) {
+ ret = work(n, ctxt);
+ if (!ret && ctxt->strict)
+ goto done;
+ }
+
+ if (n->right) {
+ ret = tree_mapent_traverse_subtree(n->right, work, ctxt);
+ if (!ret && ctxt->strict)
+ goto done;
+ }
+done:
+ return ret;
+}
+
static int tree_mapent_delete_offset_tree(struct tree_node *root)
{
struct mapent *me = MAPENT(root);

View File

@ -0,0 +1,335 @@
autofs-5.1.7 - add xdr_exports()
From: Ian Kent <raven@themaw.net>
Add an xdr_exports() function to get NFS exports from a server.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 3 +
include/rpc_subs.h | 14 ++++++
lib/rpc_subs.c | 120 +++++++++++++++++++++++++++++++++++-------------
modules/lookup_hosts.c | 25 +++-------
4 files changed, 112 insertions(+), 50 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2c48484b..84050e91 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+
+- add xdr_exports().
+
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
- update ldap READMEs and schema definitions.
diff --git a/include/rpc_subs.h b/include/rpc_subs.h
index 7ba4b93f..080f19d9 100644
--- a/include/rpc_subs.h
+++ b/include/rpc_subs.h
@@ -17,6 +17,7 @@
#define _RPC_SUBS_H
#include <rpc/rpc.h>
+#include <rpc/types.h>
#include <rpc/pmap_prot.h>
#include <linux/nfs.h>
#include <linux/nfs2.h>
@@ -47,6 +48,17 @@
#define HOST_ENT_BUF_SIZE 2048
+struct hostinfo {
+ char *name;
+ struct hostinfo *next;
+};
+
+struct exportinfo {
+ char *dir;
+ struct hostinfo *hosts;
+ struct exportinfo *next;
+};
+
struct conn_info {
const char *host;
struct sockaddr *addr;
@@ -71,6 +83,8 @@ int rpc_portmap_getport(struct conn_info *, struct pmap *, unsigned short *);
int rpc_ping_proto(struct conn_info *);
int rpc_ping(const char *, int, unsigned int, long, long, unsigned int);
double monotonic_elapsed(struct timespec, struct timespec);
+struct exportinfo *rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
+void rpc_exports_free(struct exportinfo *exports);
const char *get_addr_string(struct sockaddr *, char *, socklen_t);
#endif
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index 643b7687..7b8162b4 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -41,7 +41,6 @@ const rpcprog_t rpcb_prog = PMAPPROG;
const rpcvers_t rpcb_version = PMAPVERS;
#endif
-#include "mount.h"
#include "rpc_subs.h"
#include "replicated.h"
#include "automount.h"
@@ -58,6 +57,17 @@ const rpcvers_t rpcb_version = PMAPVERS;
#define MAX_NETWORK_LEN 255
+#define EXPPATHLEN 1024
+#define EXPNAMELEN 255
+
+#define MOUNTPROG 100005
+
+#define MOUNTVERS 1
+#define MOUNTVERS_NFSV3 3
+#define MOUNTVERS_POSIX 2
+
+#define MOUNTPROC_EXPORT 5
+
/* Get numeric value of the n bits starting at position p */
#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n))
@@ -1102,7 +1112,55 @@ double monotonic_elapsed(struct timespec start, struct timespec end)
return t2 - t1;
}
-static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
+static bool_t xdr_host(XDR *xdrs, struct hostinfo *host)
+{
+ if (!xdr_string(xdrs, &host->name, EXPNAMELEN))
+ return FALSE;
+ return TRUE;
+}
+
+static bool_t xdr_hosts(XDR *xdrs, struct hostinfo **hosts)
+{
+ unsigned int size = sizeof(struct hostinfo);
+ char **host;
+
+ host = (char **) hosts;
+ while (1) {
+ if (!xdr_pointer(xdrs, host, size, (xdrproc_t) xdr_host))
+ return FALSE;
+ if (!*host)
+ break;
+ host = (char **) &((struct hostinfo *) *host)->next;
+ }
+ return TRUE;
+}
+
+static bool_t xdr_export(XDR *xdrs, struct exportinfo *export)
+{
+ if (!xdr_string(xdrs, &export->dir, EXPPATHLEN))
+ return FALSE;
+ if (!xdr_hosts(xdrs, &export->hosts))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t xdr_exports(XDR *xdrs, struct exportinfo **exports)
+{
+ unsigned int size = sizeof(struct exportinfo);
+ char **export;
+
+ export = (char **) exports;
+ while (1) {
+ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export))
+ return FALSE;
+ if (!*export)
+ break;
+ export = (char **) &((struct exportinfo *) *export)->next;
+ }
+ return TRUE;
+}
+
+static int rpc_get_exports_proto(struct conn_info *info, struct exportinfo **exports)
{
CLIENT *client;
enum clnt_stat status;
@@ -1133,7 +1191,7 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
while (1) {
status = clnt_call(client, MOUNTPROC_EXPORT,
(xdrproc_t) xdr_void, NULL,
- (xdrproc_t) xdr_exports, (caddr_t) exp,
+ (xdrproc_t) xdr_exports, (caddr_t) exports,
info->timeout);
if (status == RPC_SUCCESS)
break;
@@ -1168,41 +1226,43 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp)
return 1;
}
-static void rpc_export_free(exports item)
+static void rpc_export_free(struct exportinfo *export)
{
- groups grp;
- groups tmp;
-
- if (item->ex_dir)
- free(item->ex_dir);
-
- grp = item->ex_groups;
- while (grp) {
- if (grp->gr_name)
- free(grp->gr_name);
- tmp = grp;
- grp = grp->gr_next;
+ struct hostinfo *host, *tmp;
+
+ if (export->dir)
+ free(export->dir);
+
+ host = export->hosts;
+ while (host) {
+ if (host->name)
+ free(host->name);
+ tmp = host;
+ host = host->next;
free(tmp);
}
- free(item);
+ free(export);
}
-void rpc_exports_free(exports list)
+void rpc_exports_free(struct exportinfo *exports)
{
- exports tmp;
+ struct exportinfo *export, *tmp;
- while (list) {
- tmp = list;
- list = list->ex_next;
+ export = exports;
+ while (export) {
+ tmp = export;
+ export = export->next;
rpc_export_free(tmp);
}
return;
}
-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option)
+struct exportinfo *rpc_get_exports(const char *host,
+ long seconds, long micros,
+ unsigned int option)
{
struct conn_info info;
- exports exportlist;
+ struct exportinfo *exports = NULL;
struct pmap parms;
int status;
@@ -1231,11 +1291,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in
if (status < 0)
goto try_tcp;
- memset(&exportlist, '\0', sizeof(exportlist));
-
- status = rpc_get_exports_proto(&info, &exportlist);
+ status = rpc_get_exports_proto(&info, &exports);
if (status)
- return exportlist;
+ return exports;
try_tcp:
info.proto = IPPROTO_TCP;
@@ -1246,13 +1304,11 @@ try_tcp:
if (status < 0)
return NULL;
- memset(&exportlist, '\0', sizeof(exportlist));
-
- status = rpc_get_exports_proto(&info, &exportlist);
+ status = rpc_get_exports_proto(&info, &exports);
if (!status)
return NULL;
- return exportlist;
+ return exports;
}
const char *get_addr_string(struct sockaddr *sa, char *name, socklen_t len)
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 744062e2..81a4eb18 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -20,14 +20,6 @@
#include <sys/stat.h>
#include <netdb.h>
-/*
- * Avoid annoying compiler noise by using an alternate name for
- * typedef name in mount.h
- */
-#define name __dummy_type_name
-#include "mount.h"
-#undef name
-
#define MODULE_LOOKUP
#include "automount.h"
#include "nsswitch.h"
@@ -43,9 +35,6 @@ struct lookup_context {
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
-exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option);
-void rpc_exports_free(exports list);
-
int lookup_init(const char *mapfmt,
int argc, const char *const *argv, void **context)
{
@@ -99,7 +88,7 @@ static char *get_exports(struct autofs_point *ap, const char *host)
{
char buf[MAX_ERR_BUF];
char *mapent;
- exports exp, this;
+ struct exportinfo *exp, *this;
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
@@ -111,7 +100,7 @@ static char *get_exports(struct autofs_point *ap, const char *host)
if (mapent) {
int len = strlen(mapent) + 1;
- len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3;
+ len += strlen(host) + 2*(strlen(this->dir) + 2) + 3;
mapent = realloc(mapent, len);
if (!mapent) {
char *estr;
@@ -121,10 +110,10 @@ static char *get_exports(struct autofs_point *ap, const char *host)
return NULL;
}
strcat(mapent, " \"");
- strcat(mapent, this->ex_dir);
+ strcat(mapent, this->dir);
strcat(mapent, "\"");
} else {
- int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3;
+ int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3;
mapent = malloc(len);
if (!mapent) {
@@ -135,16 +124,16 @@ static char *get_exports(struct autofs_point *ap, const char *host)
return NULL;
}
strcpy(mapent, "\"");
- strcat(mapent, this->ex_dir);
+ strcat(mapent, this->dir);
strcat(mapent, "\"");
}
strcat(mapent, " \"");
strcat(mapent, host);
strcat(mapent, ":");
- strcat(mapent, this->ex_dir);
+ strcat(mapent, this->dir);
strcat(mapent, "\"");
- this = this->ex_next;
+ this = this->next;
}
rpc_exports_free(exp);

View File

@ -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();
}

View File

@ -0,0 +1,50 @@
autofs-5.1.7 - check for offset with no mount location
From: Ian Kent <raven@themaw.net>
Offsets need to have a mount location, check for it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index a9209755..42914160 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -47,6 +47,7 @@
- pass root length to mount_fullpath().
- remove unused function master_submount_list_empty().
- move amd mounts removal into lib/mounts.c.
+- check for offset with no mount location.
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 b1c2611c..a81d4028 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -801,7 +801,20 @@ update_offset_entry(struct autofs_point *ap,
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
- /* Internal hosts map may have loc == NULL */
+ if (!loc || !*loc) {
+ const char *type = ap->entry->maps->type;
+
+ /* If it's not the internal hosts map it must have a
+ * mount location.
+ */
+ if (!type || strcmp(type, "hosts")) {
+ error(ap->logopt,
+ MODPREFIX "syntax error in offset %s -> %s",
+ m_offset, loc);
+ return CHE_FAIL;
+ }
+ }
+
if (!*m_offset) {
error(ap->logopt,
MODPREFIX "syntax error in offset %s -> %s", m_offset, loc);

View File

@ -0,0 +1,64 @@
autofs-5.1.7 - cleanup cache_delete() a little
From: Ian Kent <raven@themaw.net>
There's no reason to use local function storage for the passed in key
just use the given key.
Also, if there's no hash array entry for the key then there's no cache
entry so don't return a fail for this case.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 11 +++--------
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6419052d..e822efec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,7 @@
- eliminate some strlen calls in offset handling.
- don't add offset mounts to mounted mounts table.
- reduce umount EBUSY check delay.
+- cleanup cache_delete() a little.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/cache.c b/lib/cache.c
index 03d0499a..a90bbb1d 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -917,20 +917,15 @@ int cache_delete(struct mapent_cache *mc, const char *key)
struct mapent *me = NULL, *pred;
u_int32_t hashval = hash(key, mc->size);
int ret = CHE_OK;
- char this[PATH_MAX];
-
- strcpy(this, key);
me = mc->hash[hashval];
- if (!me) {
- ret = CHE_FAIL;
+ if (!me)
goto done;
- }
while (me->next != NULL) {
pred = me;
me = me->next;
- if (strcmp(this, me->key) == 0) {
+ if (strcmp(key, me->key) == 0) {
struct stack *s = me->stack;
if (me->multi && !list_empty(&me->multi_list)) {
ret = CHE_FAIL;
@@ -959,7 +954,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
if (!me)
goto done;
- if (strcmp(this, me->key) == 0) {
+ if (strcmp(key, me->key) == 0) {
struct stack *s = me->stack;
if (me->multi && !list_empty(&me->multi_list)) {
ret = CHE_FAIL;

View File

@ -0,0 +1,207 @@
autofs-5.1.7 - don't add offset mounts to mounted mounts table
From: Ian Kent <raven@themaw.net>
Multi-mount offset mounts are added to the mounted mounts table whether
they have a real mount or not. If there are a large number of offsets
this can add unnecessary overhead to the mounted mounts table processing.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 14 ++++----------
daemon/indirect.c | 4 +++-
include/mounts.h | 2 +-
lib/mounts.c | 43 +++++++++++--------------------------------
5 files changed, 20 insertions(+), 44 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index cb709773..b144f6aa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,6 +22,7 @@
- remove unused mount offset list lock functions.
- eliminate count_mounts() from expire_proc_indirect().
- eliminate some strlen calls in offset handling.
+- don't add offset mounts to mounted mounts table.
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 311a98ba..fbfebbdd 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -605,9 +605,6 @@ force_umount:
} else
info(ap->logopt, "umounted offset mount %s", me->key);
- if (!rv)
- mnts_remove_mount(me->key, MNTS_OFFSET);
-
return rv;
}
@@ -761,12 +758,6 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
- mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET);
- if (!mnt)
- error(ap->logopt,
- "failed to add offset mount %s to mounted list",
- me->key);
-
debug(ap->logopt, "mounted trigger %s", me->key);
return MOUNT_OFFSET_OK;
@@ -1214,6 +1205,7 @@ static void *do_mount_direct(void *arg)
struct mapent *me;
struct statfs fs;
unsigned int close_fd = 0;
+ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED;
sbmnt = mnts_find_submount(mt.name);
if (statfs(mt.name, &fs) == -1 ||
@@ -1232,6 +1224,8 @@ static void *do_mount_direct(void *arg)
close_fd = 0;
if (!close_fd)
me->ioctlfd = mt.ioctlfd;
+ if (me->multi && me->multi != me)
+ flags |= MNTS_OFFSET;
}
ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
cache_unlock(mt.mc);
@@ -1240,7 +1234,7 @@ static void *do_mount_direct(void *arg)
info(ap->logopt, "mounted %s", mt.name);
- mnts_set_mounted_mount(ap, mt.name);
+ mnts_set_mounted_mount(ap, mt.name, flags);
conditional_alarm_add(ap, ap->exp_runfreq);
} else {
diff --git a/daemon/indirect.c b/daemon/indirect.c
index b259ebdc..eddcfff7 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -747,12 +747,14 @@ static void *do_mount_indirect(void *arg)
status = lookup_nss_mount(ap, NULL, mt.name, mt.len);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
if (status) {
+ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED;
+
ops->send_ready(ap->logopt,
ap->ioctlfd, mt.wait_queue_token);
info(ap->logopt, "mounted %s", buf);
- mnts_set_mounted_mount(ap, mt.name);
+ mnts_set_mounted_mount(ap, mt.name, flags);
conditional_alarm_add(ap, ap->exp_runfreq);
} else {
diff --git a/include/mounts.h b/include/mounts.h
index e3022b23..ac480c06 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -131,7 +131,7 @@ struct mnt_list *get_mnt_list(const char *path, int include);
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
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);
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
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);
diff --git a/lib/mounts.c b/lib/mounts.c
index 04fe3d00..25ae2e1d 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1172,7 +1172,7 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
this = mnts_get_mount(mp);
if (this) {
this->flags |= flags;
- if (list_empty(&this->mount))
+ if ((this->flags & MNTS_MOUNTED) && list_empty(&this->mount))
list_add(&this->mount, &ap->mounts);
}
mnts_hash_mutex_unlock();
@@ -1193,42 +1193,23 @@ void mnts_remove_mount(const char *mp, unsigned int flags)
this = mnts_lookup(mp);
if (this && this->flags & flags) {
this->flags &= ~flags;
- if (!(this->flags & (MNTS_OFFSET|MNTS_MOUNTED)))
+ if (!(this->flags & MNTS_MOUNTED))
list_del_init(&this->mount);
__mnts_put_mount(this);
}
mnts_hash_mutex_unlock();
}
-void mnts_set_mounted_mount(struct autofs_point *ap, const char *name)
+void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags)
{
struct mnt_list *mnt;
- mnt = mnts_add_mount(ap, name, MNTS_MOUNTED);
+ mnt = mnts_add_mount(ap, name, flags);
if (!mnt) {
error(ap->logopt,
"failed to add mount %s to mounted list", name);
return;
}
-
- /* Offset mount failed but non-strict returns success */
- if (mnt->flags & MNTS_OFFSET &&
- !is_mounted(mnt->mp, MNTS_REAL)) {
- mnt->flags &= ~MNTS_MOUNTED;
- mnts_put_mount(mnt);
- }
-
- /* Housekeeping.
- * Set the base type of the mounted mount.
- * MNTS_AUTOFS and MNTS_OFFSET are set at mount time and
- * are used during expire.
- */
- if (!(mnt->flags & (MNTS_AUTOFS|MNTS_OFFSET))) {
- if (ap->type == LKP_INDIRECT)
- mnt->flags |= MNTS_INDIRECT;
- else
- mnt->flags |= MNTS_DIRECT;
- }
}
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap)
@@ -1947,17 +1928,13 @@ static int do_remount_direct(struct autofs_point *ap,
ret = lookup_nss_mount(ap, NULL, path, strlen(path));
if (ret) {
- struct mnt_list *mnt;
+ unsigned int flags = MNTS_DIRECT|MNTS_MOUNTED;
/* If it's an offset mount add a mount reference */
- if (type == t_offset) {
- mnt = mnts_add_mount(ap, path, MNTS_OFFSET);
- if (!mnt)
- error(ap->logopt,
- "failed to add mount %s to mounted list", path);
- }
+ if (type == t_offset)
+ flags |= MNTS_OFFSET;
- mnts_set_mounted_mount(ap, path);
+ mnts_set_mounted_mount(ap, path, flags);
info(ap->logopt, "re-connected to %s", path);
@@ -2032,7 +2009,9 @@ static int do_remount_indirect(struct autofs_point *ap, const unsigned int type,
ret = lookup_nss_mount(ap, NULL, de[n]->d_name, len);
if (ret) {
- mnts_set_mounted_mount(ap, buf);
+ unsigned int flags = MNTS_INDIRECT|MNTS_MOUNTED;
+
+ mnts_set_mounted_mount(ap, buf, flags);
info(ap->logopt, "re-connected to %s", buf);

View File

@ -0,0 +1,64 @@
autofs-5.1.7 - don't pass root to do_mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
The root parameter of do_mount_autofs_offset() is used only in a
debug log message. It doesn't really add any value to debugging
so remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 9 ++++-----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0e9ca94f..2a07bd45 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,7 @@
- reduce umount EBUSY check delay.
- cleanup cache_delete() a little.
- rename path to m_offset in update_offset_entry().
+- don't pass root to do_mount_autofs_offset().
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 25ae2e1d..289500da 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2453,13 +2453,12 @@ out:
return rv;
}
-static int do_mount_autofs_offset(struct autofs_point *ap,
- struct mapent *oe, const char *root)
+static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe)
{
int mounted = 0;
int ret;
- debug(ap->logopt, "mount offset %s at %s", oe->key, root);
+ debug(ap->logopt, "mount offset %s", oe->key);
ret = mount_autofs_offset(ap, oe);
if (ret >= MOUNT_OFFSET_OK)
@@ -2651,7 +2650,7 @@ static int do_umount_offset(struct autofs_point *ap,
*/
ret = rmdir_path_offset(ap, oe);
if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root);
+ ret = do_mount_autofs_offset(ap, oe);
if (ret)
left++;
/* But we did origianlly create this */
@@ -2697,7 +2696,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
goto cont;
}
- mounted += do_mount_autofs_offset(ap, oe, root);
+ mounted += do_mount_autofs_offset(ap, oe);
/*
* If re-constructing a multi-mount it's necessary to walk

View File

@ -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);

View File

@ -0,0 +1,112 @@
autofs-5.1.7 - dont use realloc in host exports list processing
From: Ian Kent <raven@themaw.net>
If a server exports list is very large calling realloc(3) for each
export is slow. It's better to traverse the exports list twice, once
to calculate the length of the mapent then allocate the memory and
traverse the exports list again to construct the mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 59 +++++++++++++++++++++---------------------------
2 files changed, 27 insertions(+), 33 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 19af245e..1bd6ac7f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
- add xdr_exports().
- remove mount.x and rpcgen dependencies.
+- dont use realloc in host exports list processing.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index 81a4eb18..e3ee0ab8 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -89,44 +89,40 @@ static char *get_exports(struct autofs_point *ap, const char *host)
char buf[MAX_ERR_BUF];
char *mapent;
struct exportinfo *exp, *this;
+ size_t hostlen = strlen(host);
+ size_t mapent_len;
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER);
- mapent = NULL;
this = exp;
+ mapent_len = 0;
while (this) {
- if (mapent) {
- int len = strlen(mapent) + 1;
-
- len += strlen(host) + 2*(strlen(this->dir) + 2) + 3;
- mapent = realloc(mapent, len);
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NULL;
- }
- strcat(mapent, " \"");
- strcat(mapent, this->dir);
- strcat(mapent, "\"");
- } else {
- int len = 2*(strlen(this->dir) + 2) + strlen(host) + 3;
-
- mapent = malloc(len);
- if (!mapent) {
- char *estr;
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, MODPREFIX "malloc: %s", estr);
- rpc_exports_free(exp);
- return NULL;
- }
+ mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
+ this = this->next;
+ }
+
+ mapent = malloc(mapent_len + 1);
+ if (!mapent) {
+ char *estr;
+ estr = strerror_r(errno, buf, MAX_ERR_BUF);
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
+ error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
+ rpc_exports_free(exp);
+ return NULL;
+ }
+ *mapent = 0;
+
+ this = exp;
+ while (this) {
+ if (!*mapent)
strcpy(mapent, "\"");
- strcat(mapent, this->dir);
- strcat(mapent, "\"");
- }
+ else
+ strcat(mapent, " \"");
+ strcat(mapent, this->dir);
+ strcat(mapent, "\"");
+
strcat(mapent, " \"");
strcat(mapent, host);
strcat(mapent, ":");
@@ -137,9 +133,6 @@ static char *get_exports(struct autofs_point *ap, const char *host)
}
rpc_exports_free(exp);
- if (!mapent)
- error(ap->logopt, MODPREFIX "exports lookup failed for %s", host);
-
return mapent;
}

View File

@ -0,0 +1,378 @@
autofs-5.1.7 - eliminate cache_lookup_offset() usage
From: Ian Kent <raven@themaw.net>
The function cache_lookup_offset() will do a linear search when
looking for an offset. If the number of offsets is large this
can be a lot of overhead.
But it's possible to use the information already present where
this is called to to do a hashed lookup instead.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 82 +++++++++++++++++++++++++++++++++------------------
modules/parse_sun.c | 77 ++++++++++++++++++++++++++++++------------------
3 files changed, 102 insertions(+), 58 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0b577909..484bd866 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
- use sprintf() when constructing hosts mapent.
- fix mnts_remove_amdmount() uses wrong list.
- Fix option for master read wait.
+- eliminate cache_lookup_offset() usage.
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 ccbd52e0..42e8ef07 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2495,24 +2495,27 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
char *offset = path;
struct mapent *oe;
struct list_head *pos = NULL;
- unsigned int fs_path_len;
+ unsigned int root_len = strlen(root);
int mounted;
- fs_path_len = start + strlen(base);
- if (fs_path_len > PATH_MAX)
- return -1;
-
mounted = 0;
offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
while (offset) {
- int plen = fs_path_len + strlen(offset);
+ char key[PATH_MAX + 1];
+ int key_len = root_len + strlen(offset);
- if (plen > PATH_MAX) {
+ if (key_len > PATH_MAX) {
warn(ap->logopt, "path loo long");
goto cont;
}
- oe = cache_lookup_offset(base, offset, start, &me->multi_list);
+ /* The root offset is always mounted seperately so the
+ * offset path will always be root + offset.
+ */
+ strcpy(key, root);
+ strcat(key, offset);
+
+ oe = cache_lookup_distinct(me->mc, key);
if (!oe || !oe->mapent)
goto cont;
@@ -2525,12 +2528,8 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
*/
if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL)) {
- char oe_root[PATH_MAX + 1];
- strcpy(oe_root, root);
- strcat(oe_root, offset);
- mount_multi_triggers(ap, oe, oe_root, strlen(oe_root), base);
- }
+ is_mounted(oe->key, MNTS_REAL))
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
}
cont:
offset = cache_get_offset(base,
@@ -2584,6 +2583,8 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
const char o_root[] = "/";
const char *mm_base;
int left, start;
+ unsigned int root_len;
+ unsigned int mm_base_len;
left = 0;
start = strlen(root);
@@ -2597,11 +2598,28 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
pos = NULL;
offset = path;
+ root_len = start;
+ mm_base_len = strlen(mm_base);
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+ char key[PATH_MAX + 1];
+ int key_len = root_len + strlen(offset);
char *oe_base;
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+ if (mm_base_len > 1)
+ key_len += mm_base_len;
+
+ if (key_len > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
+ continue;
+ }
+
+ strcpy(key, root);
+ if (mm_base_len > 1)
+ strcat(key, mm_base);
+ strcat(key, offset);
+
+ oe = cache_lookup_distinct(me->mc, key);
/* root offset is a special case */
if (!oe || (strlen(oe->key) - start) == 1)
continue;
@@ -2686,13 +2704,14 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
char *root;
char mm_top[PATH_MAX + 1];
char path[PATH_MAX + 1];
- char buf[MAX_ERR_BUF];
char *offset;
struct mapent *oe;
struct list_head *mm_root, *pos;
const char o_root[] = "/";
const char *mm_base;
int left, start;
+ unsigned int root_len;
+ unsigned int mm_base_len;
time_t age;
if (top)
@@ -2720,14 +2739,30 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
pos = NULL;
offset = path;
+ root_len = start;
+ mm_base_len = strlen(mm_base);
age = me->multi->age;
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
+ char key[PATH_MAX + 1];
+ int key_len = root_len + strlen(offset);
char *oe_base;
- char *key;
int ret;
- oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list);
+ if (mm_base_len > 1)
+ key_len += mm_base_len;
+
+ if (key_len > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
+ continue;
+ }
+
+ strcpy(key, root);
+ if (mm_base_len > 1)
+ strcat(key, mm_base);
+ strcat(key, offset);
+
+ oe = cache_lookup_distinct(me->mc, key);
/* root offset is a special case */
if (!oe || (strlen(oe->key) - start) == 1)
continue;
@@ -2778,14 +2813,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
}
}
- key = strdup(oe->key);
- if (!key) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- error(ap->logopt, "malloc: %s", estr);
- left++;
- continue;
- }
-
debug(ap->logopt, "umount offset %s", oe->key);
if (umount_autofs_offset(ap, oe)) {
@@ -2800,7 +2827,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
error(ap->logopt,
"failed to delete offset key %s", key);
- free(key);
continue;
}
@@ -2816,7 +2842,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
left++;
/* But we did origianlly create this */
oe->flags |= MOUNT_FLAG_DIR_CREATED;
- free(key);
continue;
}
/*
@@ -2834,7 +2859,6 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
error(ap->logopt,
"failed to delete offset key %s", key);
}
- free(key);
}
return left;
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 4b137f99..819d6adc 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1086,6 +1086,8 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
struct list_head *mm_root, *pos;
const char o_root[] = "/";
const char *mm_base;
+ unsigned int root_len;
+ unsigned int mm_base_len;
mm_root = &me->multi->multi_list;
@@ -1095,16 +1097,31 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
mm_base = base;
pos = NULL;
+ root_len = strlen(root);
+ mm_base_len = strlen(mm_base);
/* Make sure "none" of the offsets have an active mount. */
while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) {
- oe = cache_lookup_offset(mm_base, poffset, start, &me->multi_list);
- /* root offset is a special case */
- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
+ unsigned int path_len = root_len + strlen(poffset);
+
+ if (mm_base_len > 1)
+ path_len += mm_base_len;
+
+ if (path_len > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
continue;
+ }
strcpy(path, root);
+ if (mm_base_len > 1)
+ strcat(path, mm_base);
strcat(path, poffset);
+
+ oe = cache_lookup_distinct(me->mc, path);
+ /* root offset is a special case */
+ if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
+ continue;
+
if (umount(path)) {
error(ap->logopt, "error recovering from mount fail");
error(ap->logopt, "cannot umount offset %s", path);
@@ -1117,17 +1134,14 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
static int mount_subtree(struct autofs_point *ap, struct mapent *me,
const char *name, char *loc, char *options, void *ctxt)
{
- struct mapent *mm;
struct mapent *ro;
char *mm_root, *mm_base, *mm_key;
- const char *mnt_root;
- unsigned int mm_root_len, mnt_root_len;
+ unsigned int mm_root_len;
int start, ret = 0, rv;
rv = 0;
- mm = me->multi;
- mm_key = mm->key;
+ mm_key = me->multi->key;
if (*mm_key == '/') {
mm_root = mm_key;
@@ -1141,20 +1155,26 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
mm_root_len = strlen(mm_root);
- mnt_root = mm_root;
- mnt_root_len = mm_root_len;
-
if (me == me->multi) {
+ char key[PATH_MAX + 1];
+
+ if (mm_root_len + 1 > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
+ return 1;
+ }
+
/* name = NULL */
/* destination = mm_root */
mm_base = "/";
+ strcpy(key, mm_root);
+ strcat(key, mm_base);
+
/* Mount root offset if it exists */
- ro = cache_lookup_offset(mm_base, mm_base, strlen(mm_root), &me->multi_list);
+ ro = cache_lookup_distinct(me->mc, key);
if (ro) {
- char *myoptions, *ro_loc, *tmp;
+ char *myoptions, *ro_loc;
int namelen = name ? strlen(name) : 0;
- const char *root;
int ro_len;
myoptions = NULL;
@@ -1172,13 +1192,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
if (ro_loc)
ro_len = strlen(ro_loc);
- tmp = alloca(mnt_root_len + 2);
- strcpy(tmp, mnt_root);
- tmp[mnt_root_len] = '/';
- tmp[mnt_root_len + 1] = '\0';
- root = tmp;
-
- rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt);
+ rv = sun_mount(ap, key, name, namelen, ro_loc, ro_len, myoptions, ctxt);
free(myoptions);
if (ro_loc)
@@ -1186,11 +1200,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
}
if (ro && rv == 0) {
- ret = mount_multi_triggers(ap, me, mnt_root, start, mm_base);
+ ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
return 1;
}
} else if (rv <= 0) {
@@ -1206,24 +1220,29 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
int loclen = strlen(loc);
int namelen = strlen(name);
- mnt_root = name;
-
/* name = mm_root + mm_base */
/* destination = mm_root + mm_base = name */
mm_base = &me->key[start];
- rv = sun_mount(ap, mnt_root, name, namelen, loc, loclen, options, ctxt);
+ rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt);
if (rv == 0) {
- ret = mount_multi_triggers(ap, me->multi, mnt_root, start, mm_base);
+ ret = mount_multi_triggers(ap, me->multi, name, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, mnt_root, start, mm_base);
+ cleanup_multi_triggers(ap, me, name, start, mm_base);
return 1;
}
} else if (rv < 0) {
- char *mm_root_base = alloca(strlen(mm_root) + strlen(mm_base) + 1);
+ char mm_root_base[PATH_MAX + 1];
+ unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1;
+ if (mm_root_base_len > PATH_MAX) {
+ warn(ap->logopt, MODPREFIX "path too long");
+ cache_delete_offset_list(me->mc, name);
+ return 1;
+ }
+
strcpy(mm_root_base, mm_root);
strcat(mm_root_base, mm_base);

View File

@ -0,0 +1,290 @@
autofs-5.1.7 - eliminate clean_stale_multi_triggers()
From: Ian Kent <raven@themaw.net>
Eliminate clean_stale_multi_triggers() by checking for stale offsets at
the time mount_subtree() is called.
This should result in the same behaviour but eliminate an additional
seperate traversal of the offset list.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
lib/mounts.c | 209 ++++++++++-----------------------------------------
modules/parse_sun.c | 10 --
3 files changed, 43 insertions(+), 177 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5a3bedc1..b1ce7b69 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -12,6 +12,7 @@
- remove redundant variables from mount_autofs_offset().
- remove unused parameter form do_mount_autofs_offset().
- refactor umount_multi_triggers().
+- eliminate clean_stale_multi_triggers().
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 5268ba5b..a9abbebf 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2601,10 +2601,44 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
oe_base = oe->key + strlen(root);
left += do_umount_multi_triggers(ap, oe, root, oe_base);
+ /*
+ * If an offset that has an active mount has been removed
+ * from the multi-mount we don't want to attempt to trigger
+ * mounts for it. Obviously this is because it has been
+ * removed, but less obvious is the potential strange
+ * behaviour that can result if we do try and mount it
+ * again after it's been expired. For example, if an NFS
+ * file system is no longer exported and is later umounted
+ * it can be mounted again without any error message but
+ * shows as an empty directory. That's going to confuse
+ * people for sure.
+ *
+ * If the mount cannot be umounted (the process is now
+ * using a stale mount) the offset needs to be invalidated
+ * so no further mounts will be attempted but the offset
+ * cache entry must remain so expires can continue to
+ * attempt to umount it. If the mount can be umounted and
+ * the offset is removed, at least for NFS we will get
+ * ESTALE errors when attempting list the directory.
+ */
if (oe->ioctlfd != -1 ||
is_mounted(oe->key, MNTS_REAL)) {
- left++;
- return left;
+ if (umount_ent(ap, oe->key) &&
+ is_mounted(oe->key, MNTS_REAL)) {
+ debug(ap->logopt,
+ "offset %s has active mount, invalidate",
+ oe->key);
+ /*
+ * Ok, so we shouldn't modify the mapent but
+ * mount requests are blocked at a point above
+ * this and expire only uses the mapent key.
+ */
+ if (oe->mapent) {
+ free(oe->mapent);
+ oe->mapent = NULL;
+ }
+ return ++left;
+ }
}
debug(ap->logopt, "umount offset %s", oe->key);
@@ -2666,6 +2700,11 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
oe = cache_lookup_distinct(me->mc, key);
if (!oe || !oe->mapent)
goto cont;
+ if (oe->age != me->multi->age) {
+ /* Best effort */
+ do_umount_offset(ap, oe, root);
+ goto cont;
+ }
mounted += do_mount_autofs_offset(ap, oe, root);
@@ -2725,169 +2764,3 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
return left;
}
-
-int clean_stale_multi_triggers(struct autofs_point *ap,
- struct mapent *me, char *top, const char *base)
-{
- char *root;
- char mm_top[PATH_MAX + 1];
- char path[PATH_MAX + 1];
- char *offset;
- struct mapent *oe;
- struct list_head *mm_root, *pos;
- const char o_root[] = "/";
- const char *mm_base;
- int left, start;
- unsigned int root_len;
- unsigned int mm_base_len;
- time_t age;
-
- if (top)
- root = top;
- else {
- if (!strchr(me->multi->key, '/'))
- /* Indirect multi-mount root */
- /* sprintf okay - if it's mounted, it's
- * PATH_MAX or less bytes */
- sprintf(mm_top, "%s/%s", ap->path, me->multi->key);
- else
- strcpy(mm_top, me->multi->key);
- root = mm_top;
- }
-
- left = 0;
- start = strlen(root);
-
- mm_root = &me->multi->multi_list;
-
- if (!base)
- mm_base = o_root;
- else
- mm_base = base;
-
- pos = NULL;
- offset = path;
- root_len = start;
- mm_base_len = strlen(mm_base);
- age = me->multi->age;
-
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
- char *oe_base;
- int ret;
-
- if (mm_base_len > 1)
- key_len += mm_base_len;
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- continue;
- }
-
- strcpy(key, root);
- if (mm_base_len > 1)
- strcat(key, mm_base);
- strcat(key, offset);
-
- oe = cache_lookup_distinct(me->mc, key);
- /* root offset is a special case */
- if (!oe || (strlen(oe->key) - start) == 1)
- continue;
-
- /* Check for and umount stale subtree offsets */
- oe_base = oe->key + strlen(root);
- ret = clean_stale_multi_triggers(ap, oe, root, oe_base);
- left += ret;
- if (ret)
- continue;
-
- if (oe->age == age)
- continue;
-
- /*
- * If an offset that has an active mount has been removed
- * from the multi-mount we don't want to attempt to trigger
- * mounts for it. Obviously this is because it has been
- * removed, but less obvious is the potential strange
- * behaviour that can result if we do try and mount it
- * again after it's been expired. For example, if an NFS
- * file system is no longer exported and is later umounted
- * it can be mounted again without any error message but
- * shows as an empty directory. That's going to confuse
- * people for sure.
- *
- * If the mount cannot be umounted (the process is now
- * using a stale mount) the offset needs to be invalidated
- * so no further mounts will be attempted but the offset
- * cache entry must remain so expires can continue to
- * attempt to umount it. If the mount can be umounted and
- * the offset is removed, at least for NFS we will get
- * ESTALE errors when attempting list the directory.
- */
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL)) {
- if (umount_ent(ap, oe->key) &&
- is_mounted(oe->key, MNTS_REAL)) {
- debug(ap->logopt,
- "offset %s has active mount, invalidate",
- oe->key);
- if (oe->mapent) {
- free(oe->mapent);
- oe->mapent = NULL;
- }
- left++;
- continue;
- }
- }
-
- debug(ap->logopt, "umount offset %s", oe->key);
-
- if (umount_autofs_offset(ap, oe)) {
- warn(ap->logopt, "failed to umount offset %s", key);
- left++;
- } else {
- struct stat st;
-
- /* Mount point not ours to delete ? */
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED)) {
- debug(ap->logopt, "delete offset key %s", key);
- if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
- error(ap->logopt,
- "failed to delete offset key %s", key);
- continue;
- }
-
- /*
- * An error due to partial directory removal is
- * ok so only try and remount the offset if the
- * actual mount point still exists.
- */
- ret = rmdir_path_offset(ap, oe);
- if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root);
- if (ret) {
- left++;
- /* But we did origianlly create this */
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
- continue;
- }
- /*
- * Fall through if the trigger can't be mounted
- * again, since there is no offset there can't
- * be any mount requests so remove the map
- * entry from the cache. There's now a dead
- * offset mount, but what else can we do ....
- */
- }
-
- debug(ap->logopt, "delete offset key %s", key);
-
- if (cache_delete_offset(oe->mc, key) == CHE_FAIL)
- error(ap->logopt,
- "failed to delete offset key %s", key);
- }
- }
-
- return left;
-}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index f42af7b7..f4d5125c 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1176,7 +1176,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
/* Mount root offset if it exists */
ro = cache_lookup_distinct(me->mc, key);
- if (ro) {
+ if (ro && ro->age == me->multi->age) {
char *myoptions, *ro_loc;
int namelen = name ? strlen(name) : 0;
int ro_len;
@@ -1610,14 +1610,6 @@ dont_expand:
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
- /*
- * We've got the ordered list of multi-mount entries so go
- * through and remove any stale entries if this is the top
- * of the multi-mount and set the parent entry of each.
- */
- if (me == me->multi)
- clean_stale_multi_triggers(ap, me, NULL, NULL);
-
rv = mount_subtree(ap, me, name, NULL, options, ctxt);
cache_multi_unlock(me);

View File

@ -0,0 +1,140 @@
autofs-5.1.7 - eliminate count_mounts() from expire_proc_indirect()
From: Ian Kent <raven@themaw.net>
The count_mounts() function traverses the directory tree under a given
automount in order to count the number of mounts.
If there are many directories (such as when there is a very large
number of offset trigger mounts) this can take a long time.
Eliminate the call in expire_proc_indirect() by changing the expire
ioctl function to better use the expire return from the kernel.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++--
daemon/indirect.c | 10 +++++-----
lib/dev-ioctl-lib.c | 21 +++++++++++++--------
4 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c5619d2e..0b78eb62 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -20,6 +20,7 @@
- pass mapent_cache to update_offset_entry().
- fix inconsistent locking in parse_mount().
- remove unused mount offset list lock functions.
+- eliminate count_mounts() from expire_proc_indirect().
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 c41c680f..311a98ba 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -884,7 +884,7 @@ cont:
ioctlfd = me->ioctlfd;
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
- if (ret) {
+ if (ret == 1) {
left++;
pthread_setcancelstate(cur_state, NULL);
continue;
@@ -910,7 +910,7 @@ cont:
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
- if (ret)
+ if (ret == 1)
left++;
pthread_setcancelstate(cur_state, NULL);
}
diff --git a/daemon/indirect.c b/daemon/indirect.c
index 65cfe4e3..b259ebdc 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -358,7 +358,6 @@ void *expire_proc_indirect(void *arg)
struct expire_args ec;
unsigned int how;
int offsets, submnts, count;
- int retries;
int ioctlfd, cur_state;
int status, ret, left;
@@ -496,7 +495,7 @@ void *expire_proc_indirect(void *arg)
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
ret = ops->expire(ap->logopt, ioctlfd, mnt->mp, how);
- if (ret)
+ if (ret == 1)
left++;
pthread_setcancelstate(cur_state, NULL);
}
@@ -507,10 +506,11 @@ void *expire_proc_indirect(void *arg)
* so we need to umount or unlink them here.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- retries = (count_mounts(ap, ap->path, ap->dev) + 1);
- while (retries--) {
+ while (1) {
ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, how);
- if (ret)
+ if (ret != 0 && errno == EAGAIN)
+ break;
+ if (ret == 1)
left++;
}
pthread_setcancelstate(cur_state, NULL);
diff --git a/lib/dev-ioctl-lib.c b/lib/dev-ioctl-lib.c
index 7040c3da..e7a1b42a 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -650,6 +650,7 @@ static int expire(unsigned int logopt,
{
int ret, retries = EXPIRE_RETRIES;
unsigned int may_umount;
+ int save_errno = 0;
while (retries--) {
struct timespec tm = {0, 100000000};
@@ -657,9 +658,11 @@ static int expire(unsigned int logopt,
/* Ggenerate expire message for the mount. */
ret = ioctl(fd, cmd, arg);
if (ret == -1) {
+ save_errno = errno;
+
/* Mount has gone away */
if (errno == EBADF || errno == EINVAL)
- return 0;
+ break;
/*
* Other than EAGAIN is an expire error so continue.
@@ -673,14 +676,16 @@ static int expire(unsigned int logopt,
nanosleep(&tm, NULL);
}
- may_umount = 0;
- if (ctl.ops->askumount(logopt, ioctlfd, &may_umount))
- return -1;
-
- if (!may_umount)
- return 1;
+ if (!ret || save_errno == EAGAIN) {
+ may_umount = 0;
+ if (!ctl.ops->askumount(logopt, ioctlfd, &may_umount)) {
+ if (!may_umount)
+ ret = 1;
+ }
+ }
+ errno = save_errno;
- return 0;
+ return ret;
}
static int dev_ioctl_expire(unsigned int logopt,

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -71,6 +71,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.
--- autofs-5.1.7.orig/include/mounts.h
+++ autofs-5.1.7/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.7.orig/lib/mounts.c
+++ autofs-5.1.7/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.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/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);
}

View File

@ -0,0 +1,217 @@
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>
---
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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -78,6 +78,7 @@
- add missing description of null map option.
- fix nonstrict offset mount fail handling.
- fix concat_options() error handling.
+- eliminate some more alloca usage.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/modules/lookup_program.c
+++ autofs-5.1.7/modules/lookup_program.c
@@ -636,7 +636,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);
@@ -644,6 +651,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.7.orig/modules/lookup_yp.c
+++ autofs-5.1.7/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;
@@ -904,7 +912,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);
}
}
@@ -929,6 +944,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.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/modules/parse_sun.c
@@ -668,9 +668,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';
@@ -706,10 +713,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);
@@ -728,6 +735,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.7.orig/modules/replicated.c
+++ autofs-5.1.7/modules/replicated.c
@@ -1041,25 +1041,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;
}
@@ -1188,7 +1181,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,128 @@
autofs-5.1.7 - eliminate some strlen calls in offset handling
From: Ian Kent <raven@themaw.net>
There are a number of places where strlen() is used to re-calculate
the length of a string. Eliminate some of those by calculating the
length once and passing it to the functions that do the re-calculation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 30 +++++++++++++++++-------------
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0b78eb62..cb709773 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -21,6 +21,7 @@
- fix inconsistent locking in parse_mount().
- remove unused mount offset list lock functions.
- eliminate count_mounts() from expire_proc_indirect().
+- eliminate some strlen calls in offset 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 0fcd4087..04fe3d00 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2540,10 +2540,12 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
return ret;
}
-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
+static int do_umount_offset(struct autofs_point *ap,
+ struct mapent *oe, const char *root, int start);
static int do_umount_multi_triggers(struct autofs_point *ap,
- struct mapent *me, const char *root, const char *base)
+ struct mapent *me, const char *root,
+ int start, const char *base)
{
char path[PATH_MAX + 1];
char *offset;
@@ -2551,12 +2553,11 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
struct list_head *mm_root, *pos;
const char o_root[] = "/";
const char *mm_base;
- int left, start;
+ int left;
unsigned int root_len;
unsigned int mm_base_len;
left = 0;
- start = strlen(root);
mm_root = &me->multi->multi_list;
@@ -2592,13 +2593,14 @@ static int do_umount_multi_triggers(struct autofs_point *ap,
if (!oe || (strlen(oe->key) - start) == 1)
continue;
- left += do_umount_offset(ap, oe, root);
+ left += do_umount_offset(ap, oe, root, start);
}
return left;
}
-static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
+static int do_umount_offset(struct autofs_point *ap,
+ struct mapent *oe, const char *root, int start)
{
char *oe_base;
int left = 0;
@@ -2607,8 +2609,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
* Check for and umount subtree offsets resulting from
* nonstrict mount fail.
*/
- oe_base = oe->key + strlen(root);
- left += do_umount_multi_triggers(ap, oe, root, oe_base);
+ oe_base = oe->key + start;
+ left += do_umount_multi_triggers(ap, oe, root, start, oe_base);
/*
* If an offset that has an active mount has been removed
@@ -2712,7 +2714,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
goto cont;
if (oe->age != me->multi->age) {
/* Best effort */
- do_umount_offset(ap, oe, root);
+ do_umount_offset(ap, oe, root, start);
goto cont;
}
@@ -2726,7 +2728,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
if (oe->ioctlfd != -1 ||
is_mounted(oe->key, MNTS_REAL))
- mount_multi_triggers(ap, oe, key, strlen(key), base);
+ mount_multi_triggers(ap, oe, key, key_len, base);
}
cont:
offset = cache_get_offset(base,
@@ -2738,9 +2740,11 @@ cont:
int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
{
- int left;
+ int left, start;
+
+ start = strlen(root);
- left = do_umount_multi_triggers(ap, me, root, base);
+ left = do_umount_multi_triggers(ap, me, root, start, base);
if (!left && me->multi == me) {
/*
@@ -2753,7 +2757,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
info(ap->logopt, "unmounting dir = %s", root);
if (umount_ent(ap, root) &&
is_mounted(root, MNTS_REAL)) {
- if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0)
+ if (mount_multi_triggers(ap, me, root, start, "/") < 0)
warn(ap->logopt,
"failed to remount offset triggers");
return ++left;

View File

@ -0,0 +1,48 @@
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(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -68,6 +68,7 @@
- add ext_mount_hash_mutex lock helpers.
- fix dangling symlink creation if nis support is not available.
- fix amd section mounts map reload.
+- fix amd hosts mount expire.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/modules/parse_amd.c
+++ autofs-5.1.7/modules/parse_amd.c
@@ -2341,12 +2341,13 @@ int parse_mount(struct autofs_point *ap,
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 */

View File

@ -0,0 +1,120 @@
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(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -67,6 +67,7 @@
- cater for empty mounts list in mnts_get_expire_list().
- add ext_mount_hash_mutex lock helpers.
- fix dangling symlink creation if nis support is not available.
+- fix amd section mounts map reload.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/daemon/master.c
+++ autofs-5.1.7/daemon/master.c
@@ -882,6 +882,83 @@ struct master *master_new(const char *na
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
* 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);

View File

@ -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);

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -77,6 +77,7 @@
- fix lookup_prune_one_cache() refactoring change.
- add missing description of null map option.
- fix nonstrict offset mount fail handling.
+- fix concat_options() error handling.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/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;
}
@@ -989,14 +996,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;
@@ -1358,16 +1364,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;
@@ -1387,15 +1389,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,35 @@
autofs-5.1.7 - fix dangling 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(+)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/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 dangling symlink creation if nis support is not available.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/modules/Makefile
+++ autofs-5.1.7/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

View File

@ -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)

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -73,6 +73,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.
--- autofs-5.1.7.orig/daemon/direct.c
+++ autofs-5.1.7/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.7.orig/daemon/state.c
+++ autofs-5.1.7/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 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;
@@ -406,14 +407,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)
@@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -72,6 +72,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.
--- autofs-5.1.7.orig/include/automount.h
+++ autofs-5.1.7/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.7.orig/include/mounts.h
+++ autofs-5.1.7/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.7.orig/include/rpc_subs.h
+++ autofs-5.1.7/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.7.orig/lib/mounts.c
+++ autofs-5.1.7/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.7.orig/modules/lookup_hosts.c
+++ autofs-5.1.7/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,251 @@
autofs-5.1.7 - fix inconsistent locking in parse_mount()
From: Ian Kent <raven@themaw.net>
Some map entry cache locking inconsistencies have crept in.
In parse_mount() of the sun format parser the cache read lock is too
heavily used and has too broad a scope. This has lead to some operations
that should hold the write lock being called with only the read lock.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 9 ++++++++-
modules/parse_sun.c | 53 ++++++++++++++++++++++++++++++++-------------------
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c60a9ed3..d25b19c8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@
- fix inconsistent locking in umount_subtree_mounts().
- fix return from umount_subtree_mounts() on offset list delete.
- pass mapent_cache to update_offset_entry().
+- fix inconsistent locking in parse_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 5ebfe5fd..0fcd4087 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2491,6 +2491,12 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
else {
debug(ap->logopt, "ignoring \"nohide\" trigger %s",
oe->key);
+ /*
+ * Ok, so we shouldn't modify the mapent but
+ * mount requests are blocked at a point above
+ * this and expire only uses the mapent key or
+ * holds the cache write lock.
+ */
free(oe->mapent);
oe->mapent = NULL;
}
@@ -2634,7 +2640,8 @@ static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const ch
/*
* Ok, so we shouldn't modify the mapent but
* mount requests are blocked at a point above
- * this and expire only uses the mapent key.
+ * this and expire only uses the mapent key or
+ * holds the cache write lock.
*/
if (oe->mapent) {
free(oe->mapent);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 95251bee..a6630a76 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -851,10 +851,12 @@ update_offset_entry(struct autofs_point *ap,
strcpy(m_mapent, loc);
}
+ cache_writelock(mc);
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
if (!cache_set_offset_parent(mc, m_key))
error(ap->logopt, "failed to set offset parent");
+ cache_unlock(mc);
if (ret == CHE_DUPLICATE) {
warn(ap->logopt, MODPREFIX
@@ -1128,14 +1130,22 @@ static void cleanup_multi_triggers(struct autofs_point *ap,
return;
}
-static int mount_subtree(struct autofs_point *ap, struct mapent *me,
+static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
const char *name, char *loc, char *options, void *ctxt)
{
+ struct mapent *me;
struct mapent *ro;
char *mm_root, *mm_base, *mm_key;
unsigned int mm_root_len;
int start, ret = 0, rv;
+ cache_readlock(mc);
+ me = cache_lookup_distinct(mc, name);
+ if (!me) {
+ cache_unlock(mc);
+ return 0;
+ }
+
rv = 0;
mm_key = me->multi->key;
@@ -1180,9 +1190,12 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
rv = parse_mapent(ro->mapent,
options, &myoptions, &ro_loc, ap->logopt);
if (!rv) {
+ cache_unlock(mc);
warn(ap->logopt,
MODPREFIX "failed to parse root offset");
- cache_delete_offset_list(me->mc, name);
+ cache_writelock(mc);
+ cache_delete_offset_list(mc, name);
+ cache_unlock(mc);
return 1;
}
ro_len = 0;
@@ -1199,9 +1212,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
if ((ro && rv == 0) || rv <= 0) {
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+ cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
return 1;
}
}
@@ -1217,9 +1231,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
if (rv == 0) {
ret = mount_multi_triggers(ap, me->multi, name, start, mm_base);
if (ret == -1) {
+ cleanup_multi_triggers(ap, me, name, start, mm_base);
+ cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, name, start, mm_base);
return 1;
}
} else if (rv < 0) {
@@ -1227,8 +1242,11 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1;
if (mm_root_base_len > PATH_MAX) {
+ cache_unlock(mc);
warn(ap->logopt, MODPREFIX "path too long");
- cache_delete_offset_list(me->mc, name);
+ cache_writelock(mc);
+ cache_delete_offset_list(mc, name);
+ cache_unlock(mc);
return 1;
}
@@ -1237,13 +1255,15 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base);
if (ret == -1) {
+ cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+ cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
return 1;
}
}
}
+ cache_unlock(mc);
/* Mount for base of tree failed */
if (rv > 0)
@@ -1484,7 +1504,6 @@ dont_expand:
return 1;
}
- cache_multi_writelock(me);
/* So we know we're the multi-mount root */
if (!me->multi)
me->multi = me;
@@ -1509,14 +1528,13 @@ dont_expand:
if (source->flags & MAP_FLAG_FORMAT_AMD) {
free(options);
free(pmapent);
- cache_multi_unlock(me);
cache_unlock(mc);
pthread_setcancelstate(cur_state, NULL);
return 0;
}
}
-
age = me->age;
+ cache_unlock(mc);
/* It's a multi-mount; deal with it */
do {
@@ -1537,8 +1555,8 @@ dont_expand:
if (!path) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
+ cache_writelock(mc);
cache_delete_offset_list(mc, name);
- cache_multi_unlock(me);
cache_unlock(mc);
free(options);
free(pmapent);
@@ -1554,8 +1572,8 @@ dont_expand:
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
if (!l) {
+ cache_writelock(mc);
cache_delete_offset_list(mc, name);
- cache_multi_unlock(me);
cache_unlock(mc);
free(path);
free(options);
@@ -1573,8 +1591,8 @@ dont_expand:
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
+ cache_writelock(mc);
cache_delete_offset_list(mc, name);
- cache_multi_unlock(me);
cache_unlock(mc);
free(path);
free(options);
@@ -1592,10 +1610,7 @@ dont_expand:
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
- rv = mount_subtree(ap, me, name, NULL, options, ctxt);
-
- cache_multi_unlock(me);
- cache_unlock(mc);
+ rv = mount_subtree(ap, mc, name, NULL, options, ctxt);
free(options);
free(pmapent);
@@ -1616,6 +1631,7 @@ dont_expand:
cache_readlock(mc);
if (*name == '/' &&
(me = cache_lookup_distinct(mc, name)) && me->multi) {
+ cache_unlock(mc);
loc = strdup(p);
if (!loc) {
free(options);
@@ -1624,10 +1640,7 @@ dont_expand:
warn(ap->logopt, MODPREFIX "out of memory");
return 1;
}
- cache_multi_writelock(me);
- rv = mount_subtree(ap, me, name, loc, options, ctxt);
- cache_multi_unlock(me);
- cache_unlock(mc);
+ rv = mount_subtree(ap, mc, name, loc, options, ctxt);
free(loc);
free(options);
free(pmapent);

View File

@ -0,0 +1,135 @@
autofs-5.1.7 - fix inconsistent locking in umount_subtree_mounts()
From: Ian Kent <raven@themaw.net>
Some map entry cache locking inconsistencies have crept in.
In umount_subtree_mounts() the cache write lock should be held when
deleting multi-mount cache entries.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 42 ++++++++++++++++++++++++++++++------------
lib/mounts.c | 8 --------
3 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1dded118..64e619ec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,7 @@
- eliminate clean_stale_multi_triggers().
- simplify mount_subtree() mount check.
- fix mnts_get_expire_list() expire list construction.
+- fix inconsistent locking 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 7fa92877..93bd8556 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -527,8 +527,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
struct mapent_cache *mc;
struct mapent *me;
unsigned int is_mm_root = 0;
+ int cur_state;
int left;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
+
me = lookup_source_mapent(ap, path, LKP_DISTINCT);
if (!me) {
char *ind_key;
@@ -548,11 +551,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
left = 0;
if (me && me->multi) {
- char root[PATH_MAX];
+ char root[PATH_MAX + 1];
+ char key[PATH_MAX + 1];
+ struct mapent *tmp;
+ int status;
char *base;
- int cur_state;
-
- pthread_cleanup_push(cache_lock_cleanup, mc);
if (!strchr(me->multi->key, '/'))
/* Indirect multi-mount root */
@@ -567,25 +570,40 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
else
base = me->key + strlen(root);
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
- /* Lock the closest parent nesting point for umount */
- cache_multi_writelock(me->parent);
- if (umount_multi_triggers(ap, me, root, base)) {
+ left = umount_multi_triggers(ap, me, root, base);
+ if (left) {
warn(ap->logopt,
"some offset mounts still present under %s", path);
+ }
+
+ strcpy(key, me->key);
+
+ cache_unlock(mc);
+ cache_writelock(mc);
+ tmp = cache_lookup_distinct(mc, key);
+ /* mapent went away while we waited? */
+ if (tmp != me) {
+ cache_unlock(mc);
+ pthread_setcancelstate(cur_state, NULL);
+ return 0;
+ }
+
+ if (!left && is_mm_root) {
+ status = cache_delete_offset_list(mc, me->key);
+ if (status != CHE_OK)
+ warn(ap->logopt, "couldn't delete offset list");
left++;
}
- cache_multi_unlock(me->parent);
+
if (ap->entry->maps &&
(ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD))
cache_pop_mapent(me);
- pthread_setcancelstate(cur_state, NULL);
- pthread_cleanup_pop(0);
}
-
if (me)
cache_unlock(mc);
+ pthread_setcancelstate(cur_state, NULL);
+
if (left || is_autofs_fs)
return left;
diff --git a/lib/mounts.c b/lib/mounts.c
index 87813b16..5ebfe5fd 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2736,9 +2736,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
left = do_umount_multi_triggers(ap, me, root, base);
if (!left && me->multi == me) {
- struct mapent_cache *mc = me->mc;
- int status;
-
/*
* Special case.
* If we can't umount the root container then we can't
@@ -2756,11 +2753,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
}
}
- /* We're done - clean out the offsets */
- status = cache_delete_offset_list(mc, me->key);
- if (status != CHE_OK)
- warn(ap->logopt, "couldn't delete offset list");
-
/* check for mounted mount entry and remove it if found */
mnts_remove_mount(root, MNTS_MOUNTED);
}

View File

@ -0,0 +1,64 @@
autofs-5.1.7 - fix is mounted check on non existent path
From: Ian Kent <raven@themaw.net>
When checking if a path is a mount point the case of a non-existent path
was not being handled.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/dev-ioctl-lib.c | 3 +++
lib/mounts.c | 12 +++++++++++-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 484bd866..e55fd66a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
- fix mnts_remove_amdmount() uses wrong list.
- Fix option for master read wait.
- eliminate cache_lookup_offset() usage.
+- fix is mounted check on non existent path.
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 e8519236..7040c3da 100644
--- a/lib/dev-ioctl-lib.c
+++ b/lib/dev-ioctl-lib.c
@@ -759,6 +759,9 @@ static int dev_ioctl_ismountpoint(unsigned int logopt,
int save_errno = errno;
free_dev_ioctl_path(param);
errno = save_errno;
+ /* Path doesn't exist */
+ if (errno == ENOENT)
+ return 0;
return -1;
}
diff --git a/lib/mounts.c b/lib/mounts.c
index 42e8ef07..fe931b20 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1649,8 +1649,18 @@ static int table_is_mounted(const char *mp, unsigned int type)
struct mntent mnt_wrk;
char buf[PATH_MAX * 3];
size_t mp_len = strlen(mp);
+ struct stat st;
FILE *tab;
- int ret = 0;
+ int ret;
+
+ ret = stat(mp, &st);
+ if (ret == -1) {
+ if (errno == ENOENT) {
+ /* Path does not exist */
+ return 0;
+ }
+ ret = 0;
+ }
if (!mp || !mp_len || mp_len >= PATH_MAX)
return 0;

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -74,6 +74,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.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/daemon/lookup.c
+++ autofs-5.1.7/daemon/lookup.c
@@ -1379,6 +1379,7 @@ void lookup_prune_one_cache(struct autof
if (!key || strchr(key, '*')) {
if (key)
free(key);
+ me = cache_enumerate(mc, me);
continue;
}
@@ -1386,6 +1387,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;
}
@@ -1413,9 +1415,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,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] = '/';

View File

@ -0,0 +1,40 @@
autofs-5.1.7 - fix mnts_get_expire_list() expire list construction
From: Ian Kent <raven@themaw.net>
The mnts_get_expire_list() function is supposed to return an ordered
list of expire candidates but it is not checking the mounted status
of list entries and is returning a larger list than is needed.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index f5c5641a..1dded118 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,7 @@
- refactor umount_multi_triggers().
- eliminate clean_stale_multi_triggers().
- simplify mount_subtree() mount check.
+- fix mnts_get_expire_list() expire list construction.
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 a9abbebf..87813b16 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1364,6 +1364,9 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
list_for_each_entry(mnt, &ap->mounts, mount) {
struct node *n;
+ if (!(mnt->flags & MNTS_MOUNTED))
+ continue;
+
__mnts_get_mount(mnt);
if (!tree) {

View File

@ -0,0 +1,38 @@
autofs-5.1.7 - fix mnts_remove_amdmount() uses wrong list
From: Ian Kent <raven@themaw.net>
Function mnts_remove_amdmount() uses the wrong list when removing an
amd mount.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index d613e5ca..fe49740e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
- remove mount.x and rpcgen dependencies.
- dont use realloc in host exports list processing.
- use sprintf() when constructing hosts mapent.
+- fix mnts_remove_amdmount() uses wrong 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 dbeb77b5..ccbd52e0 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1124,7 +1124,7 @@ void mnts_remove_amdmount(const char *mp)
if (!(this && this->flags & MNTS_AMD_MOUNT))
goto done;
this->flags &= ~MNTS_AMD_MOUNT;
- list_del_init(&this->submount);
+ list_del_init(&this->amdmount);
if (this->ext_mp) {
free(this->ext_mp);
this->ext_mp = NULL;

View File

@ -0,0 +1,67 @@
autofs-5.1.7 - fix mount_fullpath()
From: Ian Kent <raven@themaw.net>
mount_fullpath() incorrecly fills fullpath with the contents of root
when name[0] == '/'. The cases root[last] == '/' and name[0] == '/'
need to be handled seperately.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 4 +++-
modules/parse_amd.c | 6 ++++--
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 390028ac..e2fd532c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -36,6 +36,7 @@
- add tree_mapent_add_node().
- add tree_mapent_delete_offsets().
- add tree_mapent_traverse_subtree().
+- fix mount_fullpath().
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 fded4c09..497c28c9 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -371,8 +371,10 @@ int mount_fullpath(char *fullpath, size_t max_len,
/* Root offset of multi-mount or direct or offset mount.
* Direct or offset mount, name (or root) is absolute path.
*/
- if (root[last] == '/' || *name == '/')
+ if (root[last] == '/')
len = snprintf(fullpath, max_len, "%s", root);
+ else if (*name == '/')
+ len = snprintf(fullpath, max_len, "%s", name);
else
len = snprintf(fullpath, max_len, "%s/%s", root, name);
diff --git a/modules/parse_amd.c b/modules/parse_amd.c
index 5a9079d6..64c1ce63 100644
--- a/modules/parse_amd.c
+++ b/modules/parse_amd.c
@@ -1177,7 +1177,8 @@ static int do_generic_mount(struct autofs_point *ap, const char *name,
* the automount filesystem.
*/
if (!is_mounted(entry->fs, MNTS_REAL)) {
- ret = do_mount(ap, entry->fs, "/", 1,
+ ret = do_mount(ap, entry->fs,
+ entry->fs, strlen(entry->fs),
target, entry->type, opts);
if (ret)
goto out;
@@ -1227,7 +1228,8 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name,
mount_nfs->context);
} else {
if (!is_mounted(entry->fs, MNTS_REAL)) {
- ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1,
+ ret = mount_nfs->mount_mount(ap, entry->fs,
+ entry->fs, strlen(entry->fs),
target, entry->type, opts,
mount_nfs->context);
if (ret)

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -76,6 +76,7 @@
- fix direct mount deadlock.
- fix lookup_prune_one_cache() refactoring change.
- 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.
--- autofs-5.1.7.orig/lib/mounts.c
+++ autofs-5.1.7/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.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/modules/parse_sun.c
@@ -1181,7 +1181,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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -69,6 +69,7 @@
- fix dangling symlink creation if nis support is not available.
- fix amd section mounts map reload.
- fix amd hosts mount expire.
+- fix offset entries order.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/include/automount.h
+++ autofs-5.1.7/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.7.orig/lib/cache.c
+++ autofs-5.1.7/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.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/modules/parse_sun.c
@@ -789,14 +789,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);
@@ -862,8 +863,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) {
@@ -1209,6 +1231,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] ...
@@ -1228,7 +1269,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;
@@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -0,0 +1,44 @@
autofs-5.1.7 - fix return from umount_subtree_mounts() on offset list delete
From: Ian Kent <raven@themaw.net>
When there are no mounts left in a subtree of offset mounts the offset
list is deleted. If all goes well deleting the list this shouldn't cause
a positive return from umount_subtree_mounts() (essentially saying that
the umount of the subtree has not succeeded).
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 64e619ec..6e0edd74 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
- simplify mount_subtree() mount check.
- fix mnts_get_expire_list() expire list construction.
- fix inconsistent locking in umount_subtree_mounts().
+- fix return from umount_subtree_mounts() on offset list delete.
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 93bd8556..62530b6b 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -590,9 +590,10 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
if (!left && is_mm_root) {
status = cache_delete_offset_list(mc, me->key);
- if (status != CHE_OK)
+ if (status != CHE_OK) {
warn(ap->logopt, "couldn't delete offset list");
- left++;
+ left++;
+ }
}
if (ap->entry->maps &&

View File

@ -0,0 +1,352 @@
autofs-5.1.7 - make tree implementation data independent
From: Ian Kent <raven@themaw.net>
Generalise the tree implementation so that it's independent of the
data structure that's used.
Do this by refactoring it into core tree functions and functions
specific to the data structure to be used so that different data
structures can be used when needed by adding an implementation for
the data structure specific functions.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/mounts.h | 29 +++++++++
lib/mounts.c | 174 ++++++++++++++++++++++++++++++++++--------------------
3 files changed, 140 insertions(+), 64 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 0dae6761..74571570 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,6 +31,7 @@
- add some multi-mount macros.
- remove unused functions cache_dump_multi() and cache_dump_cache().
- add a len field to struct autofs_point.
+- make tree implementation data independent.
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 ac480c06..71d29566 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -51,10 +51,36 @@ extern const unsigned int t_indirect;
extern const unsigned int t_direct;
extern const unsigned int t_offset;
+struct mnt_list;
struct mapent;
+struct tree_ops;
+
+struct tree_node {
+ struct tree_ops *ops;
+ struct tree_node *left;
+ struct tree_node *right;
+};
+#define INIT_TREE_NODE(ptr) ((ptr)->ops = NULL, (ptr)->left = NULL, (ptr)->right = NULL)
+
+#define MNT_LIST(n) (container_of(n, struct mnt_list, node))
+#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node)
+
+typedef struct tree_node *(*tree_new_t) (void *ptr);
+typedef int (*tree_cmp_t) (struct tree_node *n, void *ptr);
+typedef void (*tree_free_t) (struct tree_node *n);
+
+struct tree_ops {
+ tree_new_t new;
+ tree_cmp_t cmp;
+ tree_free_t free;
+};
+
+typedef int (*tree_work_fn_t) (struct tree_node *n, void *ptr);
+
struct mnt_list {
char *mp;
+ size_t len;
unsigned int flags;
/* Hash of all mounts */
@@ -79,6 +105,9 @@ struct mnt_list {
unsigned int amd_cache_opts;
struct list_head amdmount;
+ /* Tree operations */
+ struct tree_node node;
+
/*
* List operations ie. get_mnt_list.
*/
diff --git a/lib/mounts.c b/lib/mounts.c
index b478ecb4..a6d1c5a7 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -68,6 +68,17 @@ static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
static DEFINE_HASHTABLE(mnts_hash, MNTS_HASH_BITS);
static pthread_mutex_t mnts_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+static struct tree_node *tree_mnt_new(void *ptr);
+static int tree_mnt_cmp(struct tree_node *n, void *ptr);
+static void tree_mnt_free(struct tree_node *n);
+
+static struct tree_ops mnt_ops = {
+ .new = tree_mnt_new,
+ .cmp = tree_mnt_cmp,
+ .free = tree_mnt_free,
+};
+static struct tree_ops *tree_mnt_ops = &mnt_ops;
+
unsigned int linux_version_code(void)
{
struct utsname my_utsname;
@@ -904,6 +915,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp)
this = NULL;
goto done;
}
+ this->len = strlen(mp);
this->ref = 1;
INIT_HLIST_NODE(&this->hash);
@@ -912,6 +924,7 @@ static struct mnt_list *mnts_alloc_mount(const char *mp)
INIT_LIST_HEAD(&this->submount_work);
INIT_LIST_HEAD(&this->amdmount);
INIT_LIST_HEAD(&this->expire);
+ INIT_TREE_NODE(&this->node);
done:
return this;
}
@@ -1225,91 +1238,58 @@ done:
return has_mounted_mounts;
}
-struct tree_node {
- struct mnt_list *mnt;
- struct tree_node *left;
- struct tree_node *right;
-};
-
-static struct tree_node *tree_new(struct mnt_list *mnt)
+static inline struct tree_node *tree_root(struct tree_ops *ops, void *ptr)
{
- struct tree_node *n;
-
- n = malloc(sizeof(struct tree_node));
- if (!n)
- return NULL;
- memset(n, 0, sizeof(struct tree_node));
- n->mnt = mnt;
-
- return n;
-}
-
-static struct tree_node *tree_root(struct mnt_list *mnt)
-{
- struct tree_node *n;
-
- n = tree_new(mnt);
- if (!n) {
- error(LOGOPT_ANY, "failed to allcate tree root");
- return NULL;
- }
-
- return n;
+ return ops->new(ptr);
}
-static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt)
+static struct tree_node *tree_add_left(struct tree_node *n, void *ptr)
{
struct tree_node *new;
- new = tree_new(mnt);
- if (!new) {
- error(LOGOPT_ANY, "failed to allcate tree node");
- return NULL;
- }
+ new = n->ops->new(ptr);
n->left = new;
- return n;
+ return new;
}
-static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt)
+static struct tree_node *tree_add_right(struct tree_node *n, void *ptr)
{
struct tree_node *new;
- new = tree_new(mnt);
- if (!new) {
- error(LOGOPT_ANY, "failed to allcate tree node");
- return NULL;
- }
+ new = n->ops->new(ptr);
n->right = new;
- return n;
+ return new;
}
-static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt)
+static struct tree_node *tree_add_node(struct tree_node *root, void *ptr)
{
struct tree_node *p, *q;
- unsigned int mp_len;
-
- mp_len = strlen(mnt->mp);
+ struct tree_ops *ops = root->ops;
+ int eq;
q = root;
p = root;
- while (q && strcmp(mnt->mp, p->mnt->mp)) {
+ while (q) {
p = q;
- if (mp_len < strlen(p->mnt->mp))
+ eq = ops->cmp(p, ptr);
+ if (!eq)
+ break;
+ if (eq < 0)
q = p->left;
else
q = p->right;
}
- if (strcmp(mnt->mp, p->mnt->mp) == 0)
- error(LOGOPT_ANY, "duplicate entry in mounts list");
+ if (!eq)
+ error(LOGOPT_ANY, "cannot add duplicate entry to tree");
else {
- if (mp_len < strlen(p->mnt->mp))
- return tree_add_left(p, mnt);
+ if (eq < 0)
+ return tree_add_left(p, ptr);
else
- return tree_add_right(p, mnt);
+ return tree_add_right(p, ptr);
}
return NULL;
@@ -1317,26 +1297,92 @@ static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *
static void tree_free(struct tree_node *root)
{
+ struct tree_ops *ops = root->ops;
+
if (root->right)
tree_free(root->right);
if (root->left)
tree_free(root->left);
- free(root);
+ ops->free(root);
}
-static void tree_traverse(struct tree_node *n, struct list_head *mnts)
+static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
{
- if (n->right)
- tree_traverse(n->right, mnts);
- list_add_tail(&n->mnt->expire, mnts);
- if (n->left)
- tree_traverse(n->left, mnts);
+ int ret;
+
+ if (n->left) {
+ ret = tree_traverse_inorder(n->left, work, ptr);
+ if (!ret)
+ goto done;
+ }
+ ret = work(n, ptr);
+ if (!ret)
+ goto done;
+ if (n->right) {
+ ret = tree_traverse_inorder(n->right, work, ptr);
+ if (!ret)
+ goto done;
+ }
+done:
+ return ret;
+}
+
+static struct tree_node *tree_mnt_root(struct mnt_list *mnt)
+{
+ return tree_root(tree_mnt_ops, mnt);
+}
+
+static struct tree_node *tree_mnt_new(void *ptr)
+{
+ struct tree_node *n = MNT_LIST_NODE(ptr);
+
+ n->ops = tree_mnt_ops;
+ n->left = NULL;
+ n->right = NULL;
+
+ return n;
+}
+
+static int tree_mnt_cmp(struct tree_node *n, void *ptr)
+{
+ struct mnt_list *n_mnt = MNT_LIST(n);
+ size_t n_mnt_len = n_mnt->len;
+ struct mnt_list *mnt = ptr;
+ size_t mnt_len = mnt->len;
+ int eq;
+
+ eq = strcmp(mnt->mp, n_mnt->mp);
+ if (!eq)
+ return 0;
+ return (mnt_len < n_mnt_len) ? -1 : 1;
+}
+
+static void tree_mnt_free(struct tree_node *n)
+{
+ n->ops = NULL;
+ n->left = NULL;
+ n->right = NULL;
+}
+
+static int tree_mnt_expire_list_work(struct tree_node *n, void *ptr)
+{
+ struct mnt_list *mnt = MNT_LIST(n);
+ struct list_head *mnts = ptr;
+
+ /* The expire of the root offset of an offset tree is the same
+ * as expiring the offset tree root itself (if theree is a root
+ * offset).
+ */
+ if (mnt->mp[mnt->len - 1] != '/')
+ list_add(&mnt->expire, mnts);
+
+ return 1;
}
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
{
- struct mnt_list *mnt;
struct tree_node *tree = NULL;
+ struct mnt_list *mnt;
mnts_hash_mutex_lock();
if (list_empty(&ap->mounts))
@@ -1351,7 +1397,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
__mnts_get_mount(mnt);
if (!tree) {
- tree = tree_root(mnt);
+ tree = tree_mnt_root(mnt);
if (!tree) {
error(LOGOPT_ANY, "failed to create expire tree root");
goto done;
@@ -1367,7 +1413,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
}
}
- tree_traverse(tree, mnts);
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
tree_free(tree);
done:
mnts_hash_mutex_unlock();

View File

@ -0,0 +1,118 @@
autofs-5.1.7 - move amd mounts removal into lib/mounts.c
From: Ian Kent <raven@themaw.net>
Move the amd mounts removal from master_free_autofs_point() into
lib/mounts.c along with the rest of the amd mount handling.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 12 +-----------
include/mounts.h | 1 +
lib/mounts.c | 28 ++++++++++++++++++++++++----
4 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 002da042..a9209755 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -46,6 +46,7 @@
- use mount_fullpath() in one spot in parse_mount().
- pass root length to mount_fullpath().
- remove unused function master_submount_list_empty().
+- move amd mounts removal into lib/mounts.c.
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 af9cd79f..b288e070 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -143,22 +143,12 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
void master_free_autofs_point(struct autofs_point *ap)
{
- struct list_head *p, *head;
int status;
if (!ap)
return;
- mounts_mutex_lock(ap);
- head = &ap->amdmounts;
- p = head->next;
- while (p != head) {
- struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
- p = p->next;
- ext_mount_remove(mnt->ext_mp);
- mnts_remove_amdmount(mnt->mp);
- }
- mounts_mutex_unlock(ap);
+ mnts_remove_amdmounts(ap);
status = pthread_mutex_destroy(&ap->mounts_mutex);
if (status)
diff --git a/include/mounts.h b/include/mounts.h
index d7980976..1b376b3d 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -161,6 +161,7 @@ void mnts_remove_submount(const char *mp);
struct mnt_list *mnts_find_amdmount(const char *path);
struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *entry);
void mnts_remove_amdmount(const char *mp);
+void mnts_remove_amdmounts(struct autofs_point *ap);
struct mnt_list *mnts_add_mount(struct autofs_point *ap, const char *name, unsigned int flags);
void mnts_remove_mount(const char *mp, unsigned int flags);
struct mnt_list *get_mnt_list(const char *path, int include);
diff --git a/lib/mounts.c b/lib/mounts.c
index 6b8e4c92..c8a7bf00 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1144,14 +1144,13 @@ fail:
return NULL;
}
-void mnts_remove_amdmount(const char *mp)
+static void __mnts_remove_amdmount(const char *mp)
{
struct mnt_list *this;
- mnts_hash_mutex_lock();
this = mnts_lookup(mp);
if (!(this && this->flags & MNTS_AMD_MOUNT))
- goto done;
+ return;
this->flags &= ~MNTS_AMD_MOUNT;
list_del_init(&this->amdmount);
if (this->ext_mp) {
@@ -1172,7 +1171,28 @@ void mnts_remove_amdmount(const char *mp)
}
this->amd_cache_opts = 0;
__mnts_put_mount(this);
-done:
+}
+
+void mnts_remove_amdmount(const char *mp)
+{
+ mnts_hash_mutex_lock();
+ __mnts_remove_amdmount(mp);
+ mnts_hash_mutex_unlock();
+}
+
+void mnts_remove_amdmounts(struct autofs_point *ap)
+{
+ struct list_head *head, *p;
+
+ mnts_hash_mutex_lock();
+ head = &ap->amdmounts;
+ p = head->next;
+ while (p != head) {
+ struct mnt_list *mnt = list_entry(p, struct mnt_list, amdmount);
+ p = p->next;
+ ext_mount_remove(mnt->ext_mp);
+ __mnts_remove_amdmount(mnt->mp);
+ }
mnts_hash_mutex_unlock();
}

View File

@ -0,0 +1,72 @@
autofs-5.1.7 - pass mapent_cache to update_offset_entry()
From: Ian Kent <raven@themaw.net>
Pass mapent_cache to update_offset_entry() rather than use the wait/signal
mechanism, it isn't needed here.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 22 ++++++----------------
2 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 6e0edd74..c60a9ed3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@
- fix mnts_get_expire_list() expire list construction.
- fix inconsistent locking in umount_subtree_mounts().
- fix return from umount_subtree_mounts() on offset list delete.
+- pass mapent_cache to update_offset_entry().
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 1142e8a3..95251bee 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -793,24 +793,17 @@ static int check_is_multi(const char *mapent)
}
static int
-update_offset_entry(struct autofs_point *ap, const char *name,
+update_offset_entry(struct autofs_point *ap,
+ struct mapent_cache *mc, const char *name,
const char *m_root, int m_root_len,
- const char *path, const char *myoptions, const char *loc,
- time_t age)
+ const char *path, const char *myoptions,
+ const char *loc, time_t age)
{
- struct map_source *source;
- struct mapent_cache *mc;
char m_key[PATH_MAX + 1];
char m_mapent[MAPENT_MAX_LEN + 1];
int p_len, m_key_len, m_options_len, m_mapent_len;
int ret;
- source = ap->entry->current;
- ap->entry->current = NULL;
- master_source_current_signal(ap->entry);
-
- mc = source->mc;
-
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
/* Internal hosts map may have loc == NULL */
@@ -1574,11 +1567,8 @@ dont_expand:
p += l;
p = skipspace(p);
- master_source_current_wait(ap->entry);
- ap->entry->current = source;
-
- status = update_offset_entry(ap, name,
- m_root, m_root_len,
+ status = update_offset_entry(ap, mc,
+ name, m_root, m_root_len,
path, myoptions, loc, age);
if (status != CHE_OK) {

View File

@ -0,0 +1,171 @@
autofs-5.1.7 - pass root length to mount_fullpath()
From: Ian Kent <raven@themaw.net>
The length of root may already be known, add a parameter to allow
passing it to mount_fullpath() so a strlen() call can be avoided.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/mounts.h | 2 +-
lib/mounts.c | 11 +++++++----
modules/mount_bind.c | 2 +-
modules/mount_changer.c | 2 +-
modules/mount_ext2.c | 2 +-
modules/mount_generic.c | 2 +-
modules/mount_nfs.c | 2 +-
modules/parse_sun.c | 4 ++--
9 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 8494f0dc..1c9e2a2d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -44,6 +44,7 @@
- remove obsolete functions.
- remove redundant local var from sun_mount().
- use mount_fullpath() in one spot in parse_mount().
+- pass root length to mount_fullpath().
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 ec895e1c..d7980976 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -131,7 +131,7 @@ int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *);
extern unsigned int nfs_mount_uses_string_options;
int mount_fullpath(char *fullpath, size_t max_len,
- const char *root, const char *name);
+ const char *root, size_t root_len, const char *name);
struct amd_entry;
diff --git a/lib/mounts.c b/lib/mounts.c
index c120d2a8..6b8e4c92 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -362,11 +362,14 @@ int check_nfs_mount_version(struct nfs_mount_vers *vers,
#endif
int mount_fullpath(char *fullpath, size_t max_len,
- const char *root, const char *name)
+ const char *root, size_t root_len, const char *name)
{
int last, len;
- last = strlen(root) - 1;
+ if (root_len)
+ last = root_len - 1;
+ else
+ last = strlen(root) - 1;
/* Root offset of multi-mount or direct or offset mount.
* Direct or offset mount, name (or root) is absolute path.
@@ -1685,7 +1688,7 @@ void tree_mapent_cleanup_offsets(struct mapent *oe)
else {
char mp[PATH_MAX + 1];
- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key))
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key))
error(ap->logopt, "mount path is too long");
else
tree_mapent_umount_mount(ap, mp);
@@ -1922,7 +1925,7 @@ int tree_mapent_umount_offsets(struct mapent *oe, int nonstrict)
* one of these keys is the root of a multi-mount the mount
* path must be constructed.
*/
- if (!mount_fullpath(mp, PATH_MAX, ap->path, oe->key)) {
+ if (!mount_fullpath(mp, PATH_MAX, ap->path, ap->len, oe->key)) {
error(ap->logopt, "mount path is too long");
return 0;
}
diff --git a/modules/mount_bind.c b/modules/mount_bind.c
index c17c6f18..7f64332b 100644
--- a/modules/mount_bind.c
+++ b/modules/mount_bind.c
@@ -122,7 +122,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
}
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
if (!len) {
error(ap->logopt,
MODPREFIX "mount point path too long");
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
index d02b5f45..8adb9f9a 100644
--- a/modules/mount_changer.c
+++ b/modules/mount_changer.c
@@ -59,7 +59,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
fstype = "iso9660";
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
if (!len) {
error(ap->logopt,
MODPREFIX "mount point path too long");
diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c
index 53e6ee10..f4002e58 100644
--- a/modules/mount_ext2.c
+++ b/modules/mount_ext2.c
@@ -55,7 +55,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
if (defaults_get_mount_verbose())
mountlog = &log_info;
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
if (!len) {
error(ap->logopt,
MODPREFIX "mount point path too long");
diff --git a/modules/mount_generic.c b/modules/mount_generic.c
index c9deb7ae..8cd0f4ab 100644
--- a/modules/mount_generic.c
+++ b/modules/mount_generic.c
@@ -54,7 +54,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
if (defaults_get_mount_verbose())
mountlog = &log_info;
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
if (!len) {
error(ap->logopt,
MODPREFIX "mount point path too long");
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
index c70210f4..0314a78f 100644
--- a/modules/mount_nfs.c
+++ b/modules/mount_nfs.c
@@ -213,7 +213,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
}
/* Construct mount point directory */
- len = mount_fullpath(fullpath, PATH_MAX, root, name);
+ len = mount_fullpath(fullpath, PATH_MAX, root, 0, name);
if (!len) {
error(ap->logopt,
MODPREFIX "mount point path too long");
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index d3fc6c7f..b1c2611c 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1089,7 +1089,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
struct mapent *ro;
size_t len;
- len = mount_fullpath(key, PATH_MAX, ap->path, me->key);
+ len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key);
if (!len) {
warn(ap->logopt, "path loo long");
return 1;
@@ -1359,7 +1359,7 @@ dont_expand:
time_t age;
int l;
- m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name);
+ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, ap->len, name);
if (!m_root_len) {
error(ap->logopt,
MODPREFIX "multi-mount root path too long");

View File

@ -0,0 +1,83 @@
autofs-5.1.7 - reduce umount EBUSY check delay
From: Ian Kent <raven@themaw.net>
Some time ago I had to wait and retry umount() for autofs mounts
becuase I found EBUSY would be returned for a time after the call
causing false negative umount returns.
I think that problem has been resolved but removing the retry is
probably a little risky.
But the wait time is quite long at one fifth of a second so reduce
that to one twentieth of a second and increase the retries to make
it more resposive.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 4 ++--
daemon/indirect.c | 2 +-
include/automount.h | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b144f6aa..6419052d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -23,6 +23,7 @@
- eliminate count_mounts() from expire_proc_indirect().
- eliminate some strlen calls in offset handling.
- don't add offset mounts to mounted mounts table.
+- reduce umount EBUSY check delay.
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 fbfebbdd..5c1146a7 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -150,7 +150,7 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
retries = UMOUNT_RETRIES;
while ((rv = umount(me->key)) == -1 && retries--) {
- struct timespec tm = {0, 200000000};
+ struct timespec tm = {0, 50000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
@@ -573,7 +573,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me)
retries = UMOUNT_RETRIES;
while ((rv = umount(me->key)) == -1 && retries--) {
- struct timespec tm = {0, 200000000};
+ struct timespec tm = {0, 50000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
diff --git a/daemon/indirect.c b/daemon/indirect.c
index eddcfff7..9f2ca6a0 100644
--- a/daemon/indirect.c
+++ b/daemon/indirect.c
@@ -265,7 +265,7 @@ int umount_autofs_indirect(struct autofs_point *ap, const char *root)
retries = UMOUNT_RETRIES;
while ((rv = umount(mountpoint)) == -1 && retries--) {
- struct timespec tm = {0, 200000000};
+ struct timespec tm = {0, 50000000};
if (errno != EBUSY)
break;
nanosleep(&tm, NULL);
diff --git a/include/automount.h b/include/automount.h
index 69445b92..fa6f5d63 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -140,7 +140,7 @@ struct autofs_point;
#define NULL_MAP_HASHSIZE 64
#define NEGATIVE_TIMEOUT 10
#define POSITIVE_TIMEOUT 120
-#define UMOUNT_RETRIES 8
+#define UMOUNT_RETRIES 16
#define EXPIRE_RETRIES 3
struct mapent_cache {

View File

@ -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);
}

View File

@ -0,0 +1,259 @@
autofs-5.1.7 - refactor umount_multi_triggers()
From: Ian Kent <raven@themaw.net>
Refactor umount_multi_triggers() to try the umount of an offset subtree
in a seperate function.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
lib/mounts.c | 187 ++++++++++++++++++++++++++++++++--------------------------
2 files changed, 104 insertions(+), 84 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3eda995c..5a3bedc1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,7 @@
- set offset parent in update_offset_entry().
- remove redundant variables from mount_autofs_offset().
- remove unused parameter form do_mount_autofs_offset().
+- refactor umount_multi_triggers().
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 8e88182f..5268ba5b 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2496,57 +2496,6 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
return mounted;
}
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
- const char *root, unsigned int start, const char *base)
-{
- char path[PATH_MAX + 1];
- char *offset = path;
- struct mapent *oe;
- struct list_head *pos = NULL;
- unsigned int root_len = strlen(root);
- int mounted;
-
- mounted = 0;
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
- while (offset) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- goto cont;
- }
-
- /* The root offset is always mounted seperately so the
- * offset path will always be root + offset.
- */
- strcpy(key, root);
- strcat(key, offset);
-
- oe = cache_lookup_distinct(me->mc, key);
- if (!oe || !oe->mapent)
- goto cont;
-
- mounted += do_mount_autofs_offset(ap, oe, root);
-
- /*
- * If re-constructing a multi-mount it's necessary to walk
- * into nested mounts, unlike the usual "mount only what's
- * needed as you go" behavior.
- */
- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL))
- mount_multi_triggers(ap, oe, key, strlen(key), base);
- }
-cont:
- offset = cache_get_offset(base,
- offset, start, &me->multi_list, &pos);
- }
-
- return mounted;
-}
-
static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
{
char *dir, *path;
@@ -2582,7 +2531,10 @@ static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
return ret;
}
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root);
+
+static int do_umount_multi_triggers(struct autofs_point *ap,
+ struct mapent *me, const char *root, const char *base)
{
char path[PATH_MAX + 1];
char *offset;
@@ -2612,7 +2564,6 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
char key[PATH_MAX + 1];
int key_len = root_len + strlen(offset);
- char *oe_base;
if (mm_base_len > 1)
key_len += mm_base_len;
@@ -2632,47 +2583,116 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
if (!oe || (strlen(oe->key) - start) == 1)
continue;
+ left += do_umount_offset(ap, oe, root);
+ }
+
+ return left;
+}
+
+static int do_umount_offset(struct autofs_point *ap, struct mapent *oe, const char *root)
+{
+ char *oe_base;
+ int left = 0;
+
+ /*
+ * Check for and umount subtree offsets resulting from
+ * nonstrict mount fail.
+ */
+ oe_base = oe->key + strlen(root);
+ left += do_umount_multi_triggers(ap, oe, root, oe_base);
+
+ if (oe->ioctlfd != -1 ||
+ is_mounted(oe->key, MNTS_REAL)) {
+ left++;
+ return left;
+ }
+
+ debug(ap->logopt, "umount offset %s", oe->key);
+
+ if (umount_autofs_offset(ap, oe)) {
+ warn(ap->logopt, "failed to umount offset");
+ left++;
+ } else {
+ struct stat st;
+ int ret;
+
+ if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
+ return left;
+
/*
- * Check for and umount subtree offsets resulting from
- * nonstrict mount fail.
+ * An error due to partial directory removal is
+ * ok so only try and remount the offset if the
+ * actual mount point still exists.
*/
- oe_base = oe->key + strlen(root);
- left += umount_multi_triggers(ap, oe, root, oe_base);
+ ret = rmdir_path_offset(ap, oe);
+ if (ret == -1 && !stat(oe->key, &st)) {
+ ret = do_mount_autofs_offset(ap, oe, root);
+ if (ret)
+ left++;
+ /* But we did origianlly create this */
+ oe->flags |= MOUNT_FLAG_DIR_CREATED;
+ }
+ }
+ return left;
+}
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL)) {
- left++;
- continue;
+int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
+ const char *root, unsigned int start, const char *base)
+{
+ char path[PATH_MAX + 1];
+ char *offset = path;
+ struct mapent *oe;
+ struct list_head *pos = NULL;
+ unsigned int root_len = strlen(root);
+ int mounted;
+
+ mounted = 0;
+ offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
+ while (offset) {
+ char key[PATH_MAX + 1];
+ int key_len = root_len + strlen(offset);
+
+ if (key_len > PATH_MAX) {
+ warn(ap->logopt, "path loo long");
+ goto cont;
}
- debug(ap->logopt, "umount offset %s", oe->key);
+ /* The root offset is always mounted seperately so the
+ * offset path will always be root + offset.
+ */
+ strcpy(key, root);
+ strcat(key, offset);
- if (umount_autofs_offset(ap, oe)) {
- warn(ap->logopt, "failed to umount offset");
- left++;
- } else {
- struct stat st;
- int ret;
+ oe = cache_lookup_distinct(me->mc, key);
+ if (!oe || !oe->mapent)
+ goto cont;
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
- continue;
+ mounted += do_mount_autofs_offset(ap, oe, root);
- /*
- * An error due to partial directory removal is
- * ok so only try and remount the offset if the
- * actual mount point still exists.
- */
- ret = rmdir_path_offset(ap, oe);
- if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root);
- if (ret)
- left++;
- /* But we did origianlly create this */
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
- }
+ /*
+ * If re-constructing a multi-mount it's necessary to walk
+ * into nested mounts, unlike the usual "mount only what's
+ * needed as you go" behavior.
+ */
+ if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
+ if (oe->ioctlfd != -1 ||
+ is_mounted(oe->key, MNTS_REAL))
+ mount_multi_triggers(ap, oe, key, strlen(key), base);
}
+cont:
+ offset = cache_get_offset(base,
+ offset, start, &me->multi_list, &pos);
}
+ return mounted;
+}
+
+int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
+{
+ int left;
+
+ left = do_umount_multi_triggers(ap, me, root, base);
+
if (!left && me->multi == me) {
struct mapent_cache *mc = me->mc;
int status;
@@ -2871,4 +2891,3 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
return left;
}
-

View File

@ -0,0 +1,574 @@
autofs-5.1.7 - remove mount.x and rpcgen dependencies
From: Ian Kent <raven@themaw.net>
Adding a local implementation to get the exports list from a server
means the the rpcgen generataed code is no longer needed so remove
mount.x and the build dependencies.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
Makefile.conf.in | 1
autofs.spec | 2
configure | 58 ---------
configure.in | 1
include/automount.h | 1
include/config.h.in | 3
lib/Makefile | 26 ----
lib/mount.x | 345 ---------------------------------------------------
9 files changed, 5 insertions(+), 433 deletions(-)
delete mode 100644 lib/mount.x
diff --git a/CHANGELOG b/CHANGELOG
index 84050e91..19af245e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
- add xdr_exports().
+- remove mount.x and rpcgen dependencies.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/Makefile.conf.in b/Makefile.conf.in
index df678eec..12f26eb8 100644
--- a/Makefile.conf.in
+++ b/Makefile.conf.in
@@ -65,7 +65,6 @@ FEDFS = @ENABLE_FEDFS@
LEX = @PATH_LEX@
YACC = @PATH_YACC@
-RPCGEN = @PATH_RPCGEN@
RANLIB = @PATH_RANLIB@
# Use libtirpc if requested and available
diff --git a/autofs.spec b/autofs.spec
index 3c2b144a..823735a3 100644
--- a/autofs.spec
+++ b/autofs.spec
@@ -39,7 +39,7 @@ BuildRequires: libtirpc-devel
%endif
BuildRequires: autoconf, openldap-devel, bison, flex, libxml2-devel
BuildRequires: cyrus-sasl-devel, openssl-devel, util-linux
-BuildRequires: libtirpc-devel, rpcgen, libnsl2-devel, krb5-devel
+BuildRequires: libtirpc-devel, libnsl2-devel, krb5-devel
Requires: chkconfig
Requires: /bin/bash sed grep /bin/ps
%if %{with_systemd}
diff --git a/configure b/configure
index de968f0e..3c5fe78b 100755
--- a/configure
+++ b/configure
@@ -650,8 +650,6 @@ XML_CFLAGS
ENABLE_FEDFS
sssldir
HAVE_SSS_AUTOFS
-PATH_RPCGEN
-RPCGEN
PATH_RANLIB
RANLIB
PATH_YACC
@@ -4205,62 +4203,6 @@ else
as_fn_error $? "required program RANLIB not found" "$LINENO" 5
fi
-for ac_prog in rpcgen
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_RPCGEN+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $RPCGEN in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_RPCGEN="$RPCGEN" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $searchpath
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- ;;
-esac
-fi
-RPCGEN=$ac_cv_path_RPCGEN
-if test -n "$RPCGEN"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPCGEN" >&5
-$as_echo "$RPCGEN" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- test -n "$RPCGEN" && break
-done
-
-if test -n "$RPCGEN"; then
-
-cat >>confdefs.h <<_ACEOF
-#define PATH_RPCGEN "$RPCGEN"
-_ACEOF
-
- PATH_RPCGEN="$RPCGEN"
-else
- as_fn_error $? "required program RPCGEN not found" "$LINENO" 5
-fi
-
if test -z "$sssldir"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sssd autofs library" >&5
diff --git a/configure.in b/configure.in
index a38d6655..e774b4cc 100644
--- a/configure.in
+++ b/configure.in
@@ -164,7 +164,6 @@ AF_PATH_INCLUDE(E4FSCK, fsck.ext4 e4fsck, , $searchpath)
AF_CHECK_PROG(LEX, flex lex, , $searchpath)
AF_CHECK_PROG(YACC, bison, , $searchpath)
AF_CHECK_PROG(RANLIB, ranlib, , $searchpath)
-AF_CHECK_PROG(RPCGEN, rpcgen, , $searchpath)
AF_CHECK_SSS_LIB(SSS_AUTOFS, libsss_autofs.so)
AC_SUBST(HAVE_SSS_AUTOFS)
diff --git a/include/automount.h b/include/automount.h
index 1ae40786..2f09e8e7 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -32,7 +32,6 @@
#include "macros.h"
#include "log.h"
#include "rpc_subs.h"
-#include "mounts.h"
#include "parse_subs.h"
#include "mounts.h"
#include "dev-ioctl-lib.h"
diff --git a/include/config.h.in b/include/config.h.in
index a4879494..4e36b390 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -135,9 +135,6 @@
/* define if you have RANLIB */
#undef PATH_RANLIB
-/* define if you have RPCGEN */
-#undef PATH_RPCGEN
-
/* define if you have UMOUNT */
#undef PATH_UMOUNT
diff --git a/lib/Makefile b/lib/Makefile
index 83a80a1e..d18c67b5 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -8,10 +8,9 @@ include ../Makefile.rules
SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \
nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \
parse_subs.c dev-ioctl-lib.c
-RPCS = mount.h mount_clnt.c mount_xdr.c
-OBJS = cache.o mount_clnt.o mount_xdr.o cat_path.o rpc_subs.o \
- mounts.o log.o nsswitch.o nss_tok.o nss_parse.tab.o args.o \
- alarm.o macros.o defaults.o parse_subs.o dev-ioctl-lib.o
+OBJS = cache.o cat_path.o rpc_subs.o mounts.o log.o nsswitch.o \
+ nss_tok.o nss_parse.tab.o args.o alarm.o macros.o defaults.o \
+ parse_subs.o dev-ioctl-lib.o
YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h
@@ -33,23 +32,6 @@ libautofs.so: $(OBJS)
$(CC) $(SOLDFLAGS) $(CFLAGS) -o $*.so $^ $(LDFLAGS) $(LIBS)
$(STRIP) $*.so
-mount.h: mount.x
- $(RPCGEN) -h -o mount.h mount.x
-
-mount_clnt.c: mount.h
- $(RPCGEN) -l -o mount_clnt.c mount.x
-
-mount_clnt.o: mount_clnt.c
- $(CC) $(CFLAGS) -o mount_clnt.o -c mount_clnt.c
- $(STRIP) mount_clnt.o
-
-mount_xdr.c: mount.h
- $(RPCGEN) -c -o mount_xdr.c mount.x
-
-mount_xdr.o: mount_xdr.c
- $(CC) $(CFLAGS) -Wno-unused-variable -o mount_xdr.o -c mount_xdr.c
- $(STRIP) mount_xdr.o
-
nss_tok.c: nss_tok.l
$(LEX) -o$@ -Pnss_ $?
@@ -60,8 +42,6 @@ nss_tok.o: nss_tok.c nss_parse.tab.h
nss_parse.tab.o: nss_parse.tab.c nss_parse.tab.h
-rpc_subs.o: mount.h
-
install: all
install -d -m 755 $(INSTALLROOT)$(autofslibdir)
install -c $(LIB) -m 755 $(INSTALLROOT)$(sharedlibdir)
diff --git a/lib/mount.x b/lib/mount.x
deleted file mode 100644
index f504e7cf..00000000
--- a/lib/mount.x
+++ /dev/null
@@ -1,345 +0,0 @@
-%/*
-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-% * unrestricted use provided that this legend is included on all tape
-% * media and as a part of the software program in whole or part. Users
-% * may copy or modify Sun RPC without charge, but are not authorized
-% * to license or distribute it to anyone else except as part of a product or
-% * program developed by the user or with the express written consent of
-% * Sun Microsystems, Inc.
-% *
-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-% *
-% * Sun RPC is provided with no support and without any obligation on the
-% * part of Sun Microsystems, Inc. to assist in its use, correction,
-% * modification or enhancement.
-% *
-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-% * OR ANY PART THEREOF.
-% *
-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-% * or profits or other special, indirect and consequential damages, even if
-% * Sun has been advised of the possibility of such damages.
-% *
-% * Sun Microsystems, Inc.
-% * 2550 Garcia Avenue
-% * Mountain View, California 94043
-% */
-
-%/*
-% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
-% */
-%
-%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-/*
- * Protocol description for the mount program
- */
-
-#ifdef RPC_HDR
-%#ifndef _rpcsvc_mount_h
-%#define _rpcsvc_mount_h
-%#include <memory.h>
-#endif
-
-const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
-const MNTNAMLEN = 255; /* maximum bytes in a name argument */
-const FHSIZE = 32; /* size in bytes of a file handle */
-
-/*
- * The fhandle is the file handle that the server passes to the client.
- * All file operations are done using the file handles to refer to a file
- * or a directory. The file handle can contain whatever information the
- * server needs to distinguish an individual file.
- */
-typedef opaque fhandle[FHSIZE];
-
-/*
- * If a status of zero is returned, the call completed successfully, and
- * a file handle for the directory follows. A non-zero status indicates
- * some sort of error. The status corresponds with UNIX error numbers.
- */
-union fhstatus switch (unsigned fhs_status) {
-case 0:
- fhandle fhs_fhandle;
-default:
- void;
-};
-
-/*
- * The type dirpath is the pathname of a directory
- */
-typedef string dirpath<MNTPATHLEN>;
-
-/*
- * The type name is used for arbitrary names (hostnames, groupnames)
- */
-typedef string name<MNTNAMLEN>;
-
-/*
- * A list of who has what mounted
- */
-typedef struct mountbody *mountlist;
-struct mountbody {
- name ml_hostname;
- dirpath ml_directory;
- mountlist ml_next;
-};
-
-/*
- * A list of netgroups
- */
-typedef struct groupnode *groups;
-struct groupnode {
- name gr_name;
- groups gr_next;
-};
-
-/*
- * A list of what is exported and to whom
- */
-typedef struct exportnode *exports;
-struct exportnode {
- dirpath ex_dir;
- groups ex_groups;
- exports ex_next;
-};
-
-/*
- * POSIX pathconf information
- */
-struct ppathcnf {
- int pc_link_max; /* max links allowed */
- short pc_max_canon; /* max line len for a tty */
- short pc_max_input; /* input a tty can eat all at once */
- short pc_name_max; /* max file name length (dir entry) */
- short pc_path_max; /* max path name length (/x/y/x/.. ) */
- short pc_pipe_buf; /* size of a pipe (bytes) */
- u_char pc_vdisable; /* safe char to turn off c_cc[i] */
- char pc_xxx; /* alignment padding; cc_t == char */
- short pc_mask[2]; /* validity and boolean bits */
-};
-
-/*
- * NFSv3 file handle
- */
-const FHSIZE3 = 64; /* max size of NFSv3 file handle in bytes */
-typedef opaque fhandle3<FHSIZE3>;
-
-/*
- * NFSv3 mount status
- */
-enum mountstat3 {
- MNT_OK = 0, /* no error */
- MNT3ERR_PERM = 1, /* not owner */
- MNT3ERR_NOENT = 2, /* no such file or directory */
- MNT3ERR_IO = 5, /* I/O error */
- MNT3ERR_ACCES = 13, /* Permission denied */
- MNT3ERR_NOTDIR = 20, /* Not a directory */
- MNT3ERR_INVAL = 22, /* Invalid argument */
- MNT3ERR_NAMETOOLONG = 63, /* File name too long */
- MNT3ERR_NOTSUPP = 10004,/* Operation not supported */
- MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
-};
-
-/*
- * NFSv3 mount result
- */
-struct mountres3_ok {
- fhandle3 fhandle;
- int auth_flavors<>;
-};
-
-union mountres3 switch (mountstat3 fhs_status) {
-case MNT_OK:
- mountres3_ok mountinfo; /* File handle and supported flavors */
-default:
- void;
-};
-
-program MOUNTPROG {
- /*
- * Version one of the mount protocol communicates with version two
- * of the NFS protocol. The only connecting point is the fhandle
- * structure, which is the same for both protocols.
- */
- version MOUNTVERS {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
- } = 1;
-
- /*
- * Version two of the mount protocol communicates with version two
- * of the NFS protocol.
- * The only difference from version one is the addition of a POSIX
- * pathconf call.
- */
- version MOUNTVERS_POSIX {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
-
- /*
- * POSIX pathconf info (Sun hack)
- */
- ppathcnf
- MOUNTPROC_PATHCONF(dirpath) = 7;
- } = 2;
-
- /*
- * Version 3 of the protocol is for NFSv3
- */
- version MOUNTVERS_NFSV3 {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC3_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- mountres3
- MOUNTPROC3_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC3_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC3_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC3_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC3_EXPORT(void) = 5;
- } = 3;
-} = 100005;
-
-#ifdef RPC_HDR
-%#endif /*!_rpcsvc_mount_h*/
-#endif

View File

@ -0,0 +1,178 @@
autofs-5.1.7 - remove mounts_mutex
From: Ian Kent <raven@themaw.net>
The mounts_mutex is no longer used, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 8 +-------
daemon/master.c | 13 -------------
include/automount.h | 1 -
modules/mount_autofs.c | 8 --------
5 files changed, 2 insertions(+), 29 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 42914160..9d0f4278 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -48,6 +48,7 @@
- remove unused function master_submount_list_empty().
- move amd mounts removal into lib/mounts.c.
- check for offset with no mount location.
+- remove mounts_mutex.
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 7833dfae..28c4d1ee 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -1754,7 +1754,6 @@ static void handle_mounts_cleanup(void *arg)
* here.
*/
if (submount) {
- mounts_mutex_unlock(ap->parent);
master_source_unlock(ap->parent->entry);
master_free_mapent_sources(ap->entry, 1);
master_free_mapent(ap->entry);
@@ -1792,13 +1791,9 @@ static int submount_source_writelock_nested(struct autofs_point *ap)
if (status)
goto done;
- mounts_mutex_lock(parent);
-
status = pthread_rwlock_trywrlock(&ap->entry->source_lock);
- if (status) {
- mounts_mutex_unlock(parent);
+ if (status)
master_source_unlock(parent->entry);
- }
done:
if (status && status != EBUSY) {
@@ -1814,7 +1809,6 @@ static void submount_source_unlock_nested(struct autofs_point *ap)
struct autofs_point *parent = ap->parent;
master_source_unlock(ap->entry);
- mounts_mutex_unlock(parent);
master_source_unlock(parent->entry);
}
diff --git a/daemon/master.c b/daemon/master.c
index b288e070..30d7cf98 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -69,7 +69,6 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
unsigned nobind, unsigned ghost, int submount)
{
struct autofs_point *ap;
- int status;
ap = malloc(sizeof(struct autofs_point));
if (!ap)
@@ -128,12 +127,6 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
INIT_LIST_HEAD(&ap->amdmounts);
ap->shutdown = 0;
- status = pthread_mutex_init(&ap->mounts_mutex, NULL);
- if (status) {
- free(ap->path);
- free(ap);
- return 0;
- }
ap->mode = 0;
entry->ap = ap;
@@ -143,17 +136,11 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt,
void master_free_autofs_point(struct autofs_point *ap)
{
- int status;
-
if (!ap)
return;
mnts_remove_amdmounts(ap);
- status = pthread_mutex_destroy(&ap->mounts_mutex);
- if (status)
- fatal(status);
-
if (ap->pref)
free(ap->pref);
free(ap->path);
diff --git a/include/automount.h b/include/automount.h
index e33ee8d2..51a0bf0e 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -565,7 +565,6 @@ struct autofs_point {
enum states state; /* Current state */
int state_pipe[2]; /* State change router pipe */
struct autofs_point *parent; /* Owner of mounts list for submount */
- pthread_mutex_t mounts_mutex; /* Protect mount lists */
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 */
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
index 1c40e27a..0bcbb343 100644
--- a/modules/mount_autofs.c
+++ b/modules/mount_autofs.c
@@ -283,8 +283,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
set_exp_timeout(nap, NULL, timeout);
nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
- mounts_mutex_lock(ap);
-
if (source->flags & MAP_FLAG_FORMAT_AMD) {
struct mnt_list *mnt;
@@ -305,7 +303,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
if (handle_mounts_startup_cond_init(&suc)) {
crit(ap->logopt, MODPREFIX
"failed to init startup cond for mount %s", entry->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -316,7 +313,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
crit(ap->logopt,
MODPREFIX "failed to allocate mount %s", realpath);
handle_mounts_startup_cond_destroy(&suc);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -335,7 +331,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
realpath);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -346,7 +341,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
if (status) {
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
fatal(status);
@@ -358,7 +352,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
MODPREFIX "failed to create submount for %s", realpath);
handle_mounts_startup_cond_destroy(&suc);
mnts_remove_submount(nap->path);
- mounts_mutex_unlock(ap);
master_free_map_source(source, 1);
master_free_mapent(entry);
return 1;
@@ -368,7 +361,6 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
ap->submnt_count++;
handle_mounts_startup_cond_destroy(&suc);
- mounts_mutex_unlock(ap);
return 0;
}

View File

@ -0,0 +1,752 @@
autofs-5.1.7 - remove obsolete functions
From: Ian Kent <raven@themaw.net>
Remove the code that's no longer used due to the tree mapent
implementation.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
include/automount.h | 10 --
include/mounts.h | 2
lib/cache.c | 227 -------------------------------------
lib/mounts.c | 311 ---------------------------------------------------
modules/parse_sun.c | 56 ---------
6 files changed, 2 insertions(+), 605 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 5ac09f77..76fccf70 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -41,6 +41,7 @@
- add set_offset_tree_catatonic().
- add mount and umount offsets functions.
- switch to use tree implementation for offsets.
+- remove obsolete functions.
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 a71b8674..e33ee8d2 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -162,16 +162,13 @@ struct stack {
struct mapent {
struct mapent *next;
struct list_head ino_index;
- struct list_head multi_list;
struct mapent_cache *mc;
struct map_source *source;
/* Need to know owner if we're a multi-mount */
struct tree_node *mm_root;
+ /* Parent nesting point within multi-mount */
struct tree_node *mm_parent;
struct tree_node node;
- struct mapent *multi;
- /* Parent nesting point within multi-mount */
- struct mapent *parent;
char *key;
size_t len;
char *mapent;
@@ -209,7 +206,6 @@ struct mapent *cache_lookup_next(struct mapent_cache *mc, struct mapent *me);
struct mapent *cache_lookup_key_next(struct mapent *me);
struct mapent *cache_lookup(struct mapent_cache *mc, const char *key);
struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key);
-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head);
struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix);
struct mapent *cache_partial_match_wild(struct mapent_cache *mc, const char *prefix);
int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
@@ -217,16 +213,12 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k
int cache_lookup_negative(struct mapent *me, const char *key);
void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout);
struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key);
-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
-int cache_delete_offset(struct mapent_cache *mc, const char *key);
-int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
void cache_release(struct map_source *map);
void cache_clean_null_cache(struct mapent_cache *mc);
void cache_release_null_cache(struct master *master);
struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me);
-char *cache_get_offset(const char *prefix, char *offset, int start, struct list_head *head, struct list_head **pos);
/* Utility functions */
diff --git a/include/mounts.h b/include/mounts.h
index e56f80ba..ec895e1c 100644
--- a/include/mounts.h
+++ b/include/mounts.h
@@ -187,8 +187,6 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *);
void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *);
int umount_ent(struct autofs_point *, const char *);
int umount_amd_ext_mount(struct autofs_point *, const char *);
-int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *);
-int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
int clean_stale_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *);
#endif
diff --git a/lib/cache.c b/lib/cache.c
index 93b02daf..ef761739 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -461,30 +461,6 @@ struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key)
return NULL;
}
-/* Lookup an offset within a multi-mount entry */
-struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head)
-{
- struct list_head *p;
- struct mapent *this;
- /* Keys for direct maps may be as long as a path name */
- char o_key[PATH_MAX];
- /* Avoid "//" at the beginning of paths */
- const char *path_prefix = strlen(prefix) > 1 ? prefix : "";
- size_t size;
-
- /* root offset duplicates "/" */
- size = snprintf(o_key, sizeof(o_key), "%s%s", path_prefix, offset);
- if (size >= sizeof(o_key))
- return NULL;
-
- list_for_each(p, head) {
- this = list_entry(p, struct mapent, multi_list);
- if (!strcmp(&this->key[start], o_key))
- return this;
- }
- return NULL;
-}
-
/* cache must be read locked by caller */
static struct mapent *__cache_partial_match(struct mapent_cache *mc,
const char *prefix,
@@ -583,9 +559,6 @@ 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->multi_list);
- me->multi = NULL;
- me->parent = NULL;
me->ioctlfd = -1;
me->dev = (dev_t) -1;
me->ino = (ino_t) -1;
@@ -615,33 +588,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
return CHE_OK;
}
-/* cache must be write locked by caller */
-static void cache_add_ordered_offset(struct mapent *me, struct list_head *head)
-{
- struct list_head *p;
- struct mapent *this;
-
- list_for_each(p, head) {
- size_t tlen;
- int eq;
-
- this = list_entry(p, struct mapent, multi_list);
- tlen = strlen(this->key);
-
- eq = strncmp(this->key, me->key, tlen);
- if (!eq && tlen == strlen(me->key))
- return;
-
- if (eq > 0) {
- list_add_tail(&me->multi_list, p);
- return;
- }
- }
- list_add_tail(&me->multi_list, p);
-
- return;
-}
-
/* cache must be write locked by caller */
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age)
{
@@ -777,25 +723,6 @@ struct mapent *cache_get_offset_parent(struct mapent_cache *mc, const char *key)
return NULL;
}
-int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
-{
- struct mapent *this, *parent;
-
- this = cache_lookup_distinct(mc, offset);
- if (!this)
- return 0;
- if (!IS_MM(this))
- return 0;
-
- parent = cache_get_offset_parent(mc, offset);
- if (parent)
- this->parent = parent;
- else
- this->parent = MM_ROOT(this);
-
- return 1;
-}
-
/* cache must be write locked by caller */
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age)
{
@@ -837,50 +764,6 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
return ret;
}
-/* cache write lock of the multi mount owner must be held by caller */
-int cache_delete_offset(struct mapent_cache *mc, const char *key)
-{
- u_int32_t hashval = hash(key, mc->size);
- struct mapent *me = NULL, *pred;
- int status;
-
- me = mc->hash[hashval];
- if (!me)
- return CHE_FAIL;
-
- if (strcmp(key, me->key) == 0) {
- if (IS_MM(me) && IS_MM_ROOT(me))
- return CHE_FAIL;
- mc->hash[hashval] = me->next;
- goto delete;
- }
-
- while (me->next != NULL) {
- pred = me;
- me = me->next;
- if (strcmp(key, me->key) == 0) {
- if (IS_MM(me) && IS_MM_ROOT(me))
- return CHE_FAIL;
- pred->next = me->next;
- goto delete;
- }
- }
-
- return CHE_FAIL;
-
-delete:
- list_del(&me->multi_list);
- ino_index_lock(mc);
- list_del(&me->ino_index);
- ino_index_unlock(mc);
- free(me->key);
- if (me->mapent)
- free(me->mapent);
- free(me);
-
- return CHE_OK;
-}
-
/* cache must be write locked by caller */
int cache_delete(struct mapent_cache *mc, const char *key)
{
@@ -1054,113 +937,3 @@ struct mapent *cache_enumerate(struct mapent_cache *mc, struct mapent *me)
return cache_lookup_next(mc, me);
}
-
-/*
- * Get each offset from list head under prefix.
- * Maintain traversal current position in pos for subsequent calls.
- * Return each offset into offset.
- */
-/* cache must be read locked by caller */
-char *cache_get_offset(const char *prefix, char *offset, int start,
- struct list_head *head, struct list_head **pos)
-{
- struct list_head *next;
- struct mapent *this;
- size_t plen = strlen(prefix);
- size_t len = 0;
-
- if (*pos == head)
- return NULL;
-
- /* Find an offset */
- *offset = '\0';
- next = *pos ? (*pos)->next : head->next;
- while (next != head) {
- char *offset_start, *pstart, *pend;
-
- this = list_entry(next, struct mapent, multi_list);
- *pos = next;
- next = next->next;
-
- offset_start = &this->key[start];
- if (strlen(offset_start) <= plen)
- continue;
-
- if (!strncmp(prefix, offset_start, plen)) {
- struct mapent *np = NULL;
- char pe[PATH_MAX + 1];
-
- /* "/" doesn't count for root offset */
- if (plen == 1)
- pstart = &offset_start[plen - 1];
- else
- pstart = &offset_start[plen];
-
- /* not part of this sub-tree */
- if (*pstart != '/')
- continue;
-
- /* get next offset */
- pend = pstart;
- while (*pend++) {
- size_t nest_pt_offset;
-
- if (*pend != '/')
- continue;
-
- nest_pt_offset = start + pend - pstart;
- if (plen > 1)
- nest_pt_offset += plen;
- strcpy(pe, this->key);
- pe[nest_pt_offset] = '\0';
-
- np = cache_lookup_distinct(this->mc, pe);
- if (np)
- break;
- }
- if (np)
- continue;
- len = pend - pstart - 1;
- strncpy(offset, pstart, len);
- offset[len] ='\0';
- break;
- }
- }
-
- /* Seek to next offset */
- while (next != head) {
- char *offset_start, *pstart;
-
- this = list_entry(next, struct mapent, multi_list);
-
- offset_start = &this->key[start];
- if (strlen(offset_start) <= plen + len)
- break;
-
- /* "/" doesn't count for root offset */
- if (plen == 1)
- pstart = &offset_start[plen - 1];
- else
- pstart = &offset_start[plen];
-
- /* not part of this sub-tree */
- if (*pstart != '/')
- break;
-
- /* new offset */
- if (!*(pstart + len + 1))
- break;
-
- /* compare offset */
- if (pstart[len] != '/' ||
- strlen(pstart) != len ||
- strncmp(offset, pstart, len))
- break;
-
- *pos = next;
- next = next->next;
- }
-
- return *offset ? offset : NULL;
-}
-
diff --git a/lib/mounts.c b/lib/mounts.c
index 6ca7eff1..c120d2a8 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2853,21 +2853,6 @@ static void set_offset_tree_catatonic(struct autofs_point *ap, struct mapent *me
tree_traverse_inorder(MAPENT_ROOT(me), set_offset_tree_catatonic_work, NULL);
}
-static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
-{
- if (!list_empty(&me->multi_list)) {
- struct list_head *head = &me->multi_list;
- struct list_head *p;
-
- list_for_each(p, head) {
- struct mapent *this;
-
- this = list_entry(p, struct mapent, multi_list);
- set_mount_catatonic(ap, this, this->ioctlfd);
- }
- }
-}
-
void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
{
struct master_mapent *entry = ap->entry;
@@ -3034,299 +3019,3 @@ done:
out:
return rv;
}
-
-static int do_mount_autofs_offset(struct autofs_point *ap, struct mapent *oe)
-{
- int mounted = 0;
- int ret;
-
- debug(ap->logopt, "mount offset %s", oe->key);
-
- ret = mount_autofs_offset(ap, oe);
- if (ret >= MOUNT_OFFSET_OK)
- mounted++;
- else {
- if (ret != MOUNT_OFFSET_IGNORE)
- warn(ap->logopt, "failed to mount offset");
- else {
- debug(ap->logopt, "ignoring \"nohide\" trigger %s",
- oe->key);
- /*
- * Ok, so we shouldn't modify the mapent but
- * mount requests are blocked at a point above
- * this and expire only uses the mapent key or
- * holds the cache write lock.
- */
- free(oe->mapent);
- oe->mapent = NULL;
- }
- }
-
- return mounted;
-}
-
-static int rmdir_path_offset(struct autofs_point *ap, struct mapent *oe)
-{
- char *dir, *path;
- unsigned int split;
- int ret;
-
- if (ap->type == LKP_DIRECT)
- return rmdir_path(ap, oe->key, MM_ROOT(oe)->dev);
-
- dir = strdup(oe->key);
-
- if (ap->flags & MOUNT_FLAG_GHOST)
- split = ap->len + strlen(MM_ROOT(oe)->key) + 1;
- else
- split = ap->len;
-
- dir[split] = '\0';
- path = &dir[split + 1];
-
- if (chdir(dir) == -1) {
- error(ap->logopt, "failed to chdir to %s", dir);
- free(dir);
- return -1;
- }
-
- ret = rmdir_path(ap, path, ap->dev);
-
- free(dir);
-
- if (chdir("/") == -1)
- error(ap->logopt, "failed to chdir to /");
-
- return ret;
-}
-
-static int do_umount_offset(struct autofs_point *ap,
- struct mapent *oe, const char *root, int start);
-
-static int do_umount_multi_triggers(struct autofs_point *ap,
- struct mapent *me, const char *root,
- int start, const char *base)
-{
- char path[PATH_MAX + 1];
- char *offset;
- struct mapent *oe;
- struct list_head *mm_root, *pos;
- const char o_root[] = "/";
- const char *mm_base;
- int left;
- unsigned int root_len;
- unsigned int mm_base_len;
-
- left = 0;
-
- mm_root = &me->multi->multi_list;
-
- if (!base)
- mm_base = o_root;
- else
- mm_base = base;
-
- pos = NULL;
- offset = path;
- root_len = start;
- mm_base_len = strlen(mm_base);
-
- while ((offset = cache_get_offset(mm_base, offset, start, mm_root, &pos))) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- if (mm_base_len > 1)
- key_len += mm_base_len;
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- continue;
- }
-
- strcpy(key, root);
- if (mm_base_len > 1)
- strcat(key, mm_base);
- strcat(key, offset);
-
- oe = cache_lookup_distinct(me->mc, key);
- /* root offset is a special case */
- if (!oe || (strlen(oe->key) - start) == 1)
- continue;
-
- left += do_umount_offset(ap, oe, root, start);
- }
-
- return left;
-}
-
-static int do_umount_offset(struct autofs_point *ap,
- struct mapent *oe, const char *root, int start)
-{
- char *oe_base;
- int left = 0;
-
- /*
- * Check for and umount subtree offsets resulting from
- * nonstrict mount fail.
- */
- oe_base = oe->key + start;
- left += do_umount_multi_triggers(ap, oe, root, start, oe_base);
-
- /*
- * If an offset that has an active mount has been removed
- * from the multi-mount we don't want to attempt to trigger
- * mounts for it. Obviously this is because it has been
- * removed, but less obvious is the potential strange
- * behaviour that can result if we do try and mount it
- * again after it's been expired. For example, if an NFS
- * file system is no longer exported and is later umounted
- * it can be mounted again without any error message but
- * shows as an empty directory. That's going to confuse
- * people for sure.
- *
- * If the mount cannot be umounted (the process is now
- * using a stale mount) the offset needs to be invalidated
- * so no further mounts will be attempted but the offset
- * cache entry must remain so expires can continue to
- * attempt to umount it. If the mount can be umounted and
- * the offset is removed, at least for NFS we will get
- * ESTALE errors when attempting list the directory.
- */
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL)) {
- if (umount_ent(ap, oe->key) &&
- is_mounted(oe->key, MNTS_REAL)) {
- debug(ap->logopt,
- "offset %s has active mount, invalidate",
- oe->key);
- /*
- * Ok, so we shouldn't modify the mapent but
- * mount requests are blocked at a point above
- * this and expire only uses the mapent key or
- * holds the cache write lock.
- */
- if (oe->mapent) {
- free(oe->mapent);
- oe->mapent = NULL;
- }
- return ++left;
- }
- }
-
- debug(ap->logopt, "umount offset %s", oe->key);
-
- if (umount_autofs_offset(ap, oe)) {
- warn(ap->logopt, "failed to umount offset");
- left++;
- } else {
- struct stat st;
- int ret;
-
- if (!(oe->flags & MOUNT_FLAG_DIR_CREATED))
- return left;
-
- /*
- * An error due to partial directory removal is
- * ok so only try and remount the offset if the
- * actual mount point still exists.
- */
- ret = rmdir_path_offset(ap, oe);
- if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe);
- if (ret)
- left++;
- /* But we did origianlly create this */
- oe->flags |= MOUNT_FLAG_DIR_CREATED;
- }
- }
- return left;
-}
-
-int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
- const char *root, unsigned int start, const char *base)
-{
- char path[PATH_MAX + 1];
- char *offset = path;
- struct mapent *oe;
- struct list_head *pos = NULL;
- unsigned int root_len = strlen(root);
- int mounted;
-
- mounted = 0;
- offset = cache_get_offset(base, offset, start, &me->multi_list, &pos);
- while (offset) {
- char key[PATH_MAX + 1];
- int key_len = root_len + strlen(offset);
-
- if (key_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- goto cont;
- }
-
- /* The root offset is always mounted seperately so the
- * offset path will always be root + offset.
- */
- strcpy(key, root);
- strcat(key, offset);
-
- oe = cache_lookup_distinct(me->mc, key);
- if (!oe || !oe->mapent)
- goto cont;
- if (oe->age != MM_ROOT(me)->age) {
- /* Best effort */
- do_umount_offset(ap, oe, root, start);
- goto cont;
- }
-
- mounted += do_mount_autofs_offset(ap, oe);
-
- /*
- * If re-constructing a multi-mount it's necessary to walk
- * into nested mounts, unlike the usual "mount only what's
- * needed as you go" behavior.
- */
- if (ap->state == ST_READMAP && ap->flags & MOUNT_FLAG_REMOUNT) {
- if (oe->ioctlfd != -1 ||
- is_mounted(oe->key, MNTS_REAL))
- mount_multi_triggers(ap, oe, key, key_len, base);
- }
-cont:
- offset = cache_get_offset(base,
- offset, start, &me->multi_list, &pos);
- }
-
- return mounted;
-}
-
-int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root, const char *base)
-{
- int left, start;
-
- start = strlen(root);
-
- left = do_umount_multi_triggers(ap, me, root, start, base);
-
- if (!left && IS_MM_ROOT(me)) {
- /*
- * Special case.
- * If we can't umount the root container then we can't
- * delete the offsets from the cache and we need to put
- * the offset triggers back.
- */
- if (is_mounted(root, MNTS_REAL)) {
- info(ap->logopt, "unmounting dir = %s", root);
- if (umount_ent(ap, root) &&
- is_mounted(root, MNTS_REAL)) {
- if (mount_multi_triggers(ap, me, root, start, "/") < 0)
- warn(ap->logopt,
- "failed to remount offset triggers");
- return ++left;
- }
- }
-
- /* check for mounted mount entry and remove it if found */
- mnts_remove_mount(root, MNTS_MOUNTED);
- }
-
- return left;
-}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index d6ef48b8..ef74eda9 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1074,62 +1074,6 @@ next:
return (p - ent);
}
-static void cleanup_multi_triggers(struct autofs_point *ap,
- struct mapent *me, const char *root, int start,
- const char *base)
-{
- char path[PATH_MAX + 1];
- char offset[PATH_MAX + 1];
- char *poffset = offset;
- struct mapent *oe;
- struct list_head *mm_root, *pos;
- const char o_root[] = "/";
- const char *mm_base;
- unsigned int root_len;
- unsigned int mm_base_len;
-
- mm_root = &me->multi->multi_list;
-
- if (!base)
- mm_base = o_root;
- else
- mm_base = base;
-
- pos = NULL;
- root_len = strlen(root);
- mm_base_len = strlen(mm_base);
-
- /* Make sure "none" of the offsets have an active mount. */
- while ((poffset = cache_get_offset(mm_base, poffset, start, mm_root, &pos))) {
- unsigned int path_len = root_len + strlen(poffset);
-
- if (mm_base_len > 1)
- path_len += mm_base_len;
-
- if (path_len > PATH_MAX) {
- warn(ap->logopt, "path loo long");
- continue;
- }
-
- strcpy(path, root);
- if (mm_base_len > 1)
- strcat(path, mm_base);
- strcat(path, poffset);
-
- oe = cache_lookup_distinct(me->mc, path);
- /* root offset is a special case */
- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1)
- continue;
-
- if (umount(path)) {
- error(ap->logopt, "error recovering from mount fail");
- error(ap->logopt, "cannot umount offset %s", path);
- }
- }
-
- return;
-}
-
static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
const char *name, char *loc, char *options, void *ctxt)
{

View File

@ -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:

View File

@ -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);

View File

@ -0,0 +1,74 @@
autofs-5.1.7 - remove redundant local var from sun_mount()
From: Ian Kent <raven@themaw.net>
The local variable mountpoint in sun_mount() is set directly from a
passed in parameter and never changed and the source isn't changed
either, so use the variable directly.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 13 ++++---------
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 76fccf70..444ade5b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -42,6 +42,7 @@
- add mount and umount offsets functions.
- switch to use tree implementation for offsets.
- remove obsolete functions.
+- remove redundant local var from sun_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 ef74eda9..437869b5 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -530,7 +530,6 @@ static int sun_mount(struct autofs_point *ap, const char *root,
int nonstrict = 1;
int use_weight_only = ap->flags & MOUNT_FLAG_USE_WEIGHT_ONLY;
int rv, cur_state;
- char *mountpoint;
char *what;
char *type;
@@ -624,9 +623,6 @@ static int sun_mount(struct autofs_point *ap, const char *root,
}
}
- mountpoint = alloca(namelen + 1);
- sprintf(mountpoint, "%.*s", namelen, name);
-
type = ap->entry->maps->type;
if (type && !strcmp(type, "hosts")) {
if (options && *options != '\0') {
@@ -698,9 +694,9 @@ static int sun_mount(struct autofs_point *ap, const char *root,
debug(ap->logopt, MODPREFIX
"mounting root %s, mountpoint %s, "
"what %s, fstype %s, options %s",
- root, mountpoint, what, fstype, options);
+ root, name, what, fstype, options);
- rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint),
+ rv = mount_nfs->mount_mount(ap, root, name, namelen,
what, fstype, options, mount_nfs->context);
} else {
if (!loclen)
@@ -720,11 +716,10 @@ static int sun_mount(struct autofs_point *ap, const char *root,
debug(ap->logopt, MODPREFIX
"mounting root %s, mountpoint %s, "
"what %s, fstype %s, options %s",
- root, mountpoint, what, fstype, options);
+ root, name, what, fstype, options);
/* Generic mount routine */
- rv = do_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype,
- options);
+ rv = do_mount(ap, root, name, namelen, what, fstype, options);
}
pthread_setcancelstate(cur_state, NULL);

View File

@ -0,0 +1,182 @@
autofs-5.1.7 - remove redundant variables from mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
The path to be mounted is the key in the passed in mapent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/direct.c | 42 +++++++++++++++++++-----------------------
include/automount.h | 2 +-
lib/mounts.c | 2 +-
4 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index c4ebb52f..45be4783 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,7 @@
- fix is mounted check on non existent path.
- simplify cache_get_parent().
- set offset parent in update_offset_entry().
+- remove redundant variables from mount_autofs_offset().
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 9fe4903a..c41c680f 100644
--- a/daemon/direct.c
+++ b/daemon/direct.c
@@ -611,7 +611,7 @@ force_umount:
return rv;
}
-int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *root, const char *offset)
+int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
{
const char *str_offset = mount_type_str(t_offset);
struct ioctl_ops *ops = get_ioctl_ops();
@@ -623,7 +623,6 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
const char *hosts_map_name = "-hosts";
const char *map_name = hosts_map_name;
const char *type;
- char mountpoint[PATH_MAX];
struct mnt_list *mnt;
if (ops->version && ap->flags & MOUNT_FLAG_REMOUNT) {
@@ -681,11 +680,8 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
return MOUNT_OFFSET_OK;
}
- strcpy(mountpoint, root);
- strcat(mountpoint, offset);
-
/* In case the directory doesn't exist, try to mkdir it */
- if (mkdir_path(mountpoint, mp_mode) < 0) {
+ if (mkdir_path(me->key, mp_mode) < 0) {
if (errno == EEXIST) {
/*
* If the mount point directory is a real mount
@@ -694,7 +690,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
* the kernel NFS client.
*/
if (me->multi != me &&
- is_mounted(mountpoint, MNTS_REAL))
+ is_mounted(me->key, MNTS_REAL))
return MOUNT_OFFSET_IGNORE;
/*
@@ -714,13 +710,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
debug(ap->logopt,
"can't create mount directory: %s, %s",
- mountpoint, estr);
+ me->key, estr);
return MOUNT_OFFSET_FAIL;
} else {
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
crit(ap->logopt,
"failed to create mount directory: %s, %s",
- mountpoint, estr);
+ me->key, estr);
return MOUNT_OFFSET_FAIL;
}
} else {
@@ -730,56 +726,56 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me, const char *
debug(ap->logopt,
"calling mount -t autofs " SLOPPY " -o %s automount %s",
- mp->options, mountpoint);
+ mp->options, me->key);
type = ap->entry->maps->type;
if (!type || strcmp(ap->entry->maps->type, "hosts"))
map_name = me->mc->map->argv[0];
- ret = mount(map_name, mountpoint, "autofs", MS_MGC_VAL, mp->options);
+ ret = mount(map_name, me->key, "autofs", MS_MGC_VAL, mp->options);
if (ret) {
crit(ap->logopt,
"failed to mount offset trigger %s at %s",
- me->key, mountpoint);
+ me->key, me->key);
goto out_err;
}
- ret = stat(mountpoint, &st);
+ ret = stat(me->key, &st);
if (ret == -1) {
error(ap->logopt,
- "failed to stat direct mount trigger %s", mountpoint);
+ "failed to stat direct mount trigger %s", me->key);
goto out_umount;
}
- ops->open(ap->logopt, &ioctlfd, st.st_dev, mountpoint);
+ ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
if (ioctlfd < 0) {
- crit(ap->logopt, "failed to create ioctl fd for %s", mountpoint);
+ crit(ap->logopt, "failed to create ioctl fd for %s", me->key);
goto out_umount;
}
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, mountpoint, timeout, str_offset);
+ notify_mount_result(ap, me->key, timeout, str_offset);
else
notify_mount_result(ap, me->key, timeout, str_offset);
ops->close(ap->logopt, ioctlfd);
- mnt = mnts_add_mount(ap, mountpoint, MNTS_OFFSET);
+ mnt = mnts_add_mount(ap, me->key, MNTS_OFFSET);
if (!mnt)
error(ap->logopt,
"failed to add offset mount %s to mounted list",
- mountpoint);
+ me->key);
- debug(ap->logopt, "mounted trigger %s at %s", me->key, mountpoint);
+ debug(ap->logopt, "mounted trigger %s", me->key);
return MOUNT_OFFSET_OK;
out_umount:
- umount(mountpoint);
+ umount(me->key);
out_err:
- if (stat(mountpoint, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED)
- rmdir_path(ap, mountpoint, st.st_dev);
+ if (stat(me->key, &st) == 0 && me->flags & MOUNT_FLAG_DIR_CREATED)
+ rmdir_path(ap, me->key, st.st_dev);
return MOUNT_OFFSET_FAIL;
}
diff --git a/include/automount.h b/include/automount.h
index 730be19a..09d84f05 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -596,7 +596,7 @@ 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 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, const char *root, const char *offset);
+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);
diff --git a/lib/mounts.c b/lib/mounts.c
index fe931b20..12d22023 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2481,7 +2481,7 @@ static int do_mount_autofs_offset(struct autofs_point *ap,
debug(ap->logopt, "mount offset %s at %s", oe->key, root);
- ret = mount_autofs_offset(ap, oe, root, offset);
+ ret = mount_autofs_offset(ap, oe);
if (ret >= MOUNT_OFFSET_OK)
mounted++;
else {

View File

@ -0,0 +1,60 @@
autofs-5.1.7 - remove unused function master_submount_list_empty()
From: Ian Kent <raven@themaw.net>
This function is not used anywhere now, remove it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/master.c | 12 ------------
include/master.h | 1 -
3 files changed, 1 insertion(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1c9e2a2d..002da042 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -45,6 +45,7 @@
- remove redundant local var from sun_mount().
- use mount_fullpath() in one spot in parse_mount().
- pass root length to mount_fullpath().
+- remove unused function master_submount_list_empty().
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 022fb9dd..af9cd79f 100644
--- a/daemon/master.c
+++ b/daemon/master.c
@@ -1119,18 +1119,6 @@ int master_read_master(struct master *master, time_t age)
return 1;
}
-int master_submount_list_empty(struct autofs_point *ap)
-{
- int res = 0;
-
- mounts_mutex_lock(ap);
- if (list_empty(&ap->submounts))
- res = 1;
- mounts_mutex_unlock(ap);
-
- return res;
-}
-
int master_notify_submount(struct autofs_point *ap, const char *path, enum states state)
{
struct mnt_list *this, *sbmnt;
diff --git a/include/master.h b/include/master.h
index 0806b372..2d727943 100644
--- a/include/master.h
+++ b/include/master.h
@@ -116,7 +116,6 @@ void master_free_mapent_sources(struct master_mapent *, unsigned int);
void master_free_mapent(struct master_mapent *);
struct master *master_new(const char *, unsigned int, unsigned int);
int master_read_master(struct master *, time_t);
-int master_submount_list_empty(struct autofs_point *ap);
int master_notify_submount(struct autofs_point *, const char *path, enum states);
void master_notify_state_change(struct master *, int);
int master_mount_mounts(struct master *, time_t);

View File

@ -0,0 +1,63 @@
autofs-5.1.7 - remove unused functions cache_dump_multi() and cache_dump_cache()
From: Ian Kent <raven@themaw.net>
Remove debugging functions cache_dump_multi() and cache_dump_cache()
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 28 ----------------------------
2 files changed, 1 insertion(+), 28 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3ba748d7..60924b3f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -29,6 +29,7 @@
- don't pass root to do_mount_autofs_offset().
- rename tree implementation functions.
- add some multi-mount macros.
+- remove unused functions cache_dump_multi() and cache_dump_cache().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/cache.c b/lib/cache.c
index 1d9f5cc7..629c4d0a 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -24,34 +24,6 @@
#include "automount.h"
-void cache_dump_multi(struct list_head *list)
-{
- struct list_head *p;
- struct mapent *me;
-
- list_for_each(p, list) {
- me = list_entry(p, struct mapent, multi_list);
- logmsg("key=%s", me->key);
- }
-}
-
-void cache_dump_cache(struct mapent_cache *mc)
-{
- struct mapent *me;
- unsigned int i;
-
- for (i = 0; i < mc->size; i++) {
- me = mc->hash[i];
- if (me == NULL)
- continue;
- while (me) {
- logmsg("me->key=%s me->multi=%p dev=%ld ino=%ld",
- me->key, me->multi, me->dev, me->ino);
- me = me->next;
- }
- }
-}
-
void cache_readlock(struct mapent_cache *mc)
{
int status;

View File

@ -0,0 +1,179 @@
autofs-5.1.7 - remove unused mount offset list lock functions
From: Ian Kent <raven@themaw.net>
When fixing the locking in parse_mount() it was evident that there was
no real benefit of having an additional lock for the offset list so its
use was eliminated.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 4 ---
lib/cache.c | 70 +--------------------------------------------------
3 files changed, 3 insertions(+), 72 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index d25b19c8..c5619d2e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@
- fix return from umount_subtree_mounts() on offset list delete.
- pass mapent_cache to update_offset_entry().
- fix inconsistent locking in parse_mount().
+- remove unused mount offset list lock functions.
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 09d84f05..69445b92 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -162,7 +162,6 @@ struct stack {
struct mapent {
struct mapent *next;
struct list_head ino_index;
- pthread_rwlock_t multi_rwlock;
struct list_head multi_list;
struct mapent_cache *mc;
struct map_source *source;
@@ -212,9 +211,6 @@ int cache_set_offset_parent(struct mapent_cache *mc, const char *offset);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
int cache_delete_offset(struct mapent_cache *mc, const char *key);
-void cache_multi_readlock(struct mapent *me);
-void cache_multi_writelock(struct mapent *me);
-void cache_multi_unlock(struct mapent *me);
int cache_delete_offset_list(struct mapent_cache *mc, const char *key);
void cache_release(struct map_source *map);
void cache_clean_null_cache(struct mapent_cache *mc);
diff --git a/lib/cache.c b/lib/cache.c
index ce9e9bd2..03d0499a 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -108,58 +108,6 @@ void cache_lock_cleanup(void *arg)
return;
}
-void cache_multi_readlock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_rdlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex lock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_writelock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_wrlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex lock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_unlock(struct mapent *me)
-{
- int status;
-
- if (!me)
- return;
-
- status = pthread_rwlock_unlock(&me->multi_rwlock);
- if (status) {
- logmsg("mapent cache multi mutex unlock failed");
- fatal(status);
- }
- return;
-}
-
-void cache_multi_lock_cleanup(void *arg)
-{
- struct mapent *me = (struct mapent *) arg;
- cache_multi_unlock(me);
- return;
-}
-
static inline void ino_index_lock(struct mapent_cache *mc)
{
int status = pthread_mutex_lock(&mc->ino_index_mutex);
@@ -626,7 +574,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
struct mapent *me, *existing = NULL;
char *pkey, *pent;
u_int32_t hashval = hash(key, mc->size);
- int status;
me = (struct mapent *) malloc(sizeof(struct mapent));
if (!me)
@@ -665,10 +612,6 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
me->ino = (ino_t) -1;
me->flags = 0;
- status = pthread_rwlock_init(&me->multi_rwlock, NULL);
- if (status)
- fatal(status);
-
/*
* We need to add to the end if values exist in order to
* preserve the order in which the map was read on lookup.
@@ -924,7 +867,7 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
return ret;
}
-/* cache_multi_lock of the multi mount owner must be held by caller */
+/* cache write lock of the multi mount owner must be held by caller */
int cache_delete_offset(struct mapent_cache *mc, const char *key)
{
u_int32_t hashval = hash(key, mc->size);
@@ -956,9 +899,6 @@ int cache_delete_offset(struct mapent_cache *mc, const char *key)
return CHE_FAIL;
delete:
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
list_del(&me->multi_list);
ino_index_lock(mc);
list_del(&me->ino_index);
@@ -976,7 +916,7 @@ int cache_delete(struct mapent_cache *mc, const char *key)
{
struct mapent *me = NULL, *pred;
u_int32_t hashval = hash(key, mc->size);
- int status, ret = CHE_OK;
+ int ret = CHE_OK;
char this[PATH_MAX];
strcpy(this, key);
@@ -997,9 +937,6 @@ int cache_delete(struct mapent_cache *mc, const char *key)
goto done;
}
pred->next = me->next;
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
ino_index_lock(mc);
list_del(&me->ino_index);
ino_index_unlock(mc);
@@ -1029,9 +966,6 @@ int cache_delete(struct mapent_cache *mc, const char *key)
goto done;
}
mc->hash[hashval] = me->next;
- status = pthread_rwlock_destroy(&me->multi_rwlock);
- if (status)
- fatal(status);
ino_index_lock(mc);
list_del(&me->ino_index);
ino_index_unlock(mc);

View File

@ -0,0 +1,66 @@
autofs-5.1.7 - remove unused parameter form do_mount_autofs_offset()
From: Ian Kent <raven@themaw.net>
The offset parameter of do_mount_autofs_offset() isn't used.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 10 ++++------
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 45be4783..3eda995c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,7 @@
- simplify cache_get_parent().
- set offset parent in update_offset_entry().
- remove redundant variables from mount_autofs_offset().
+- remove unused parameter form do_mount_autofs_offset().
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 12d22023..8e88182f 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2472,9 +2472,7 @@ out:
}
static int do_mount_autofs_offset(struct autofs_point *ap,
- struct mapent *oe, const char *root,
- char *offset)
-
+ struct mapent *oe, const char *root)
{
int mounted = 0;
int ret;
@@ -2529,7 +2527,7 @@ int mount_multi_triggers(struct autofs_point *ap, struct mapent *me,
if (!oe || !oe->mapent)
goto cont;
- mounted += do_mount_autofs_offset(ap, oe, root, offset);
+ mounted += do_mount_autofs_offset(ap, oe, root);
/*
* If re-constructing a multi-mount it's necessary to walk
@@ -2666,7 +2664,7 @@ int umount_multi_triggers(struct autofs_point *ap, struct mapent *me, char *root
*/
ret = rmdir_path_offset(ap, oe);
if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root, offset);
+ ret = do_mount_autofs_offset(ap, oe, root);
if (ret)
left++;
/* But we did origianlly create this */
@@ -2847,7 +2845,7 @@ int clean_stale_multi_triggers(struct autofs_point *ap,
*/
ret = rmdir_path_offset(ap, oe);
if (ret == -1 && !stat(oe->key, &st)) {
- ret = do_mount_autofs_offset(ap, oe, root, offset);
+ ret = do_mount_autofs_offset(ap, oe, root);
if (ret) {
left++;
/* But we did origianlly create this */

View File

@ -0,0 +1,32 @@
autofs-5.1.7 - remove unused variable from get_exports()
From: Ian Kent <raven@themaw.net>
Fix complier warning about unused variable entry in get_exports().
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
--- autofs-5.1.7.orig/modules/lookup_hosts.c
+++ autofs-5.1.7/modules/lookup_hosts.c
@@ -87,7 +87,6 @@ int lookup_read_master(struct master *ma
static char *get_exports(struct autofs_point *ap, const char *host)
{
char buf[MAX_ERR_BUF];
- char entry[PATH_MAX + 1];
char *mapent;
struct exportinfo *exp, *this;
size_t hostlen = strlen(host);
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -49,6 +49,7 @@
- move amd mounts removal into lib/mounts.c.
- check for offset with no mount location.
- remove mounts_mutex.
+- remove unused variable from get_exports().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.

View File

@ -0,0 +1,159 @@
autofs-5.1.7 - rename path to m_offset in update_offset_entry()
From: Ian Kent <raven@themaw.net>
Rename local variable from path to m_offset in update_offset_entry() to
make the meaning of this variable clear.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 46 +++++++++++++++++++++++-----------------------
2 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e822efec..0e9ca94f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -25,6 +25,7 @@
- don't add offset mounts to mounted mounts table.
- reduce umount EBUSY check delay.
- cleanup cache_delete() a little.
+- rename path to m_offset in update_offset_entry().
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 a6630a76..34d4441e 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -796,36 +796,36 @@ static int
update_offset_entry(struct autofs_point *ap,
struct mapent_cache *mc, const char *name,
const char *m_root, int m_root_len,
- const char *path, const char *myoptions,
+ 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 p_len, m_key_len, m_options_len, m_mapent_len;
+ int o_len, m_key_len, m_options_len, m_mapent_len;
int ret;
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
/* Internal hosts map may have loc == NULL */
- if (!*path) {
+ if (!*m_offset) {
error(ap->logopt,
- MODPREFIX "syntax error in offset %s -> %s", path, loc);
+ MODPREFIX "syntax error in offset %s -> %s", m_offset, loc);
return CHE_FAIL;
}
- p_len = strlen(path);
+ o_len = strlen(m_offset);
/* Trailing '/' causes us pain */
- if (p_len > 1) {
- while (p_len > 1 && path[p_len - 1] == '/')
- p_len--;
+ if (o_len > 1) {
+ while (o_len > 1 && m_offset[o_len - 1] == '/')
+ o_len--;
}
- m_key_len = m_root_len + p_len;
+ m_key_len = m_root_len + o_len;
if (m_key_len > PATH_MAX) {
error(ap->logopt, MODPREFIX "multi mount key too long");
return CHE_FAIL;
}
strcpy(m_key, m_root);
- strncat(m_key, path, p_len);
+ strncat(m_key, m_offset, o_len);
m_key[m_key_len] = '\0';
m_options_len = 0;
@@ -860,15 +860,15 @@ update_offset_entry(struct autofs_point *ap,
if (ret == CHE_DUPLICATE) {
warn(ap->logopt, MODPREFIX
- "syntax error or duplicate offset %s -> %s", path, loc);
+ "syntax error or duplicate offset %s -> %s", m_offset, loc);
ret = CHE_OK;
} else if (ret == CHE_FAIL)
debug(ap->logopt, MODPREFIX
- "failed to update multi-mount offset %s -> %s", path, m_mapent);
+ "failed to update multi-mount offset %s -> %s", m_offset, m_mapent);
else {
ret = CHE_OK;
debug(ap->logopt, MODPREFIX
- "updated multi-mount offset %s -> %s", path, m_mapent);
+ "updated multi-mount offset %s -> %s", m_offset, m_mapent);
}
return ret;
@@ -1538,22 +1538,22 @@ dont_expand:
/* It's a multi-mount; deal with it */
do {
- char *path, *myoptions, *loc;
+ char *m_offset, *myoptions, *loc;
int status;
if ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/')) {
l = 0;
- path = dequote("/", 1, ap->logopt);
+ m_offset = dequote("/", 1, ap->logopt);
debug(ap->logopt,
- MODPREFIX "dequote(\"/\") -> %s", path);
+ MODPREFIX "dequote(\"/\") -> %s", m_offset);
} else {
l = span_space(p, mapent_len - (p - pmapent));
- path = sanitize_path(p, l, LKP_MULTI, ap->logopt);
+ m_offset = sanitize_path(p, l, LKP_MULTI, ap->logopt);
debug(ap->logopt, MODPREFIX
- "dequote(\"%.*s\") -> %s", l, p, path);
+ "dequote(\"%.*s\") -> %s", l, p, m_offset);
}
- if (!path) {
+ if (!m_offset) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
cache_writelock(mc);
cache_delete_offset_list(mc, name);
@@ -1575,7 +1575,7 @@ dont_expand:
cache_writelock(mc);
cache_delete_offset_list(mc, name);
cache_unlock(mc);
- free(path);
+ free(m_offset);
free(options);
free(pmapent);
pthread_setcancelstate(cur_state, NULL);
@@ -1587,14 +1587,14 @@ dont_expand:
status = update_offset_entry(ap, mc,
name, m_root, m_root_len,
- path, myoptions, loc, age);
+ m_offset, myoptions, loc, age);
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
cache_writelock(mc);
cache_delete_offset_list(mc, name);
cache_unlock(mc);
- free(path);
+ free(m_offset);
free(options);
free(pmapent);
free(myoptions);
@@ -1606,7 +1606,7 @@ dont_expand:
if (loc)
free(loc);
- free(path);
+ free(m_offset);
free(myoptions);
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));

View File

@ -0,0 +1,197 @@
autofs-5.1.7 - rename tree implementation functions
From: Ian Kent <raven@themaw.net>
Rename the tree struct and functions to make them consistent.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/mounts.c | 80 +++++++++++++++++++++++++++++-----------------------------
2 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 2a07bd45..1bf20699 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -27,6 +27,7 @@
- cleanup cache_delete() a little.
- rename path to m_offset in update_offset_entry().
- don't pass root to do_mount_autofs_offset().
+- rename tree implementation functions.
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 289500da..f5b905a6 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -1225,30 +1225,30 @@ done:
return has_mounted_mounts;
}
-struct node {
+struct tree_node {
struct mnt_list *mnt;
- struct node *left;
- struct node *right;
+ struct tree_node *left;
+ struct tree_node *right;
};
-static struct node *new(struct mnt_list *mnt)
+static struct tree_node *tree_new(struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *n;
- n = malloc(sizeof(struct node));
+ n = malloc(sizeof(struct tree_node));
if (!n)
return NULL;
- memset(n, 0, sizeof(struct node));
+ memset(n, 0, sizeof(struct tree_node));
n->mnt = mnt;
return n;
}
-static struct node *tree_root(struct mnt_list *mnt)
+static struct tree_node *tree_root(struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *n;
- n = new(mnt);
+ n = tree_new(mnt);
if (!n) {
error(LOGOPT_ANY, "failed to allcate tree root");
return NULL;
@@ -1257,37 +1257,37 @@ static struct node *tree_root(struct mnt_list *mnt)
return n;
}
-static struct node *add_left(struct node *this, struct mnt_list *mnt)
+static struct tree_node *tree_add_left(struct tree_node *n, struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *new;
- n = new(mnt);
- if (!n) {
+ new = tree_new(mnt);
+ if (!new) {
error(LOGOPT_ANY, "failed to allcate tree node");
return NULL;
}
- this->left = n;
+ n->left = new;
return n;
}
-static struct node *add_right(struct node *this, struct mnt_list *mnt)
+static struct tree_node *tree_add_right(struct tree_node *n, struct mnt_list *mnt)
{
- struct node *n;
+ struct tree_node *new;
- n = new(mnt);
- if (!n) {
+ new = tree_new(mnt);
+ if (!new) {
error(LOGOPT_ANY, "failed to allcate tree node");
return NULL;
}
- this->right = n;
+ n->right = new;
return n;
}
-static struct node *add_node(struct node *root, struct mnt_list *mnt)
+static struct tree_node *tree_add_node(struct tree_node *root, struct mnt_list *mnt)
{
- struct node *p, *q;
+ struct tree_node *p, *q;
unsigned int mp_len;
mp_len = strlen(mnt->mp);
@@ -1307,43 +1307,43 @@ static struct node *add_node(struct node *root, struct mnt_list *mnt)
error(LOGOPT_ANY, "duplicate entry in mounts list");
else {
if (mp_len < strlen(p->mnt->mp))
- return add_left(p, mnt);
+ return tree_add_left(p, mnt);
else
- return add_right(p, mnt);
+ return tree_add_right(p, mnt);
}
return NULL;
}
-static void tree_free(struct node *tree)
+static void tree_free(struct tree_node *root)
{
- if (tree->right)
- tree_free(tree->right);
- if (tree->left)
- tree_free(tree->left);
- free(tree);
+ if (root->right)
+ tree_free(root->right);
+ if (root->left)
+ tree_free(root->left);
+ free(root);
}
-static void traverse(struct node *node, struct list_head *mnts)
+static void tree_traverse(struct tree_node *n, struct list_head *mnts)
{
- if (node->right)
- traverse(node->right, mnts);
- list_add_tail(&node->mnt->expire, mnts);
- if (node->left)
- traverse(node->left, mnts);
+ if (n->right)
+ tree_traverse(n->right, mnts);
+ list_add_tail(&n->mnt->expire, mnts);
+ if (n->left)
+ tree_traverse(n->left, mnts);
}
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
{
struct mnt_list *mnt;
- struct node *tree = NULL;
+ struct tree_node *tree = NULL;
mnts_hash_mutex_lock();
if (list_empty(&ap->mounts))
goto done;
list_for_each_entry(mnt, &ap->mounts, mount) {
- struct node *n;
+ struct tree_node *n;
if (!(mnt->flags & MNTS_MOUNTED))
continue;
@@ -1359,7 +1359,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
continue;
}
- n = add_node(tree, mnt);
+ n = tree_add_node(tree, mnt);
if (!n) {
error(LOGOPT_ANY, "failed to add expire tree node");
tree_free(tree);
@@ -1367,7 +1367,7 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
}
}
- traverse(tree, mnts);
+ tree_traverse(tree, mnts);
tree_free(tree);
done:
mnts_hash_mutex_unlock();

View File

@ -0,0 +1,104 @@
autofs-5.1.7 - set offset parent in update_offset_entry()
From: Ian Kent <raven@themaw.net>
Avoid the list traversal in cache_set_parents() by setting the
offset parent when updating the offset.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
include/automount.h | 2 +-
lib/cache.c | 26 +++++++++++---------------
modules/parse_sun.c | 5 ++++-
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ee746277..c4ebb52f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@
- eliminate cache_lookup_offset() usage.
- fix is mounted check on non existent path.
- simplify cache_get_parent().
+- set offset parent in update_offset_entry().
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 2f09e8e7..730be19a 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -208,7 +208,7 @@ int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, c
int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age);
int cache_lookup_negative(struct mapent *me, const char *key);
void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout);
-int cache_set_parents(struct mapent *mm);
+int cache_set_offset_parent(struct mapent_cache *mc, const char *offset);
int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age);
int cache_delete(struct mapent_cache *mc, const char *key);
int cache_delete_offset(struct mapent_cache *mc, const char *key);
diff --git a/lib/cache.c b/lib/cache.c
index 53f290cd..ce9e9bd2 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -864,25 +864,21 @@ static struct mapent *get_offset_parent(struct mapent_cache *mc,
return NULL;
}
-int cache_set_parents(struct mapent *mm)
+int cache_set_offset_parent(struct mapent_cache *mc, const char *offset)
{
- struct list_head *multi_head, *p;
- struct mapent *this;
+ struct mapent *this, *parent;
- if (!mm->multi)
+ this = cache_lookup_distinct(mc, offset);
+ if (!this)
+ return 0;
+ if (!this->multi)
return 0;
- multi_head = &mm->multi->multi_list;
-
- list_for_each(p, multi_head) {
- struct mapent *parent;
- this = list_entry(p, struct mapent, multi_list);
- parent = get_offset_parent(mm->mc, this->key);
- if (parent)
- this->parent = parent;
- else
- this->parent = mm->multi;
- }
+ parent = get_offset_parent(mc, offset);
+ if (parent)
+ this->parent = parent;
+ else
+ this->parent = this->multi;
return 1;
}
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 819d6adc..f42af7b7 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -859,6 +859,10 @@ update_offset_entry(struct autofs_point *ap, const char *name,
}
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
+
+ if (!cache_set_offset_parent(mc, m_key))
+ error(ap->logopt, "failed to set offset parent");
+
if (ret == CHE_DUPLICATE) {
warn(ap->logopt, MODPREFIX
"syntax error or duplicate offset %s -> %s", path, loc);
@@ -1613,7 +1617,6 @@ dont_expand:
*/
if (me == me->multi)
clean_stale_multi_triggers(ap, me, NULL, NULL);
- cache_set_parents(me);
rv = mount_subtree(ap, me, name, NULL, options, ctxt);

View File

@ -0,0 +1,105 @@
autofs-5.1.7 - simplify cache_get_parent()
From: Ian Kent <raven@themaw.net>
Eliminate the list traversal from get_parent() and rename it to
get_offset_parent() to better describe it's usage.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
lib/cache.c | 46 ++++++++++++++++++++++++++++------------------
2 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index e55fd66a..ee746277 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
- Fix option for master read wait.
- eliminate cache_lookup_offset() usage.
- fix is mounted check on non existent path.
+- simplify cache_get_parent().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/lib/cache.c b/lib/cache.c
index d3b6642b..53f290cd 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -827,47 +827,57 @@ void cache_update_negative(struct mapent_cache *mc,
}
-static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos)
+static struct mapent *get_offset_parent(struct mapent_cache *mc,
+ const char *key)
{
- struct list_head *next;
- struct mapent *this, *last;
- int eq;
+ struct mapent *me;
+ char *parent, *tail;
+ int key_len;
- last = NULL;
- next = *pos ? (*pos)->next : head->next;
+ key_len = strlen(key);
- list_for_each(next, head) {
- this = list_entry(next, struct mapent, multi_list);
+ /* Check if this is the root offset */
+ if (key[key_len - 1] == '/')
+ return NULL;
+
+ parent = strdup(key);
+ tail = &parent[key_len - 1];
- if (!strcmp(this->key, key))
+ while (*tail) {
+ while (*tail != '/')
+ tail--;
+
+ *tail = 0;
+
+ tail--;
+ if (tail == parent)
break;
- eq = strncmp(this->key, key, strlen(this->key));
- if (eq == 0) {
- *pos = next;
- last = this;
- continue;
+ me = cache_lookup_distinct(mc, parent);
+ if (me) {
+ free(parent);
+ return me;
}
}
+ free(parent);
- return last;
+ return NULL;
}
int cache_set_parents(struct mapent *mm)
{
- struct list_head *multi_head, *p, *pos;
+ struct list_head *multi_head, *p;
struct mapent *this;
if (!mm->multi)
return 0;
- pos = NULL;
multi_head = &mm->multi->multi_list;
list_for_each(p, multi_head) {
struct mapent *parent;
this = list_entry(p, struct mapent, multi_list);
- parent = get_parent(this->key, multi_head, &pos);
+ parent = get_offset_parent(mm->mc, this->key);
if (parent)
this->parent = parent;
else

View File

@ -0,0 +1,46 @@
autofs-5.1.7 - simplify mount_subtree() mount check
From: Ian Kent <raven@themaw.net>
The check of the return from sun_mount() following the possible mount
of the root offset in mount_subtree() can be simpler.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 10 +---------
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b1ce7b69..f5c5641a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -13,6 +13,7 @@
- remove unused parameter form do_mount_autofs_offset().
- refactor umount_multi_triggers().
- eliminate clean_stale_multi_triggers().
+- simplify mount_subtree() mount check.
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 f4d5125c..1142e8a3 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1203,15 +1203,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me,
free(ro_loc);
}
- if (ro && rv == 0) {
- ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
- if (ret == -1) {
- error(ap->logopt, MODPREFIX
- "failed to mount offset triggers");
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
- return 1;
- }
- } else if (rv <= 0) {
+ if ((ro && rv == 0) || rv <= 0) {
ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
if (ret == -1) {
error(ap->logopt, MODPREFIX

View File

@ -0,0 +1,414 @@
autofs-5.1.7 - switch to use tree implementation for offsets
From: Ian Kent <raven@themaw.net>
Change to use the tree mapent implementation for the handling
of offset mounts.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1
daemon/automount.c | 25 ++----------
daemon/lookup.c | 2 -
include/automount.h | 8 ++--
lib/cache.c | 67 ---------------------------------
lib/mounts.c | 4 +-
modules/lookup_program.c | 2 -
modules/parse_sun.c | 94 ++++++++++++----------------------------------
8 files changed, 39 insertions(+), 164 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 892f7581..5ac09f77 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -40,6 +40,7 @@
- add tree_mapent_cleanup_offsets().
- add set_offset_tree_catatonic().
- add mount and umount offsets functions.
+- switch to use tree implementation for offsets.
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 f4608fc9..7833dfae 100644
--- a/daemon/automount.c
+++ b/daemon/automount.c
@@ -551,29 +551,15 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
left = 0;
if (me && IS_MM(me)) {
- char root[PATH_MAX + 1];
char key[PATH_MAX + 1];
struct mapent *tmp;
- int status;
- char *base;
-
- if (!strchr(MM_ROOT(me)->key, '/'))
- /* Indirect multi-mount root */
- /* sprintf okay - if it's mounted, it's
- * PATH_MAX or less bytes */
- sprintf(root, "%s/%s", ap->path, MM_ROOT(me)->key);
- else
- strcpy(root, MM_ROOT(me)->key);
-
- if (IS_MM_ROOT(me))
- base = NULL;
- else
- base = me->key + strlen(root);
+ int ret;
- left = umount_multi_triggers(ap, me, root, base);
- if (left) {
+ ret = tree_mapent_umount_offsets(me, 1);
+ if (!ret) {
warn(ap->logopt,
"some offset mounts still present under %s", path);
+ left++;
}
strcpy(key, me->key);
@@ -589,8 +575,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
}
if (!left && IS_MM_ROOT(me)) {
- status = cache_delete_offset_list(mc, me->key);
- if (status != CHE_OK) {
+ if (!tree_mapent_delete_offsets(mc, me->key)) {
warn(ap->logopt, "couldn't delete offset list");
left++;
}
diff --git a/daemon/lookup.c b/daemon/lookup.c
index 5116b927..32dbc24d 100644
--- a/daemon/lookup.c
+++ b/daemon/lookup.c
@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct autofs_point *ap,
return NSS_STATUS_UNKNOWN;
}
- m_key = malloc(ap->len + strlen(MM_ROOT(me)->key) + 2);
+ m_key = malloc(ap->len + MM_ROOT(me)->len + 2);
if (!m_key) {
error(ap->logopt,
"failed to allocate storage for search key");
diff --git a/include/automount.h b/include/automount.h
index f6023e27..a71b8674 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -187,10 +187,10 @@ struct mapent {
ino_t ino;
};
-#define IS_MM(me) (me->multi)
-#define IS_MM_ROOT(me) (me->multi == me)
-#define MM_ROOT(me) (me->multi)
-#define MM_PARENT(me) (me->parent)
+#define IS_MM(me) (me->mm_root)
+#define IS_MM_ROOT(me) (me->mm_root == &me->node)
+#define MM_ROOT(me) (MAPENT(me->mm_root))
+#define MM_PARENT(me) (MAPENT(me->mm_parent))
void cache_lock_cleanup(void *arg);
void cache_readlock(struct mapent_cache *mc);
diff --git a/lib/cache.c b/lib/cache.c
index 7c409a56..93b02daf 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -682,14 +682,6 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k
return CHE_FAIL;
}
- me = cache_lookup_distinct(mc, key);
- if (me) {
- cache_add_ordered_offset(me, &owner->multi_list);
- MM_ROOT(me) = owner;
- goto done;
- }
- ret = CHE_FAIL;
-done:
return ret;
}
@@ -958,65 +950,6 @@ done:
return ret;
}
-/* cache must be write locked by caller */
-int cache_delete_offset_list(struct mapent_cache *mc, const char *key)
-{
- unsigned logopt = mc->ap ? mc->ap->logopt : master_get_logopt();
- struct mapent *me;
- struct mapent *this;
- struct list_head *head, *next;
- int remain = 0;
- int status;
-
- me = cache_lookup_distinct(mc, key);
- if (!me)
- return CHE_FAIL;
-
- /* Not offset list owner */
- if (!IS_MM_ROOT(me))
- return CHE_FAIL;
-
- head = &me->multi_list;
- next = head->next;
- while (next != head) {
- this = list_entry(next, struct mapent, multi_list);
- next = next->next;
- if (this->ioctlfd != -1) {
- error(logopt,
- "active offset mount key %s", this->key);
- return CHE_FAIL;
- }
- }
-
- head = &me->multi_list;
- next = head->next;
- while (next != head) {
- this = list_entry(next, struct mapent, multi_list);
- next = next->next;
- list_del_init(&this->multi_list);
- MM_ROOT(this) = NULL;
- debug(logopt, "deleting offset key %s", this->key);
- status = cache_delete(mc, this->key);
- if (status == CHE_FAIL) {
- warn(logopt,
- "failed to delete offset %s", this->key);
- MM_ROOT(this) = me;
- /* TODO: add list back in */
- remain++;
- }
- }
-
- if (!remain) {
- list_del_init(&me->multi_list);
- MM_ROOT(me) = NULL;
- }
-
- if (remain)
- return CHE_FAIL;
-
- return CHE_OK;
-}
-
void cache_release(struct map_source *map)
{
struct mapent_cache *mc;
diff --git a/lib/mounts.c b/lib/mounts.c
index f7c29475..6ca7eff1 100644
--- a/lib/mounts.c
+++ b/lib/mounts.c
@@ -2893,7 +2893,7 @@ void set_indirect_mount_tree_catatonic(struct autofs_point *ap)
/* Only need to set offset mounts catatonic */
if (IS_MM(me) && IS_MM_ROOT(me))
- set_multi_mount_tree_catatonic(ap, me);
+ set_offset_tree_catatonic(ap, me);
next:
me = cache_enumerate(mc, me);
}
@@ -2913,7 +2913,7 @@ void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me)
{
/* Set offset mounts catatonic for this mapent */
if (IS_MM(me) && IS_MM_ROOT(me))
- set_multi_mount_tree_catatonic(ap, me);
+ set_offset_tree_catatonic(ap, me);
set_mount_catatonic(ap, me, me->ioctlfd);
}
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
index 70f27545..6cab52c8 100644
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -658,7 +658,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
me = cache_lookup_distinct(mc, name);
if (me) {
if (IS_MM(me))
- cache_delete_offset_list(mc, name);
+ tree_mapent_delete_offsets(mc, name);
cache_delete(mc, name);
}
cache_unlock(mc);
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index b1f64ca0..d6ef48b8 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -854,8 +854,8 @@ update_offset_entry(struct autofs_point *ap,
cache_writelock(mc);
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
- if (!cache_set_offset_parent(mc, m_key))
- error(ap->logopt, "failed to set offset parent");
+ if (!tree_mapent_add_node(mc, name, m_key))
+ error(ap->logopt, "failed to add offset %s to tree", m_key);
cache_unlock(mc);
if (ret == CHE_DUPLICATE) {
@@ -1134,10 +1134,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
const char *name, char *loc, char *options, void *ctxt)
{
struct mapent *me;
- struct mapent *ro;
- char *mm_root, *mm_base, *mm_key;
- unsigned int mm_root_len;
- int start, ret = 0, rv;
+ int ret = 0, rv;
cache_readlock(mc);
me = cache_lookup_distinct(mc, name);
@@ -1148,34 +1145,18 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
rv = 0;
- mm_key = MM_ROOT(me)->key;
-
- if (*mm_key == '/') {
- mm_root = mm_key;
- start = strlen(mm_key);
- } else {
- start = ap->len + strlen(mm_key) + 1;
- mm_root = alloca(start + 3);
- strcpy(mm_root, ap->path);
- strcat(mm_root, "/");
- strcat(mm_root, mm_key);
- }
- mm_root_len = strlen(mm_root);
-
if (IS_MM_ROOT(me)) {
char key[PATH_MAX + 1];
+ struct mapent *ro;
+ size_t len;
- if (mm_root_len + 1 > PATH_MAX) {
+ len = mount_fullpath(key, PATH_MAX, ap->path, me->key);
+ if (!len) {
warn(ap->logopt, "path loo long");
return 1;
}
-
- /* name = NULL */
- /* destination = mm_root */
- mm_base = "/";
-
- strcpy(key, mm_root);
- strcat(key, mm_base);
+ key[len] = '/';
+ key[len + 1] = 0;
/* Mount root offset if it exists */
ro = cache_lookup_distinct(me->mc, key);
@@ -1194,7 +1175,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
warn(ap->logopt,
MODPREFIX "failed to parse root offset");
cache_writelock(mc);
- cache_delete_offset_list(mc, name);
+ tree_mapent_delete_offsets(mc, name);
cache_unlock(mc);
return 1;
}
@@ -1209,10 +1190,10 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
free(ro_loc);
}
- if ((ro && rv == 0) || rv <= 0) {
- ret = mount_multi_triggers(ap, me, mm_root, start, mm_base);
- if (ret == -1) {
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+ if (rv <= 0) {
+ ret = tree_mapent_mount_offsets(me, 1);
+ if (!ret) {
+ tree_mapent_cleanup_offsets(me);
cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
@@ -1223,39 +1204,14 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
int loclen = strlen(loc);
int namelen = strlen(name);
- /* name = mm_root + mm_base */
- /* destination = mm_root + mm_base = name */
- mm_base = &me->key[start];
-
+ /* Mounts at nesting points must succeed for subtree
+ * offsets to be mounted.
+ */
rv = sun_mount(ap, name, name, namelen, loc, loclen, options, ctxt);
if (rv == 0) {
- ret = mount_multi_triggers(ap, me->multi, name, start, mm_base);
- if (ret == -1) {
- cleanup_multi_triggers(ap, me, name, start, mm_base);
- cache_unlock(mc);
- error(ap->logopt, MODPREFIX
- "failed to mount offset triggers");
- return 1;
- }
- } else if (rv < 0) {
- char mm_root_base[PATH_MAX + 1];
- unsigned int mm_root_base_len = mm_root_len + strlen(mm_base) + 1;
-
- if (mm_root_base_len > PATH_MAX) {
- cache_unlock(mc);
- warn(ap->logopt, MODPREFIX "path too long");
- cache_writelock(mc);
- cache_delete_offset_list(mc, name);
- cache_unlock(mc);
- return 1;
- }
-
- strcpy(mm_root_base, mm_root);
- strcat(mm_root_base, mm_base);
-
- ret = mount_multi_triggers(ap, me->multi, mm_root_base, start, mm_base);
- if (ret == -1) {
- cleanup_multi_triggers(ap, me, mm_root, start, mm_base);
+ ret = tree_mapent_mount_offsets(me, 1);
+ if (!ret) {
+ tree_mapent_cleanup_offsets(me);
cache_unlock(mc);
error(ap->logopt, MODPREFIX
"failed to mount offset triggers");
@@ -1265,7 +1221,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
}
cache_unlock(mc);
- /* Mount for base of tree failed */
+ /* strict mount failed */
if (rv > 0)
return rv;
@@ -1506,7 +1462,7 @@ dont_expand:
/* So we know we're the multi-mount root */
if (!IS_MM(me))
- me->multi = me;
+ MAPENT_SET_ROOT(me, tree_mapent_root(me))
else {
/*
* The amd host mount type assumes the lookup name
@@ -1556,7 +1512,7 @@ dont_expand:
if (!m_offset) {
warn(ap->logopt, MODPREFIX "null path or out of memory");
cache_writelock(mc);
- cache_delete_offset_list(mc, name);
+ tree_mapent_delete_offsets(mc, name);
cache_unlock(mc);
free(options);
free(pmapent);
@@ -1573,7 +1529,7 @@ dont_expand:
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
if (!l) {
cache_writelock(mc);
- cache_delete_offset_list(mc, name);
+ tree_mapent_delete_offsets(mc, name);
cache_unlock(mc);
free(m_offset);
free(options);
@@ -1592,7 +1548,7 @@ dont_expand:
if (status != CHE_OK) {
warn(ap->logopt, MODPREFIX "error adding multi-mount");
cache_writelock(mc);
- cache_delete_offset_list(mc, name);
+ tree_mapent_delete_offsets(mc, name);
cache_unlock(mc);
free(m_offset);
free(options);

View File

@ -0,0 +1,120 @@
autofs-5.1.7 - use default stack size for threads
From: Ian Kent <raven@themaw.net>
autofs uses PTHREAD_STACK_MIN to set the stack size for threads it
creates.
In two cases it is used to reduce the stack size for long running
service threads while it's used to allocate a larger stack for worker
threads that can have larger memory requirements.
In recent glibc releases PTHREAD_STACK_MIN is no longer a constant
which can lead to unexpectedly different stack sizes on different
architectures and the autofs assumption it's a constant causes a
compile failure.
The need to alter the stack size was due to observed stack overflow
which was thought to be due the thread stack being too small for autofs
and glibc alloca(3) usage.
Quite a bit of that alloca(3) usage has been eliminated from autofs now,
particularly those that might be allocating largish amounts of storage,
and there has been a lot of change in glibc too so using the thread
default stack should be ok.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
daemon/automount.c | 29 -----------------------------
daemon/state.c | 6 +-----
lib/alarm.c | 6 +-----
4 files changed, 3 insertions(+), 39 deletions(-)
--- autofs-5.1.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -79,6 +79,7 @@
- fix nonstrict offset mount fail handling.
- fix concat_options() error handling.
- eliminate some more alloca usage.
+- use default stack size for threads.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/daemon/automount.c
+++ autofs-5.1.7/daemon/automount.c
@@ -84,7 +84,6 @@ static size_t kpkt_len;
/* Attributes for creating detached and joinable threads */
pthread_attr_t th_attr;
pthread_attr_t th_attr_detached;
-size_t detached_thread_stack_size = PTHREAD_STACK_MIN * 144;
struct master_readmap_cond mrc = {
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
@@ -2614,34 +2613,6 @@ int main(int argc, char *argv[])
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);
- }
-
-#ifdef _POSIX_THREAD_ATTR_STACKSIZE
- if (pthread_attr_setstacksize(
- &th_attr_detached, detached_thread_stack_size)) {
- logerr("%s: failed to set stack size thread attribute!",
- program);
- 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);
- }
-#endif
-
- if (pthread_attr_getstacksize(
- &th_attr_detached, &detached_thread_stack_size)) {
- logerr("%s: failed to get detached thread stack size!",
- program);
- 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();
--- autofs-5.1.7.orig/daemon/state.c
+++ autofs-5.1.7/daemon/state.c
@@ -1177,12 +1177,8 @@ int st_start_handler(void)
status = pthread_attr_init(pattrs);
if (status)
pattrs = NULL;
- else {
+ else
pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED);
-#ifdef _POSIX_THREAD_ATTR_STACKSIZE
- pthread_attr_setstacksize(pattrs, PTHREAD_STACK_MIN*4);
-#endif
- }
status = pthread_create(&thid, pattrs, st_queue_handler, NULL);
--- autofs-5.1.7.orig/lib/alarm.c
+++ autofs-5.1.7/lib/alarm.c
@@ -270,12 +270,8 @@ int alarm_start_handler(void)
status = pthread_attr_init(pattrs);
if (status)
pattrs = NULL;
- else {
+ else
pthread_attr_setdetachstate(pattrs, PTHREAD_CREATE_DETACHED);
-#ifdef _POSIX_THREAD_ATTR_STACKSIZE
- pthread_attr_setstacksize(pattrs, PTHREAD_STACK_MIN*4);
-#endif
- }
status = pthread_condattr_init(&condattrs);
if (status)

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.7.orig/CHANGELOG
+++ autofs-5.1.7/CHANGELOG
@@ -70,6 +70,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().
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
--- autofs-5.1.7.orig/include/mounts.h
+++ autofs-5.1.7/include/mounts.h
@@ -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.7.orig/lib/mounts.c
+++ autofs-5.1.7/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.7.orig/modules/parse_sun.c
+++ autofs-5.1.7/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);
}

View File

@ -0,0 +1,74 @@
autofs-5.1.7 - use mount_fullpath() in one spot in parse_mount()
From: Ian Kent <raven@themaw.net>
mount_fullpath() is meant to be used for this type of path construction
so use it.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/parse_sun.c | 34 ++++++++--------------------------
2 files changed, 9 insertions(+), 26 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 444ade5b..8494f0dc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -43,6 +43,7 @@
- switch to use tree implementation for offsets.
- remove obsolete functions.
- remove redundant local var from sun_mount().
+- use mount_fullpath() in one spot 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 437869b5..d3fc6c7f 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -1354,36 +1354,18 @@ dont_expand:
debug(ap->logopt, MODPREFIX "gathered options: %s", options);
if (check_is_multi(p)) {
- char *m_root = NULL;
+ char m_root[PATH_MAX + 1];
int m_root_len;
time_t age;
int l;
- /* If name starts with "/" it's a direct mount */
- if (*name == '/') {
- m_root_len = name_len;
- m_root = alloca(m_root_len + 1);
- if (!m_root) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- free(options);
- free(pmapent);
- logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
- strcpy(m_root, name);
- } else {
- m_root_len = ap->len + name_len + 1;
- m_root = alloca(m_root_len + 1);
- if (!m_root) {
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
- free(options);
- free(pmapent);
- logerr(MODPREFIX "alloca: %s", estr);
- return 1;
- }
- strcpy(m_root, ap->path);
- strcat(m_root, "/");
- strcat(m_root, name);
+ m_root_len = mount_fullpath(m_root, PATH_MAX, ap->path, name);
+ if (!m_root_len) {
+ error(ap->logopt,
+ MODPREFIX "multi-mount root path too long");
+ free(options);
+ free(pmapent);
+ return 1;
}
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);

View File

@ -0,0 +1,76 @@
autofs-5.1.7 - use snprintf() when constructing hosts mapent
From: Ian Kent <raven@themaw.net>
Using multiple strcpy() and strcat() functions when constructing the
hosts map offset for each export is much slower than using a single
sprintf() for each.
Signed-off-by: Ian Kent <raven@themaw.net>
---
CHANGELOG | 1 +
modules/lookup_hosts.c | 26 +++++++++++++-------------
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1bd6ac7f..d613e5ca 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,7 @@
- add xdr_exports().
- remove mount.x and rpcgen dependencies.
- dont use realloc in host exports list processing.
+- use sprintf() when constructing hosts mapent.
25/01/2021 autofs-5.1.7
- make bind mounts propagation slave by default.
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
index e3ee0ab8..c1ebb7f6 100644
--- a/modules/lookup_hosts.c
+++ b/modules/lookup_hosts.c
@@ -87,10 +87,12 @@ int lookup_read_master(struct master *master, time_t age, void *context)
static char *get_exports(struct autofs_point *ap, const char *host)
{
char buf[MAX_ERR_BUF];
+ char entry[PATH_MAX + 1];
char *mapent;
struct exportinfo *exp, *this;
size_t hostlen = strlen(host);
size_t mapent_len;
+ int len, pos;
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
@@ -114,21 +116,19 @@ static char *get_exports(struct autofs_point *ap, const char *host)
}
*mapent = 0;
+ pos = 0;
this = exp;
- while (this) {
- if (!*mapent)
- strcpy(mapent, "\"");
- else
- strcat(mapent, " \"");
- strcat(mapent, this->dir);
- strcat(mapent, "\"");
-
- strcat(mapent, " \"");
- strcat(mapent, host);
- strcat(mapent, ":");
- strcat(mapent, this->dir);
- strcat(mapent, "\"");
+ 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;
}
rpc_exports_free(exp);

2518
SPECS/autofs.spec Normal file

File diff suppressed because it is too large Load Diff