commit
869259cd92
@ -0,0 +1 @@
|
||||
086c327711a7f76692c582264c0742842f3570ba SOURCES/autofs-5.1.7-2.tar.gz
|
@ -0,0 +1 @@
|
||||
SOURCES/autofs-5.1.7-2.tar.gz
|
@ -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'},
|
@ -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);
|
@ -0,0 +1,104 @@
|
||||
autofs-5.1.7 - add ext_mount_hash_mutex lock helpers
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: check_return: Calling "pthread_mutex_lock" without checking
|
||||
return value.
|
||||
|
||||
Well, I use helpers to do this in many places so can't really disagree.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 26 ++++++++++++++++++++------
|
||||
2 files changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index b1b28888..ff44ac25 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -65,6 +65,7 @@
|
||||
- fix double free in parse_mapent().
|
||||
- refactor lookup_prune_one_cache() a bit.
|
||||
- cater for empty mounts list in mnts_get_expire_list().
|
||||
+- add ext_mount_hash_mutex lock helpers.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index 3996eb5e..c24d1a88 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -788,6 +788,20 @@ char *make_mnt_name_string(char *path)
|
||||
return mnt_name;
|
||||
}
|
||||
|
||||
+static void ext_mount_hash_mutex_lock(void)
|
||||
+{
|
||||
+ int status = pthread_mutex_lock(&ext_mount_hash_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+}
|
||||
+
|
||||
+static void ext_mount_hash_mutex_unlock(void)
|
||||
+{
|
||||
+ int status = pthread_mutex_unlock(&ext_mount_hash_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+}
|
||||
+
|
||||
static struct ext_mount *ext_mount_lookup(const char *mp)
|
||||
{
|
||||
uint32_t hval = hash(mp, HASH_SIZE(ext_mounts_hash));
|
||||
@@ -806,7 +820,7 @@ int ext_mount_add(const char *path, const char *umount)
|
||||
struct ext_mount *em;
|
||||
int ret = 0;
|
||||
|
||||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_lock();
|
||||
|
||||
em = ext_mount_lookup(path);
|
||||
if (em) {
|
||||
@@ -840,7 +854,7 @@ int ext_mount_add(const char *path, const char *umount)
|
||||
|
||||
ret = 1;
|
||||
done:
|
||||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -849,7 +863,7 @@ int ext_mount_remove(const char *path)
|
||||
struct ext_mount *em;
|
||||
int ret = 0;
|
||||
|
||||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_lock();
|
||||
|
||||
em = ext_mount_lookup(path);
|
||||
if (!em)
|
||||
@@ -867,7 +881,7 @@ int ext_mount_remove(const char *path)
|
||||
ret = 1;
|
||||
}
|
||||
done:
|
||||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -876,13 +890,13 @@ int ext_mount_inuse(const char *path)
|
||||
struct ext_mount *em;
|
||||
int ret = 0;
|
||||
|
||||
- pthread_mutex_lock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_lock();
|
||||
em = ext_mount_lookup(path);
|
||||
if (!em)
|
||||
goto done;
|
||||
ret = em->ref;
|
||||
done:
|
||||
- pthread_mutex_unlock(&ext_mount_hash_mutex);
|
||||
+ ext_mount_hash_mutex_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
autofs-5.1.7 - add length check in umount_subtree_mounts()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: fixed_size_dest: You might overrun the 4097-character
|
||||
fixed-size string "key" by copying "me->key" without
|
||||
checking the length.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/automount.c | 5 +++++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 224f58d6..9e385ba9 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -55,6 +55,7 @@
|
||||
- fix possible memory leak in master_parse().
|
||||
- fix possible memory leak in mnts_add_amdmount().
|
||||
- fix double unlock in parse_mount().
|
||||
+- add length check in umount_subtree_mounts().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
||||
index 48472d5f..70506d83 100644
|
||||
--- a/daemon/automount.c
|
||||
+++ b/daemon/automount.c
|
||||
@@ -562,6 +562,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi
|
||||
left++;
|
||||
}
|
||||
|
||||
+ if (me->len > PATH_MAX) {
|
||||
+ crit(ap->logopt, "me->key too long for buffer");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
strcpy(key, me->key);
|
||||
|
||||
cache_unlock(mc);
|
@ -0,0 +1,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
|
@ -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
|
@ -0,0 +1,42 @@
|
||||
autofs-5.1.7 - add missing free in handle_mounts()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: error[doubleFree]: Memory pointed to by 'root' is freed twice
|
||||
|
||||
No it's not, but root isn't freed before the fatal call which crashes
|
||||
automount so add a free() before the fatal() call.
|
||||
|
||||
It appears Coverity doesn't recognise pthread_exit() as an exit condition.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/automount.c | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 9c3ede45..62a918a9 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -50,6 +50,7 @@
|
||||
- check for offset with no mount location.
|
||||
- remove mounts_mutex.
|
||||
- remove unused variable from get_exports().
|
||||
+- add missing free in handle_mounts().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
||||
index 28c4d1ee..48472d5f 100644
|
||||
--- a/daemon/automount.c
|
||||
+++ b/daemon/automount.c
|
||||
@@ -1922,6 +1922,8 @@ void *handle_mounts(void *arg)
|
||||
status = pthread_mutex_lock(&suc->mutex);
|
||||
if (status) {
|
||||
logerr("failed to lock startup condition mutex!");
|
||||
+ if (root)
|
||||
+ free(root);
|
||||
fatal(status);
|
||||
}
|
||||
|
@ -0,0 +1,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
|
@ -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)) {
|
@ -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) {
|
@ -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
|
@ -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
|
@ -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
|
@ -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);
|
@ -0,0 +1,34 @@
|
||||
autofs-5.1.7 - also require TCP_REQUESTED when setting NFS port
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Set the NFS service port to the default (2049) only if tcp protocol is
|
||||
being used and not alternate port has been given.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/replicated.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -98,6 +98,7 @@
|
||||
- fix handling of incorrect return from umount_ent().
|
||||
- make NFS version check flags consistent.
|
||||
- refactor get_nfs_info().
|
||||
+- also require TCP_REQUESTED when setting NFS port.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/replicated.c
|
||||
+++ autofs-5.1.7/modules/replicated.c
|
||||
@@ -291,7 +291,7 @@ static unsigned int get_nfs_info(unsigne
|
||||
|
||||
rpc_info->proto = proto;
|
||||
if (port < 0) {
|
||||
- if (version & NFS4_REQUESTED)
|
||||
+ if ((version & NFS4_REQUESTED) && (version & TCP_REQUESTED))
|
||||
rpc_info->port = NFS_PORT;
|
||||
else
|
||||
port = 0;
|
@ -0,0 +1,44 @@
|
||||
autofs-5.1.7 - cater for empty mounts list in mnts_get_expire_list()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: var_deref_model: Passing null pointer "tree" to
|
||||
"tree_traverse_inorder", which dereferences it.
|
||||
|
||||
This obviously can't happen but deal with it anyway to quiet Coverity.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 6 ++++--
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index b79aebc8..b1b28888 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -64,6 +64,7 @@
|
||||
- fix missing lock release in mount_subtree().
|
||||
- fix double free in parse_mapent().
|
||||
- refactor lookup_prune_one_cache() a bit.
|
||||
+- cater for empty mounts list in mnts_get_expire_list().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index 883e3743..3996eb5e 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -1445,8 +1445,10 @@ void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap)
|
||||
}
|
||||
}
|
||||
|
||||
- tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
||||
- tree_free(tree);
|
||||
+ if (tree) {
|
||||
+ tree_traverse_inorder(tree, tree_mnt_expire_list_work, mnts);
|
||||
+ tree_free(tree);
|
||||
+ }
|
||||
done:
|
||||
mnts_hash_mutex_unlock();
|
||||
}
|
@ -0,0 +1,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);
|
@ -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;
|
@ -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);
|
||||
|
@ -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
|
@ -0,0 +1,45 @@
|
||||
autofs-5.1.7 - dont try umount after stat() ENOENT fail
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: Calling function "umount" that uses "me->key" after a check
|
||||
function. This can cause a time-of-check, time-of-use race
|
||||
condition.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/direct.c | 6 +++++-
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 7add6c55..c7bc0c39 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -57,6 +57,7 @@
|
||||
- fix double unlock in parse_mount().
|
||||
- add length check in umount_subtree_mounts().
|
||||
- fix flags check in umount_multi().
|
||||
+- dont try umount after stat() ENOENT fail.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
||||
index a33f9f91..3bd714e6 100644
|
||||
--- a/daemon/direct.c
|
||||
+++ b/daemon/direct.c
|
||||
@@ -739,9 +739,13 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
||||
|
||||
ret = stat(me->key, &st);
|
||||
if (ret == -1) {
|
||||
+ int save_errno = errno;
|
||||
+
|
||||
error(ap->logopt,
|
||||
"failed to stat direct mount trigger %s", me->key);
|
||||
- goto out_umount;
|
||||
+ if (save_errno != ENOENT)
|
||||
+ goto out_umount;
|
||||
+ goto out_err;
|
||||
}
|
||||
|
||||
ops->open(ap->logopt, &ioctlfd, st.st_dev, me->key);
|
@ -0,0 +1,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
@ -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,
|
@ -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);
|
||||
}
|
@ -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;
|
@ -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;
|
@ -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 */
|
@ -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);
|
@ -0,0 +1,40 @@
|
||||
autofs-5.1.7 - fix arg not used in error print
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: extra_argument: This argument was not used by the format
|
||||
string: "key".
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 4 +---
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index f11aa1c7..1d56c96f 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -60,6 +60,7 @@
|
||||
- dont try umount after stat() ENOENT fail.
|
||||
- remove redundant assignment in master_add_amd_mount_section_mounts().
|
||||
- fix dead code in mnts_add_mount().
|
||||
+- fix arg not used in error print.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index 018b9c80..883e3743 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -1519,9 +1519,7 @@ int tree_mapent_add_node(struct mapent_cache *mc,
|
||||
}
|
||||
|
||||
if (MAPENT_ROOT(base) != MAPENT_NODE(base)) {
|
||||
- error(logopt,
|
||||
- "failed to find multi-mount root of offset tree",
|
||||
- key);
|
||||
+ error(logopt, "key %s is not multi-mount root", root);
|
||||
return 0;
|
||||
}
|
||||
tree = MAPENT_ROOT(base);
|
@ -0,0 +1,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;
|
||||
}
|
@ -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
|
@ -0,0 +1,55 @@
|
||||
autofs-5.1.7 - fix dead code in mnts_add_mount()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: dead_error_line: Execution cannot reach this statement: "free(mp);".
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 8 ++------
|
||||
2 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index f95b1aa6..f11aa1c7 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -59,6 +59,7 @@
|
||||
- fix flags check in umount_multi().
|
||||
- dont try umount after stat() ENOENT fail.
|
||||
- remove redundant assignment in master_add_amd_mount_section_mounts().
|
||||
+- fix dead code in mnts_add_mount().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index ef69cec1..018b9c80 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -1205,13 +1205,13 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
||||
if (*name == '/') {
|
||||
mp = strdup(name);
|
||||
if (!mp)
|
||||
- goto fail;
|
||||
+ return NULL;
|
||||
} else {
|
||||
int len = ap->len + strlen(name) + 2;
|
||||
|
||||
mp = malloc(len);
|
||||
if (!mp)
|
||||
- goto fail;
|
||||
+ return NULL;
|
||||
strcpy(mp, ap->path);
|
||||
strcat(mp, "/");
|
||||
strcat(mp, name);
|
||||
@@ -1228,10 +1228,6 @@ struct mnt_list *mnts_add_mount(struct autofs_point *ap,
|
||||
free(mp);
|
||||
|
||||
return this;
|
||||
-fail:
|
||||
- if (mp)
|
||||
- free(mp);
|
||||
- return NULL;
|
||||
}
|
||||
|
||||
void mnts_remove_mount(const char *mp, unsigned int flags)
|
@ -0,0 +1,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);
|
@ -0,0 +1,39 @@
|
||||
autofs-5.1.7 - fix double free in parse_mapent()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity:
|
||||
in parse_mapent(): double_free: Calling "free" frees pointer "newopt"
|
||||
which has already been freed.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_sun.c | 2 --
|
||||
2 files changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index ff3d88eb..81461978 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -62,6 +62,7 @@
|
||||
- fix dead code in mnts_add_mount().
|
||||
- fix arg not used in error print.
|
||||
- fix missing lock release in mount_subtree().
|
||||
+- fix double free in parse_mapent().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
||||
index 5d15f892..03a63290 100644
|
||||
--- a/modules/parse_sun.c
|
||||
+++ b/modules/parse_sun.c
|
||||
@@ -974,8 +974,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
|
||||
estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
error(logopt, MODPREFIX
|
||||
"concat_options: %s", estr);
|
||||
- if (newopt)
|
||||
- free(newopt);
|
||||
free(myoptions);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
autofs-5.1.7 - fix double unlock in parse_mount()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: double_unlock: "cache_unlock" unlocks "mc->rwlock" while it
|
||||
is unlocked.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_sun.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 2e3b9fd7..224f58d6 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -54,6 +54,7 @@
|
||||
- remove redundant if check.
|
||||
- fix possible memory leak in master_parse().
|
||||
- fix possible memory leak in mnts_add_amdmount().
|
||||
+- fix double unlock in parse_mount().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
||||
index a81d4028..05f53fc2 100644
|
||||
--- a/modules/parse_sun.c
|
||||
+++ b/modules/parse_sun.c
|
||||
@@ -1526,7 +1526,6 @@ dont_expand:
|
||||
if (!loc) {
|
||||
free(options);
|
||||
free(pmapent);
|
||||
- cache_unlock(mc);
|
||||
warn(ap->logopt, MODPREFIX "out of memory");
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
autofs-5.1.7 - fix flags check in umount_multi()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: operator_confusion: "ap->flags | 1" is always 1/true
|
||||
regardless of the values of its operand.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/automount.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 9e385ba9..7add6c55 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -56,6 +56,7 @@
|
||||
- fix possible memory leak in mnts_add_amdmount().
|
||||
- fix double unlock in parse_mount().
|
||||
- add length check in umount_subtree_mounts().
|
||||
+- fix flags check in umount_multi().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
||||
index 70506d83..23235a7d 100644
|
||||
--- a/daemon/automount.c
|
||||
+++ b/daemon/automount.c
|
||||
@@ -662,7 +662,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl)
|
||||
/* Check if the autofs mount has browse mode enabled.
|
||||
* If so re-create the directory entry.
|
||||
*/
|
||||
- if (ap->flags | MOUNT_FLAG_GHOST) {
|
||||
+ if (ap->flags & MOUNT_FLAG_GHOST) {
|
||||
int ret;
|
||||
|
||||
/* If the browse directory create fails log an
|
@ -0,0 +1,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);
|
||||
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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;
|
@ -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)
|
@ -0,0 +1,36 @@
|
||||
autofs-5.1.7 - fix missing lock release in mount_subtree()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Covarity: missing_unlock: Returning without unlocking "mc->rwlock".
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_sun.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 1d56c96f..ff3d88eb 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -61,6 +61,7 @@
|
||||
- remove redundant assignment in master_add_amd_mount_section_mounts().
|
||||
- fix dead code in mnts_add_mount().
|
||||
- fix arg not used in error print.
|
||||
+- fix missing lock release in mount_subtree().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
||||
index 05f53fc2..5d15f892 100644
|
||||
--- a/modules/parse_sun.c
|
||||
+++ b/modules/parse_sun.c
|
||||
@@ -1105,6 +1105,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent_cache *mc,
|
||||
len = mount_fullpath(key, PATH_MAX, ap->path, ap->len, me->key);
|
||||
if (!len) {
|
||||
warn(ap->logopt, "path loo long");
|
||||
+ cache_unlock(mc);
|
||||
return 1;
|
||||
}
|
||||
key[len] = '/';
|
@ -0,0 +1,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) {
|
@ -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;
|
@ -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)
|
@ -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);
|
@ -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);
|
@ -0,0 +1,38 @@
|
||||
autofs-5.1.7 - fix possible memory leak in master_parse()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: Overwriting "path" in "path = master_strdup(yyvsp[-1].strtype)"
|
||||
leaks the storage that "path" points to.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/master_parse.y | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 2186cbe3..b797f6dc 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -52,6 +52,7 @@
|
||||
- remove unused variable from get_exports().
|
||||
- add missing free in handle_mounts().
|
||||
- remove redundant if check.
|
||||
+- fix possible memory leak in master_parse().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
|
||||
index 08e44b57..7480c36a 100644
|
||||
--- a/daemon/master_parse.y
|
||||
+++ b/daemon/master_parse.y
|
||||
@@ -155,6 +155,8 @@ file: {
|
||||
line:
|
||||
| PATH mapspec
|
||||
{
|
||||
+ if (path)
|
||||
+ free(path);
|
||||
path = master_strdup($1);
|
||||
if (!path) {
|
||||
local_free_vars();
|
@ -0,0 +1,58 @@
|
||||
autofs-5.1.7 - fix possible memory leak in mnts_add_amdmount()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: leaked_storage: Variable "ext_mp" going out of scope leaks
|
||||
the storage it points to.
|
||||
|
||||
Same applies to the other duped fields destined for the mnt_list struct.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 20 ++++++++++----------
|
||||
2 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index b797f6dc..2e3b9fd7 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -53,6 +53,7 @@
|
||||
- add missing free in handle_mounts().
|
||||
- remove redundant if check.
|
||||
- fix possible memory leak in master_parse().
|
||||
+- fix possible memory leak in mnts_add_amdmount().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index c8a7bf00..ef69cec1 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -1119,16 +1119,16 @@ struct mnt_list *mnts_add_amdmount(struct autofs_point *ap, struct amd_entry *en
|
||||
|
||||
mnts_hash_mutex_lock();
|
||||
this = mnts_get_mount(entry->path);
|
||||
- if (this) {
|
||||
- this->ext_mp = ext_mp;
|
||||
- this->amd_pref = pref;
|
||||
- this->amd_type = type;
|
||||
- this->amd_opts = opts;
|
||||
- this->amd_cache_opts = entry->cache_opts;
|
||||
- this->flags |= MNTS_AMD_MOUNT;
|
||||
- if (list_empty(&this->amdmount))
|
||||
- list_add_tail(&this->amdmount, &ap->amdmounts);
|
||||
- }
|
||||
+ if (!this)
|
||||
+ goto fail;
|
||||
+ this->ext_mp = ext_mp;
|
||||
+ this->amd_pref = pref;
|
||||
+ this->amd_type = type;
|
||||
+ this->amd_opts = opts;
|
||||
+ this->amd_cache_opts = entry->cache_opts;
|
||||
+ this->flags |= MNTS_AMD_MOUNT;
|
||||
+ if (list_empty(&this->amdmount))
|
||||
+ list_add_tail(&this->amdmount, &ap->amdmounts);
|
||||
mnts_hash_mutex_unlock();
|
||||
|
||||
return this;
|
@ -0,0 +1,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 &&
|
@ -0,0 +1,65 @@
|
||||
autofs-5.1.7 - make NFS version check flags consistent
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Several of the NFS connection macros have the same value so that they
|
||||
can be used as internal code documentation of what is being done.
|
||||
|
||||
Adjust the protocol macro naming to be consistent in a few places.
|
||||
|
||||
Also make sure the correct flags are set for the function they indicate.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/mount_nfs.c | 16 +++++++++-------
|
||||
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -96,6 +96,7 @@
|
||||
- fix sysconf(3) return handling.
|
||||
- remove nonstrict parameter from tree_mapent_umount_offsets().
|
||||
- fix handling of incorrect return from umount_ent().
|
||||
+- make NFS version check flags consistent.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/mount_nfs.c
|
||||
+++ autofs-5.1.7/modules/mount_nfs.c
|
||||
@@ -178,18 +178,20 @@ int mount_mount(struct autofs_point *ap,
|
||||
port = 0;
|
||||
} else if (_strncmp("proto=udp", cp, o_len) == 0 ||
|
||||
_strncmp("udp", cp, o_len) == 0) {
|
||||
- vers &= ~TCP_SUPPORTED;
|
||||
+ vers &= ~TCP_REQUESTED;
|
||||
+ vers |= UDP_REQUESTED;
|
||||
} else if (_strncmp("proto=udp6", cp, o_len) == 0 ||
|
||||
_strncmp("udp6", cp, o_len) == 0) {
|
||||
- vers &= ~TCP_SUPPORTED;
|
||||
- vers |= UDP6_REQUESTED;
|
||||
+ vers &= ~(TCP_REQUESTED|TCP6_REQUESTED);
|
||||
+ vers |= (UDP_REQUESTED|UDP6_REQUESTED);
|
||||
} else if (_strncmp("proto=tcp", cp, o_len) == 0 ||
|
||||
_strncmp("tcp", cp, o_len) == 0) {
|
||||
- vers &= ~UDP_SUPPORTED;
|
||||
+ vers &= ~UDP_REQUESTED;
|
||||
+ vers |= TCP_REQUESTED;
|
||||
} else if (_strncmp("proto=tcp6", cp, o_len) == 0 ||
|
||||
_strncmp("tcp6", cp, o_len) == 0) {
|
||||
- vers &= ~UDP_SUPPORTED;
|
||||
- vers |= TCP6_REQUESTED;
|
||||
+ vers &= ~(UDP_REQUESTED|UDP6_REQUESTED);
|
||||
+ vers |= TCP_REQUESTED|TCP6_REQUESTED;
|
||||
}
|
||||
/* Check for options that also make sense
|
||||
with bind mounts */
|
||||
@@ -246,7 +248,7 @@ int mount_mount(struct autofs_point *ap,
|
||||
mount_default_proto == 4 &&
|
||||
(vers & NFS_VERS_MASK) != 0 &&
|
||||
(vers & NFS4_VERS_MASK) != 0 &&
|
||||
- !(vers & UDP6_REQUESTED)) {
|
||||
+ !(vers & (UDP_REQUESTED|UDP6_REQUESTED))) {
|
||||
unsigned int v4_probe_ok = 0;
|
||||
struct host *tmp = new_host(hosts->name, 0,
|
||||
hosts->addr, hosts->addr_len,
|
@ -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();
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
@ -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");
|
@ -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 {
|
@ -0,0 +1,202 @@
|
||||
autofs-5.1.7 - refactor get_nfs_info()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Make getting a portmap client and getting a service port from portmap
|
||||
helper functions and simplify the return handling.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1
|
||||
modules/replicated.c | 135 ++++++++++++++++++++++++++++-----------------------
|
||||
2 files changed, 76 insertions(+), 60 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -97,6 +97,7 @@
|
||||
- remove nonstrict parameter from tree_mapent_umount_offsets().
|
||||
- fix handling of incorrect return from umount_ent().
|
||||
- make NFS version check flags consistent.
|
||||
+- refactor get_nfs_info().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/replicated.c
|
||||
+++ autofs-5.1.7/modules/replicated.c
|
||||
@@ -223,6 +223,49 @@ void free_host_list(struct host **list)
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
+static unsigned int get_portmap_client(unsigned logopt,
|
||||
+ struct conn_info *pm_info, struct host *host,
|
||||
+ int proto)
|
||||
+{
|
||||
+ unsigned int status;
|
||||
+
|
||||
+ /* On success client is stored in pm_info->client */
|
||||
+ status = rpc_portmap_getclient(pm_info,
|
||||
+ host->name, host->addr, host->addr_len,
|
||||
+ proto, RPC_CLOSE_DEFAULT);
|
||||
+ if (status == -EHOSTUNREACH)
|
||||
+ debug(logopt,
|
||||
+ "host not reachable getting portmap client");
|
||||
+ else if (status)
|
||||
+ debug(logopt, "error 0x%d getting portmap client");
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static unsigned int get_portmap_port(unsigned logopt,
|
||||
+ struct conn_info *pm_info, struct pmap *parms,
|
||||
+ unsigned long vers, unsigned int version,
|
||||
+ short unsigned int *port)
|
||||
+{
|
||||
+ unsigned int status;
|
||||
+ short unsigned int nfs_port;
|
||||
+
|
||||
+ parms->pm_vers = vers;
|
||||
+ status = rpc_portmap_getport(pm_info, parms, &nfs_port);
|
||||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
||||
+ debug(logopt,
|
||||
+ "host not reachable or timed out getting service port");
|
||||
+ } else if (status < 0) {
|
||||
+ if (!(version & NFS_VERS_MASK))
|
||||
+ debug(logopt, "error 0x%d getting service port");
|
||||
+ }
|
||||
+
|
||||
+ if (!status)
|
||||
+ *port = nfs_port;
|
||||
+
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
static unsigned int get_nfs_info(unsigned logopt, struct host *host,
|
||||
struct conn_info *pm_info, struct conn_info *rpc_info,
|
||||
int proto, unsigned int version, int port)
|
||||
@@ -263,33 +306,20 @@ static unsigned int get_nfs_info(unsigne
|
||||
goto v3_ver;
|
||||
|
||||
if (!port) {
|
||||
- status = rpc_portmap_getclient(pm_info,
|
||||
- host->name, host->addr, host->addr_len,
|
||||
- proto, RPC_CLOSE_DEFAULT);
|
||||
- if (status == -EHOSTUNREACH) {
|
||||
- debug(logopt,
|
||||
- "host not reachable getting portmap client");
|
||||
- supported = status;
|
||||
- goto done_ver;
|
||||
- } else if (status) {
|
||||
- debug(logopt, "error 0x%d getting portmap client");
|
||||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH)
|
||||
+ supported = status;
|
||||
goto done_ver;
|
||||
}
|
||||
- parms.pm_vers = NFS4_VERSION;
|
||||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
||||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
||||
- debug(logopt,
|
||||
- "host not reachable or timed out getting service port");
|
||||
- supported = status;
|
||||
- goto done_ver;
|
||||
- } else if (status < 0) {
|
||||
- if (version & NFS_VERS_MASK)
|
||||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
||||
+ NFS4_VERSION, version, &rpc_info->port);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
||||
+ supported = status;
|
||||
+ if (status < 0 && version & NFS_VERS_MASK)
|
||||
goto v3_ver; /* MOUNT_NFS_DEFAULT_PROTOCOL=4 */
|
||||
- else {
|
||||
- debug(logopt,
|
||||
- "error 0x%d getting service port");
|
||||
- goto done_ver;
|
||||
- }
|
||||
+ goto done_ver;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,31 +364,22 @@ v3_ver:
|
||||
goto v2_ver;
|
||||
|
||||
if (!port && !pm_info->client) {
|
||||
- status = rpc_portmap_getclient(pm_info,
|
||||
- host->name, host->addr, host->addr_len,
|
||||
- proto, RPC_CLOSE_DEFAULT);
|
||||
- if (status == -EHOSTUNREACH) {
|
||||
- debug(logopt,
|
||||
- "host not reachable getting portmap client");
|
||||
- supported = status;
|
||||
- goto done_ver;
|
||||
- } else if (status) {
|
||||
- debug(logopt,
|
||||
- "error 0x%d getting getting portmap client");
|
||||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH)
|
||||
+ supported = status;
|
||||
goto done_ver;
|
||||
}
|
||||
}
|
||||
|
||||
if (!port) {
|
||||
- parms.pm_vers = NFS3_VERSION;
|
||||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
||||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
||||
- debug(logopt,
|
||||
- "host not reachable or timed out getting service port");
|
||||
- supported = status;
|
||||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
||||
+ NFS3_VERSION, version, &rpc_info->port);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
||||
+ supported = status;
|
||||
goto done_ver;
|
||||
- } else if (status < 0)
|
||||
- goto v2_ver;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (rpc_info->proto == IPPROTO_UDP)
|
||||
@@ -399,28 +420,22 @@ v2_ver:
|
||||
goto done_ver;
|
||||
|
||||
if (!port && !pm_info->client) {
|
||||
- status = rpc_portmap_getclient(pm_info,
|
||||
- host->name, host->addr, host->addr_len,
|
||||
- proto, RPC_CLOSE_DEFAULT);
|
||||
- if (status == -EHOSTUNREACH) {
|
||||
- debug(logopt,
|
||||
- "host not reachable getting portmap client");
|
||||
- supported = status;
|
||||
- goto done_ver;
|
||||
- } else if (status)
|
||||
+ status = get_portmap_client(logopt, pm_info, host, proto);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH)
|
||||
+ supported = status;
|
||||
goto done_ver;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!port) {
|
||||
- parms.pm_vers = NFS2_VERSION;
|
||||
- status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port);
|
||||
- if (status == -EHOSTUNREACH || status == -ETIMEDOUT) {
|
||||
- debug(logopt,
|
||||
- "host not reachable or timed out getting service port");
|
||||
- supported = status;
|
||||
- goto done_ver;
|
||||
- } else if (status < 0)
|
||||
+ status = get_portmap_port(logopt, pm_info, &parms,
|
||||
+ NFS2_VERSION, version, &rpc_info->port);
|
||||
+ if (status) {
|
||||
+ if (status == -EHOSTUNREACH || status == -ETIMEDOUT)
|
||||
+ supported = status;
|
||||
goto done_ver;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (rpc_info->proto == IPPROTO_UDP)
|
@ -0,0 +1,75 @@
|
||||
autofs-5.1.7 - refactor lookup_prune_one_cache() a bit
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: use: Using an unreliable value of "me" inside the second locked
|
||||
section.
|
||||
|
||||
Change lookup_prune_one_cache() a little, move the location the next
|
||||
key is set (before releasing the lock) and add a comment explaining
|
||||
why we don't care about the side effects of the read lock release/
|
||||
write lock aquire/write lock release/read lock reaquire.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 20 +++++++++++++++++++-
|
||||
2 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 81461978..b79aebc8 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -63,6 +63,7 @@
|
||||
- fix arg not used in error print.
|
||||
- fix missing lock release in mount_subtree().
|
||||
- fix double free in parse_mapent().
|
||||
+- refactor lookup_prune_one_cache() a bit.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
||||
index 32dbc24d..3e9722e4 100644
|
||||
--- a/daemon/lookup.c
|
||||
+++ b/daemon/lookup.c
|
||||
@@ -1375,7 +1375,6 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
||||
}
|
||||
|
||||
key = strdup(me->key);
|
||||
- me = cache_enumerate(mc, me);
|
||||
/* Don't consider any entries with a wildcard */
|
||||
if (!key || strchr(key, '*')) {
|
||||
if (key)
|
||||
@@ -1422,6 +1421,7 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
||||
if (valid)
|
||||
cache_unlock(valid->mc);
|
||||
|
||||
+ me = cache_enumerate(mc, me);
|
||||
if (me)
|
||||
next_key = strdup(me->key);
|
||||
|
||||
@@ -1456,6 +1456,24 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
||||
next:
|
||||
cache_readlock(mc);
|
||||
if (next_key) {
|
||||
+ /* The lock release and reaquire above can mean
|
||||
+ * a number of things could happen.
|
||||
+ *
|
||||
+ * First, mapents could be added between the
|
||||
+ * current mapent and the mapent of next_key.
|
||||
+ * Don't care about that because there's no
|
||||
+ * need to prune newly added entries.
|
||||
+ *
|
||||
+ * Second, the next mapent data could have
|
||||
+ * changed. Don't care about that either since
|
||||
+ * we are looking to prune stale map entries
|
||||
+ * and don't care when they become stale.
|
||||
+ *
|
||||
+ * Finally, the mapent of next_key could have
|
||||
+ * gone away. Again don't care about this either,
|
||||
+ * the loop will exit prematurely so just wait
|
||||
+ * until the next prune and try again.
|
||||
+ */
|
||||
me = cache_lookup_distinct(mc, next_key);
|
||||
free(next_key);
|
||||
}
|
@ -0,0 +1,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;
|
||||
}
|
||||
-
|
@ -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;
|
||||
}
|
@ -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)
|
||||
{
|
@ -0,0 +1,40 @@
|
||||
autofs-5.1.7 - remove redundant assignment in master_add_amd_mount_section_mounts()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: missing_lock: Accessing "entry->current" without holding lock
|
||||
"master_mapent.current_mutex".
|
||||
|
||||
This is initialization not clearing current source. But the field has
|
||||
already been initialized in the master_new_mapent() call.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/master.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index c7bc0c39..f95b1aa6 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -58,6 +58,7 @@
|
||||
- add length check in umount_subtree_mounts().
|
||||
- fix flags check in umount_multi().
|
||||
- dont try umount after stat() ENOENT fail.
|
||||
+- remove redundant assignment in master_add_amd_mount_section_mounts().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/master.c b/daemon/master.c
|
||||
index 30d7cf98..84743f80 100644
|
||||
--- a/daemon/master.c
|
||||
+++ b/daemon/master.c
|
||||
@@ -996,7 +996,6 @@ static void master_add_amd_mount_section_mounts(struct master *master, time_t ag
|
||||
source->master_line = 0;
|
||||
|
||||
entry->age = age;
|
||||
- entry->current = NULL;
|
||||
|
||||
master_add_mapent(master, entry);
|
||||
next:
|
@ -0,0 +1,40 @@
|
||||
autofs-5.1.7 - remove redundant if check
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity: identical code in if condition branches.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/direct.c | 5 +----
|
||||
2 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 62a918a9..2186cbe3 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -51,6 +51,7 @@
|
||||
- remove mounts_mutex.
|
||||
- remove unused variable from get_exports().
|
||||
- add missing free in handle_mounts().
|
||||
+- remove redundant if check.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
||||
index 3f4f5704..a33f9f91 100644
|
||||
--- a/daemon/direct.c
|
||||
+++ b/daemon/direct.c
|
||||
@@ -752,10 +752,7 @@ int mount_autofs_offset(struct autofs_point *ap, struct mapent *me)
|
||||
|
||||
ops->timeout(ap->logopt, ioctlfd, timeout);
|
||||
cache_set_ino_index(me->mc, me->key, st.st_dev, st.st_ino);
|
||||
- if (ap->logopt & LOGOPT_DEBUG)
|
||||
- notify_mount_result(ap, me->key, timeout, str_offset);
|
||||
- else
|
||||
- notify_mount_result(ap, me->key, timeout, str_offset);
|
||||
+ notify_mount_result(ap, me->key, timeout, str_offset);
|
||||
ops->close(ap->logopt, ioctlfd);
|
||||
|
||||
debug(ap->logopt, "mounted trigger %s", me->key);
|
@ -0,0 +1,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);
|
||||
|
@ -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 {
|
@ -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);
|
@ -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;
|
@ -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);
|
@ -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 */
|
@ -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.
|
@ -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) == '/'));
|
||||
|
@ -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();
|
@ -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);
|
||||
|
@ -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
|
@ -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
|
@ -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);
|
@ -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)
|
@ -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);
|
||||
}
|
@ -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);
|
@ -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);
|
@ -0,0 +1,35 @@
|
||||
autofs-5.1.8 - avoid calling pthread_getspecific() with NULL key_thread_attempt_id
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Don't call pthread_getspecific() if key_thread_attempt_id is NULL in
|
||||
case the pthread_getspecific() implementation doesn't check for this.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/log.c | 3 +++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -92,6 +92,7 @@
|
||||
- simplify cache_add() a little.
|
||||
- fix use after free in tree_mapent_delete_offset_tree().
|
||||
- fix memory leak in xdr_exports().
|
||||
+- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/lib/log.c
|
||||
+++ autofs-5.1.7/lib/log.c
|
||||
@@ -38,6 +38,9 @@ static char *prepare_attempt_prefix(cons
|
||||
char buffer[ATTEMPT_ID_SIZE + 1];
|
||||
char *prefixed_msg = NULL;
|
||||
|
||||
+ if (!key_thread_attempt_id)
|
||||
+ return NULL;
|
||||
+
|
||||
attempt_id = pthread_getspecific(key_thread_attempt_id);
|
||||
if (attempt_id) {
|
||||
int len = sizeof(buffer) + 1 + strlen(msg) + 1;
|
@ -0,0 +1,34 @@
|
||||
autofs-5.1.8 - bailout on rpc systemerror
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
If there's a system error (eg. oversize packet received) just give up
|
||||
since redoing the call would likely end up with the same error.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/rpc_subs.c | 2 ++
|
||||
2 files changed, 3 insertions(+)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -99,6 +99,7 @@
|
||||
- make NFS version check flags consistent.
|
||||
- refactor get_nfs_info().
|
||||
- also require TCP_REQUESTED when setting NFS port.
|
||||
+- bailout on rpc systemerror.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/lib/rpc_subs.c
|
||||
+++ autofs-5.1.7/lib/rpc_subs.c
|
||||
@@ -1200,6 +1200,8 @@ static int rpc_get_exports_proto(struct
|
||||
info->timeout);
|
||||
if (status == RPC_SUCCESS)
|
||||
break;
|
||||
+ if (status == RPC_SYSTEMERROR)
|
||||
+ break;
|
||||
if (++vers_entry > 2)
|
||||
break;
|
||||
CLNT_CONTROL(client, CLSET_VERS,
|
@ -0,0 +1,32 @@
|
||||
autofs-5.1.8 - coverity fix for invalid access
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Fix invalid access in modules/parse_amd.c:do_host_mount().
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/parse_amd.c | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -106,6 +106,7 @@
|
||||
- fix missing unlock in sasl_do_kinit_ext_cc().
|
||||
- fix parse module instance mutex naming.
|
||||
- serialise lookup module open and reinit.
|
||||
+- coverity fix for invalid access.
|
||||
|
||||
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
|
||||
@@ -1366,7 +1366,6 @@ static int do_host_mount(struct autofs_p
|
||||
if (!instance) {
|
||||
error(ap->logopt, MODPREFIX
|
||||
"failed to create source instance for hosts map");
|
||||
- close_lookup(lookup);
|
||||
goto out;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
autofs-5.1.8 - dont fail on duplicate host export entry
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
If we encounter a duplicate host export entry don't fail, just ignore
|
||||
it and return the duplicate.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 6 ++++--
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -87,6 +87,7 @@
|
||||
- fix root offset error handling.
|
||||
- fix fix root offset error handling.
|
||||
- fix nonstrict fail handling of last offset mount.
|
||||
+- dont fail on duplicate offset entry tree add.
|
||||
|
||||
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
|
||||
@@ -1341,7 +1341,7 @@ static struct tree_node *tree_add_node(s
|
||||
}
|
||||
|
||||
if (!eq)
|
||||
- error(LOGOPT_ANY, "cannot add duplicate entry to tree");
|
||||
+ return p;
|
||||
else {
|
||||
if (eq < 0)
|
||||
return tree_add_left(p, ptr);
|
||||
@@ -1515,8 +1515,10 @@ static int tree_host_cmp(struct tree_nod
|
||||
int eq;
|
||||
|
||||
eq = strcmp(exp->dir, n_exp->dir);
|
||||
- if (!eq)
|
||||
+ if (!eq) {
|
||||
+ error(LOGOPT_ANY, "duplicate entry %s ignored", exp->dir);
|
||||
return 0;
|
||||
+ }
|
||||
return (exp_len < n_exp_len) ? -1 : 1;
|
||||
}
|
||||
|
@ -0,0 +1,131 @@
|
||||
autofs-5.1.8 - dont use initgroups() at spawn
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The initgroups(3) function isn't safe to use between fork() and
|
||||
exec() in a threaded program.
|
||||
|
||||
Using it this way often leads to a hang for even moderate work
|
||||
loads.
|
||||
|
||||
But the getgrouplist()/setgroups() combination can be used safely
|
||||
in this case and this patch changes autofs to use these (the safety
|
||||
of using of setgroups() is yet to to be documented).
|
||||
|
||||
A large portion of the work on this patch has been contributed
|
||||
by Roberto Bergantinos <rbergant@redhat.com>.
|
||||
|
||||
Reported-by: Roberto Bergantinos <rbergant@redhat.com>
|
||||
Fixes: 6343a3292020 ("autofs-5.1.3 - fix ordering of seteuid/setegid in do_spawn()")
|
||||
Signed-off-by: Roberto Bergantinos <rbergant@redhat.com>
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/spawn.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
2 files changed, 48 insertions(+), 4 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -101,6 +101,7 @@
|
||||
- also require TCP_REQUESTED when setting NFS port.
|
||||
- bailout on rpc systemerror.
|
||||
- fix nfsv4 only mounts should not use rpcbind.
|
||||
+- dont use initgroups() at spawn.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/daemon/spawn.c
|
||||
+++ autofs-5.1.7/daemon/spawn.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mount.h>
|
||||
+#include <pwd.h>
|
||||
|
||||
#include "automount.h"
|
||||
|
||||
@@ -335,6 +336,10 @@ static int do_spawn(unsigned logopt, uns
|
||||
struct thread_stdenv_vars *tsv;
|
||||
pid_t euid = 0;
|
||||
gid_t egid = 0;
|
||||
+ gid_t *groups = NULL;
|
||||
+ gid_t *saved_groups = NULL;
|
||||
+ int ngroups = 0;
|
||||
+ int nsaved_groups = 0;
|
||||
|
||||
if (open_pipe(pipefd))
|
||||
return -1;
|
||||
@@ -357,6 +362,31 @@ static int do_spawn(unsigned logopt, uns
|
||||
}
|
||||
|
||||
open_mutex_lock();
|
||||
+
|
||||
+ if (euid) {
|
||||
+ struct passwd *pwd;
|
||||
+
|
||||
+ pwd = getpwuid(getuid());
|
||||
+ if (!pwd)
|
||||
+ fprintf(stderr,
|
||||
+ "warning: getpwuid: can't get current username\n");
|
||||
+ else {
|
||||
+ /* get number of groups for current gid */
|
||||
+ getgrouplist(pwd->pw_name, getgid(), NULL, &nsaved_groups);
|
||||
+ saved_groups = malloc(nsaved_groups * sizeof(gid_t));
|
||||
+
|
||||
+ /* get current gid groups list */
|
||||
+ getgrouplist(pwd->pw_name, getgid(), saved_groups, &nsaved_groups);
|
||||
+ }
|
||||
+
|
||||
+ /* get number of groups of mount triggering process */
|
||||
+ getgrouplist(tsv->user, egid, NULL, &ngroups);
|
||||
+ groups = malloc(ngroups * sizeof(gid_t));
|
||||
+
|
||||
+ /* get groups list of mount triggering process */
|
||||
+ getgrouplist(tsv->user, egid, groups, &ngroups);
|
||||
+ }
|
||||
+
|
||||
f = fork();
|
||||
if (f == 0) {
|
||||
char **pargv = (char **) argv;
|
||||
@@ -398,10 +428,13 @@ static int do_spawn(unsigned logopt, uns
|
||||
if (!tsv->user)
|
||||
fprintf(stderr,
|
||||
"warning: can't init groups\n");
|
||||
- else if (initgroups(tsv->user, egid) == -1)
|
||||
- fprintf(stderr,
|
||||
- "warning: initgroups: %s\n",
|
||||
- strerror(errno));
|
||||
+ else if (groups) {
|
||||
+ if (setgroups(ngroups, groups) == -1)
|
||||
+ fprintf(stderr,
|
||||
+ "warning: setgroups: %s\n",
|
||||
+ strerror(errno));
|
||||
+ free(groups);
|
||||
+ }
|
||||
|
||||
if (setegid(egid) == -1)
|
||||
fprintf(stderr,
|
||||
@@ -436,6 +469,11 @@ static int do_spawn(unsigned logopt, uns
|
||||
strerror(errno));
|
||||
if (pgrp >= 0)
|
||||
setpgid(0, pgrp);
|
||||
+ /* Reset groups for trigger of trailing mount */
|
||||
+ if (euid && saved_groups) {
|
||||
+ setgroups(nsaved_groups, saved_groups);
|
||||
+ free(saved_groups);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* The kernel leaves mount type autofs alone because
|
||||
@@ -474,6 +512,11 @@ done:
|
||||
pthread_sigmask(SIG_SETMASK, &tmpsig, NULL);
|
||||
open_mutex_unlock();
|
||||
|
||||
+ if (groups)
|
||||
+ free(groups);
|
||||
+ if (saved_groups)
|
||||
+ free(saved_groups);
|
||||
+
|
||||
close(pipefd[1]);
|
||||
|
||||
if (f < 0) {
|
@ -0,0 +1,169 @@
|
||||
autofs-5.1.8 - fix deadlock with hosts map reload
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When reloading maps the hosts map calls lookup method ->parse_mount()
|
||||
for each multi-mount root entry in the map (each host) while holding
|
||||
the cache read lock which leads to a cache lock deadlock.
|
||||
|
||||
Remove the need to hold the cache read lock by creating an independent
|
||||
list of entries for the update so the lock doesn't need to be taken.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1
|
||||
modules/lookup_hosts.c | 100 ++++++++++++++++++++++++++++++++++++++++---------
|
||||
2 files changed, 83 insertions(+), 18 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -108,6 +108,7 @@
|
||||
- serialise lookup module open and reinit.
|
||||
- coverity fix for invalid access.
|
||||
- fix hosts map deadlock on restart.
|
||||
+- fix deadlock with hosts map reload.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/lookup_hosts.c
|
||||
+++ autofs-5.1.7/modules/lookup_hosts.c
|
||||
@@ -201,10 +201,72 @@ static int do_parse_mount(struct autofs_
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
+struct update_context {
|
||||
+ char *key;
|
||||
+ int key_len;
|
||||
+ char *entry;
|
||||
+ struct update_context *next;
|
||||
+};
|
||||
+
|
||||
+static int add_update_entry(struct update_context **entries, struct mapent *me)
|
||||
+{
|
||||
+ struct update_context *upd;
|
||||
+ char *key, *ent;
|
||||
+
|
||||
+ key = strdup(me->key);
|
||||
+ if (!key)
|
||||
+ return 0;
|
||||
+
|
||||
+ ent = strdup(me->mapent);
|
||||
+ if (!ent) {
|
||||
+ free(key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ upd = malloc(sizeof(struct update_context));
|
||||
+ if (!upd) {
|
||||
+ free(ent);
|
||||
+ free(key);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ upd->key = key;
|
||||
+ upd->key_len = me->len;
|
||||
+ upd->entry = ent;
|
||||
+ upd->next = NULL;
|
||||
+ if (*entries)
|
||||
+ (*entries)->next = upd;
|
||||
+ *entries = upd;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static void free_update_entries(struct update_context *entries)
|
||||
+{
|
||||
+ struct update_context *this = entries;
|
||||
+
|
||||
+ while (this) {
|
||||
+ struct update_context *next = this->next;
|
||||
+ free(this->key);
|
||||
+ free(this->entry);
|
||||
+ free(this);
|
||||
+ this = next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void entries_cleanup(void *arg)
|
||||
+{
|
||||
+ struct update_context *entries = arg;
|
||||
+
|
||||
+ free_update_entries(entries);
|
||||
+}
|
||||
+
|
||||
static void update_hosts_mounts(struct autofs_point *ap,
|
||||
struct map_source *source, time_t age,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ struct update_context *head = NULL;
|
||||
+ struct update_context *entries = NULL;
|
||||
struct mapent_cache *mc;
|
||||
struct mapent *me;
|
||||
char *mapent;
|
||||
@@ -212,6 +274,8 @@ static void update_hosts_mounts(struct a
|
||||
|
||||
mc = source->mc;
|
||||
|
||||
+ pthread_cleanup_push(entries_cleanup, head);
|
||||
+
|
||||
pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
cache_writelock(mc);
|
||||
me = cache_lookup_first(mc);
|
||||
@@ -224,39 +288,39 @@ static void update_hosts_mounts(struct a
|
||||
|
||||
mapent = get_exports(ap, me->key);
|
||||
if (mapent) {
|
||||
- cache_update(mc, source, me->key, mapent, age);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = cache_update(mc, source, me->key, mapent, age);
|
||||
free(mapent);
|
||||
+ if (!IS_MM_ROOT(me))
|
||||
+ goto next;
|
||||
+ if (ret != CHE_FAIL) {
|
||||
+ if (!add_update_entry(&entries, me))
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "failed to add update entry for %s", me->key);
|
||||
+ else if (!head)
|
||||
+ head = entries;
|
||||
+ }
|
||||
}
|
||||
next:
|
||||
me = cache_lookup_next(mc, me);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
- cache_readlock(mc);
|
||||
- me = cache_lookup_first(mc);
|
||||
- while (me) {
|
||||
- /*
|
||||
- * Hosts map entry not yet expanded, already expired
|
||||
- * or not the base of the tree
|
||||
- */
|
||||
- if (!IS_MM(me) || !IS_MM_ROOT(me))
|
||||
- goto cont;
|
||||
-
|
||||
+ while (head) {
|
||||
debug(ap->logopt, MODPREFIX
|
||||
- "attempt to update exports for %s", me->key);
|
||||
+ "attempt to update exports for %s", head->key);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = source;
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
- ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key),
|
||||
- me->mapent, ctxt->parse->context);
|
||||
+ ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
|
||||
+ head->entry, ctxt->parse->context);
|
||||
if (ret)
|
||||
warn(ap->logopt, MODPREFIX
|
||||
- "failed to parse mount %s", me->mapent);
|
||||
+ "failed to parse mount %s", head->entry);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
-cont:
|
||||
- me = cache_lookup_next(mc, me);
|
||||
+ head = head->next;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
autofs-5.1.8 - fix fedfs build flags
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Dynamic executables should be compiled with -fPIE and linked with -pie.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
fedfs/Makefile | 4 ++--
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -81,6 +81,7 @@
|
||||
- eliminate some more alloca usage.
|
||||
- use default stack size for threads.
|
||||
- fix kernel mount status notification.
|
||||
+- fix fedfs build flags.
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/fedfs/Makefile
|
||||
+++ autofs-5.1.7/fedfs/Makefile
|
||||
@@ -23,12 +23,12 @@ LDFLAGS += -rdynamic
|
||||
all: mount.fedfs fedfs-map-nfs4
|
||||
|
||||
mount.fedfs: $(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS)
|
||||
- $(CC) -o mount.fedfs \
|
||||
+ $(CC) $(DAEMON_LDFLAGS) -o mount.fedfs \
|
||||
$(mount_fedfs_OBJ) $(fedfs-getsrvinfo_OBJ) \
|
||||
$(LDFLAGS) $(LIBRESOLV) $(LIBS)
|
||||
|
||||
fedfs-map-nfs4: $(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) $(HDRS)
|
||||
- $(CC) -o fedfs-map-nfs4 \
|
||||
+ $(CC) $(DAEMON_LDFLAGS) -o fedfs-map-nfs4 \
|
||||
$(fedfs-map-nfs4_OBJ) $(fedfs-getsrvinfo_OBJ) \
|
||||
$(LDFLAGS) $(LIBRESOLV) $(LIBS)
|
||||
|
@ -0,0 +1,34 @@
|
||||
autofs-5.1.8 - fix fix root offset error handling
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The change to fix root offset error handlling is missing a cache read
|
||||
lock prior to the key lookup, the following unmatched unlock then
|
||||
causes a hang.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/direct.c | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -85,6 +85,7 @@
|
||||
- fix set open file limit.
|
||||
- improve descriptor open error reporting.
|
||||
- fix root offset error handling.
|
||||
+- fix fix root offset error handling.
|
||||
|
||||
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
|
||||
@@ -1271,6 +1271,7 @@ static void *do_mount_direct(void *arg)
|
||||
/* If this is a multi-mount subtree mount failure
|
||||
* ensure the tree continues to expire.
|
||||
*/
|
||||
+ cache_readlock(mt.mc);
|
||||
me = cache_lookup_distinct(mt.mc, mt.name);
|
||||
if (me && IS_MM(me) && !IS_MM_ROOT(me))
|
||||
conditional_alarm_add(ap, ap->exp_runfreq);
|
@ -0,0 +1,110 @@
|
||||
autofs-5.1.8 - fix handling of incorrect return from umount_ent()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Commit 0210535df4b ("autofs-5.1.0 - gaurd against incorrect umount
|
||||
return") guards against umount_ent() returning a fail when the mount
|
||||
has actually been umounted.
|
||||
|
||||
But we also see umount_ent() return success when in fact the mount has
|
||||
not been umounted leading to incorrect handling of automounts.
|
||||
|
||||
So checking the return of umount_ent() isn't always giving the correct
|
||||
result in more than just one case, consequently we should ignore the
|
||||
result from the spawned umount(8) and check if the mount has in fact
|
||||
been umounted.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/automount.c | 3 +--
|
||||
lib/mounts.c | 19 ++++++++++---------
|
||||
3 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -95,6 +95,7 @@
|
||||
- avoid calling pthread_getspecific() with NULL key_thread_attempt_id.
|
||||
- fix sysconf(3) return handling.
|
||||
- remove nonstrict parameter from tree_mapent_umount_offsets().
|
||||
+- fix handling of incorrect return from umount_ent().
|
||||
|
||||
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
|
||||
@@ -605,8 +605,7 @@ static int umount_subtree_mounts(struct
|
||||
struct mnt_list *mnt;
|
||||
|
||||
debug(ap->logopt, "unmounting dir = %s", path);
|
||||
- if (umount_ent(ap, path) &&
|
||||
- is_mounted(path, MNTS_REAL)) {
|
||||
+ if (umount_ent(ap, path)) {
|
||||
warn(ap->logopt, "could not umount dir %s", path);
|
||||
left++;
|
||||
goto done;
|
||||
--- autofs-5.1.7.orig/lib/mounts.c
|
||||
+++ autofs-5.1.7/lib/mounts.c
|
||||
@@ -1869,8 +1869,7 @@ static int tree_mapent_umount_offset(str
|
||||
*/
|
||||
if (oe->ioctlfd != -1 ||
|
||||
is_mounted(oe->key, MNTS_REAL)) {
|
||||
- if (umount_ent(ap, oe->key) &&
|
||||
- is_mounted(oe->key, MNTS_REAL)) {
|
||||
+ if (umount_ent(ap, oe->key)) {
|
||||
debug(ap->logopt,
|
||||
"offset %s has active mount, invalidate",
|
||||
oe->key);
|
||||
@@ -2010,8 +2009,7 @@ int tree_mapent_umount_offsets(struct ma
|
||||
*/
|
||||
if (is_mounted(mp, MNTS_REAL)) {
|
||||
info(ap->logopt, "unmounting dir = %s", mp);
|
||||
- if (umount_ent(ap, mp) &&
|
||||
- is_mounted(mp, MNTS_REAL)) {
|
||||
+ if (umount_ent(ap, mp)) {
|
||||
if (!tree_mapent_mount_offsets(oe, 1))
|
||||
warn(ap->logopt,
|
||||
"failed to remount offset triggers");
|
||||
@@ -2982,6 +2980,7 @@ void set_direct_mount_tree_catatonic(str
|
||||
|
||||
int umount_ent(struct autofs_point *ap, const char *path)
|
||||
{
|
||||
+ unsigned int mounted;
|
||||
int rv;
|
||||
|
||||
if (ap->state != ST_SHUTDOWN_FORCE)
|
||||
@@ -2993,6 +2992,8 @@ int umount_ent(struct autofs_point *ap,
|
||||
rv = spawn_umount(ap->logopt, "-l", path, NULL);
|
||||
}
|
||||
|
||||
+ mounted = is_mounted(path, MNTS_REAL);
|
||||
+
|
||||
if (rv && (ap->state == ST_SHUTDOWN_FORCE || ap->state == ST_SHUTDOWN)) {
|
||||
/*
|
||||
* Verify that we actually unmounted the thing. This is a
|
||||
@@ -3004,20 +3005,20 @@ int umount_ent(struct autofs_point *ap,
|
||||
* so that we do not try to call rmdir_path on the
|
||||
* directory.
|
||||
*/
|
||||
- if (is_mounted(path, MNTS_REAL)) {
|
||||
+ if (mounted) {
|
||||
crit(ap->logopt,
|
||||
"the umount binary reported that %s was "
|
||||
"unmounted, but there is still something "
|
||||
"mounted on this path.", path);
|
||||
- rv = -1;
|
||||
+ mounted = -1;
|
||||
}
|
||||
}
|
||||
|
||||
- /* On success, check for mounted mount and remove it if found */
|
||||
- if (!rv)
|
||||
+ /* If mount is gone remove it from mounted mounts list. */
|
||||
+ if (!mounted)
|
||||
mnts_remove_mount(path, MNTS_MOUNTED);
|
||||
|
||||
- return rv;
|
||||
+ return mounted;
|
||||
}
|
||||
|
||||
int umount_amd_ext_mount(struct autofs_point *ap, const char *path)
|
@ -0,0 +1,97 @@
|
||||
autofs-5.1.8 - fix hosts map deadlock on restart
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When starting automount(8) with a hosts map that has mounts that were
|
||||
in use at the last exit a deadlock can occur.
|
||||
|
||||
In this case automount(8) will perform the same steps but not actually
|
||||
perform the mount to re-construct the context of each mount. But, with
|
||||
the hosts map, that leads to calling back into the sun parse module
|
||||
while holding the map module read lock which will again try and take
|
||||
the write lock.
|
||||
|
||||
Fix this by only taking the write lock in the mount code path if the
|
||||
module handle has not already been opened.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 22 ++++++++++++----------
|
||||
modules/parse_amd.c | 18 ++++++++++--------
|
||||
3 files changed, 23 insertions(+), 18 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -107,6 +107,7 @@
|
||||
- fix parse module instance mutex naming.
|
||||
- serialise lookup module open and reinit.
|
||||
- coverity fix for invalid access.
|
||||
+- fix hosts map deadlock on restart.
|
||||
|
||||
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
|
||||
@@ -807,19 +807,21 @@ int do_lookup_mount(struct autofs_point
|
||||
struct lookup_mod *lookup;
|
||||
int status;
|
||||
|
||||
- map_module_writelock(map);
|
||||
if (!map->lookup) {
|
||||
- status = open_lookup(map->type, "",
|
||||
- map->format, map->argc, map->argv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- map_module_unlock(map);
|
||||
- debug(ap->logopt,
|
||||
- "lookup module %s open failed", map->type);
|
||||
- return status;
|
||||
+ map_module_writelock(map);
|
||||
+ if (!map->lookup) {
|
||||
+ status = open_lookup(map->type, "",
|
||||
+ map->format, map->argc, map->argv, &lookup);
|
||||
+ if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(map);
|
||||
+ debug(ap->logopt,
|
||||
+ "lookup module %s open failed", map->type);
|
||||
+ return status;
|
||||
+ }
|
||||
+ map->lookup = lookup;
|
||||
}
|
||||
- map->lookup = lookup;
|
||||
+ map_module_unlock(map);
|
||||
}
|
||||
- map_module_unlock(map);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = map;
|
||||
--- autofs-5.1.7.orig/modules/parse_amd.c
|
||||
+++ autofs-5.1.7/modules/parse_amd.c
|
||||
@@ -1370,17 +1370,19 @@ static int do_host_mount(struct autofs_p
|
||||
}
|
||||
}
|
||||
|
||||
- map_module_writelock(instance);
|
||||
if (!instance->lookup) {
|
||||
- status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
- if (status != NSS_STATUS_SUCCESS) {
|
||||
- map_module_unlock(instance);
|
||||
- debug(ap->logopt, "open lookup module hosts failed");
|
||||
- goto out;
|
||||
+ map_module_writelock(instance);
|
||||
+ if (!instance->lookup) {
|
||||
+ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup);
|
||||
+ if (status != NSS_STATUS_SUCCESS) {
|
||||
+ map_module_unlock(instance);
|
||||
+ debug(ap->logopt, "open lookup module hosts failed");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ instance->lookup = lookup;
|
||||
}
|
||||
- instance->lookup = lookup;
|
||||
+ map_module_unlock(instance);
|
||||
}
|
||||
- map_module_unlock(instance);
|
||||
|
||||
cache_writelock(source->mc);
|
||||
me = cache_lookup_distinct(source->mc, name);
|
@ -0,0 +1,63 @@
|
||||
autofs-5.1.8 - fix incorrect path for is_mounted() in try_remount()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
A regression was introduced when the offset mount handling was rewritten.
|
||||
|
||||
It resulted in an incorrect path sometimes being used in an is_mounted()
|
||||
check.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/mounts.c | 26 +++++++++++++++++++++-----
|
||||
2 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -111,6 +111,7 @@
|
||||
- fix deadlock with hosts map reload.
|
||||
- fix memory leak in update_hosts_mounts().
|
||||
- fix minus only option handling in concat_options().
|
||||
+- fix incorrect path for is_mounted() in try_remount().
|
||||
|
||||
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
|
||||
@@ -2803,14 +2803,30 @@ int try_remount(struct autofs_point *ap,
|
||||
ap->flags &= ~MOUNT_FLAG_DIR_CREATED;
|
||||
else
|
||||
ap->flags |= MOUNT_FLAG_DIR_CREATED;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ me->flags &= ~MOUNT_FLAG_DIR_CREATED;
|
||||
+ /* Direct or offset mount, key is full path */
|
||||
+ if (MM_PARENT(me)->key[0] == '/') {
|
||||
+ if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
|
||||
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
|
||||
} else {
|
||||
- me->flags &= ~MOUNT_FLAG_DIR_CREATED;
|
||||
- if (type == t_offset) {
|
||||
- if (!is_mounted(MM_PARENT(me)->key, MNTS_REAL))
|
||||
- me->flags |= MOUNT_FLAG_DIR_CREATED;
|
||||
+ char *p_key = MM_PARENT(me)->key;
|
||||
+ char mp[PATH_MAX + 1];
|
||||
+ int len;
|
||||
+
|
||||
+ len = mount_fullpath(mp, PATH_MAX, ap->path, ap->len, p_key);
|
||||
+ if (len > PATH_MAX) {
|
||||
+ /* This should never happen due to earlier checks */
|
||||
+ error(ap->logopt, "mountpoint path too long");
|
||||
+ return 0;
|
||||
}
|
||||
- }
|
||||
|
||||
+ if (!is_mounted(mp, MNTS_REAL))
|
||||
+ me->flags |= MOUNT_FLAG_DIR_CREATED;
|
||||
+ }
|
||||
+done:
|
||||
/*
|
||||
* Either we opened the mount or we're re-reading the map.
|
||||
* If we opened the mount and ioctlfd is not -1 we have
|
@ -0,0 +1,46 @@
|
||||
autofs-5.1.8 - fix invalid tsv access
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When using the --dumpmaps option of automount(8) a SEGV can occur
|
||||
because a thread specific data variable accessed in the code hasn't
|
||||
yet been created.
|
||||
|
||||
The thread specific data doesn't need to be set to list the maps
|
||||
so we can create the key and rely on pthread_getspecific() returning
|
||||
NULL when the value hasn't been set as this case is handled correctly.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/automount.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -102,6 +102,7 @@
|
||||
- bailout on rpc systemerror.
|
||||
- fix nfsv4 only mounts should not use rpcbind.
|
||||
- dont use initgroups() at spawn.
|
||||
+- fix invalid tsv access.
|
||||
|
||||
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
|
||||
@@ -2518,6 +2518,15 @@ int main(int argc, char *argv[])
|
||||
master = argv[2];
|
||||
}
|
||||
|
||||
+ status = pthread_key_create(&key_thread_stdenv_vars,
|
||||
+ key_thread_stdenv_vars_destroy);
|
||||
+ if (status) {
|
||||
+ logerr("%s: failed to create thread data key for std env vars!",
|
||||
+ program);
|
||||
+ macro_free_global_table();
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
if (master)
|
||||
master_list = master_new(NULL, timeout, flags);
|
||||
else
|
@ -0,0 +1,135 @@
|
||||
autofs-5.1.8 - fix kernel mount status notification
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The status return for attempted mount notification is not done
|
||||
correctly in some cases leading to a status being sent to the
|
||||
kernel multiple times or the send causing an error.
|
||||
|
||||
We must send a status to the kernel but it needs to be the correct
|
||||
one. It definitely shouldn't be sent twice for the same mount attempt
|
||||
and shouldn't be failing.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/direct.c | 19 +++++++++++--------
|
||||
daemon/indirect.c | 19 +++++++++++--------
|
||||
3 files changed, 23 insertions(+), 16 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -80,6 +80,7 @@
|
||||
- fix concat_options() error handling.
|
||||
- eliminate some more alloca usage.
|
||||
- use default stack size for threads.
|
||||
+- fix kernel mount status notification.
|
||||
|
||||
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
|
||||
@@ -1143,12 +1143,18 @@ int handle_packet_expire_direct(struct a
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mount_send_fail(void *arg)
|
||||
+static void mount_send_status(void *arg)
|
||||
{
|
||||
struct ioctl_ops *ops = get_ioctl_ops();
|
||||
struct pending_args *mt = arg;
|
||||
struct autofs_point *ap = mt->ap;
|
||||
- ops->send_fail(ap->logopt, mt->ioctlfd, mt->wait_queue_token, -ENOENT);
|
||||
+
|
||||
+ if (mt->status)
|
||||
+ ops->send_fail(ap->logopt, mt->ioctlfd,
|
||||
+ mt->wait_queue_token, mt->status);
|
||||
+ else
|
||||
+ ops->send_ready(ap->logopt,
|
||||
+ mt->ioctlfd, mt->wait_queue_token);
|
||||
ops->close(ap->logopt, mt->ioctlfd);
|
||||
}
|
||||
|
||||
@@ -1177,7 +1183,8 @@ static void *do_mount_direct(void *arg)
|
||||
|
||||
pending_mutex_unlock(args);
|
||||
|
||||
- pthread_cleanup_push(mount_send_fail, &mt);
|
||||
+ mt.status = 0;
|
||||
+ pthread_cleanup_push(mount_send_status, &mt);
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||||
|
||||
@@ -1191,9 +1198,7 @@ static void *do_mount_direct(void *arg)
|
||||
if (status == -1) {
|
||||
error(ap->logopt,
|
||||
"can't stat direct mount trigger %s", mt.name);
|
||||
- ops->send_fail(ap->logopt,
|
||||
- mt.ioctlfd, mt.wait_queue_token, -ENOENT);
|
||||
- ops->close(ap->logopt, mt.ioctlfd);
|
||||
+ mt.status = -ENOENT;
|
||||
pthread_setcancelstate(state, NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
@@ -1203,8 +1208,6 @@ static void *do_mount_direct(void *arg)
|
||||
error(ap->logopt,
|
||||
"direct trigger not valid or already mounted %s",
|
||||
mt.name);
|
||||
- ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token);
|
||||
- ops->close(ap->logopt, mt.ioctlfd);
|
||||
pthread_setcancelstate(state, NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
--- autofs-5.1.7.orig/daemon/indirect.c
|
||||
+++ autofs-5.1.7/daemon/indirect.c
|
||||
@@ -674,13 +674,18 @@ int handle_packet_expire_indirect(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mount_send_fail(void *arg)
|
||||
+static void mount_send_status(void *arg)
|
||||
{
|
||||
struct ioctl_ops *ops = get_ioctl_ops();
|
||||
struct pending_args *mt = arg;
|
||||
struct autofs_point *ap = mt->ap;
|
||||
- ops->send_fail(ap->logopt,
|
||||
- ap->ioctlfd, mt->wait_queue_token, -ENOENT);
|
||||
+
|
||||
+ if (mt->status)
|
||||
+ ops->send_fail(ap->logopt, ap->ioctlfd,
|
||||
+ mt->wait_queue_token, mt->status);
|
||||
+ else
|
||||
+ ops->send_ready(ap->logopt,
|
||||
+ ap->ioctlfd, mt->wait_queue_token);
|
||||
}
|
||||
|
||||
static void *do_mount_indirect(void *arg)
|
||||
@@ -709,7 +714,8 @@ static void *do_mount_indirect(void *arg
|
||||
|
||||
pending_mutex_unlock(args);
|
||||
|
||||
- pthread_cleanup_push(mount_send_fail, &mt);
|
||||
+ mt.status = 0;
|
||||
+ pthread_cleanup_push(mount_send_status, &mt);
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
|
||||
|
||||
@@ -722,9 +728,7 @@ static void *do_mount_indirect(void *arg
|
||||
len = ncat_path(buf, sizeof(buf), ap->path, mt.name, mt.len);
|
||||
if (!len) {
|
||||
crit(ap->logopt, "path to be mounted is to long");
|
||||
- ops->send_fail(ap->logopt,
|
||||
- ap->ioctlfd, mt.wait_queue_token,
|
||||
- -ENAMETOOLONG);
|
||||
+ mt.status = -ENAMETOOLONG;
|
||||
pthread_setcancelstate(state, NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
@@ -733,7 +737,6 @@ static void *do_mount_indirect(void *arg
|
||||
if (status != -1 && !(S_ISDIR(st.st_mode) && st.st_dev == mt.dev)) {
|
||||
error(ap->logopt,
|
||||
"indirect trigger not valid or already mounted %s", buf);
|
||||
- ops->send_ready(ap->logopt, ap->ioctlfd, mt.wait_queue_token);
|
||||
pthread_setcancelstate(state, NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
autofs-5.1.8 - fix loop under run in cache_get_offset_parent()
|
||||
|
||||
From: Frank Sorenson <sorenson@redhat.com>
|
||||
|
||||
To avoid reading memory outside of the the string
|
||||
allocated for parent, tail needs to stop when it
|
||||
reaches or passes parent, even if it doesn't
|
||||
actually equal parent.
|
||||
|
||||
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/cache.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -88,6 +88,7 @@
|
||||
- fix fix root offset error handling.
|
||||
- fix nonstrict fail handling of last offset mount.
|
||||
- dont fail on duplicate offset entry tree add.
|
||||
+- fix loop under run in cache_get_offset_parent().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/lib/cache.c
|
||||
+++ autofs-5.1.7/lib/cache.c
|
||||
@@ -710,7 +710,7 @@ struct mapent *cache_get_offset_parent(s
|
||||
*tail = 0;
|
||||
|
||||
tail--;
|
||||
- if (tail == parent)
|
||||
+ if (tail <= parent)
|
||||
break;
|
||||
|
||||
me = cache_lookup_distinct(mc, parent);
|
@ -0,0 +1,53 @@
|
||||
autofs-5.1.8 - fix memory leak in update_hosts_mounts()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Coverity has reported a memory leak in update_hosts_mounts() introduced
|
||||
by the map reload deadlock fix.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_hosts.c | 13 +++++++------
|
||||
2 files changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -109,6 +109,7 @@
|
||||
- coverity fix for invalid access.
|
||||
- fix hosts map deadlock on restart.
|
||||
- fix deadlock with hosts map reload.
|
||||
+- fix memory leak in update_hosts_mounts().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/modules/lookup_hosts.c
|
||||
+++ autofs-5.1.7/modules/lookup_hosts.c
|
||||
@@ -307,20 +307,21 @@ next:
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
- while (head) {
|
||||
+ entries = head;
|
||||
+ while (entries) {
|
||||
debug(ap->logopt, MODPREFIX
|
||||
- "attempt to update exports for %s", head->key);
|
||||
+ "attempt to update exports for %s", entries->key);
|
||||
|
||||
master_source_current_wait(ap->entry);
|
||||
ap->entry->current = source;
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
- ret = ctxt->parse->parse_mount(ap, head->key, strlen(head->key),
|
||||
- head->entry, ctxt->parse->context);
|
||||
+ ret = ctxt->parse->parse_mount(ap, entries->key, strlen(entries->key),
|
||||
+ entries->entry, ctxt->parse->context);
|
||||
if (ret)
|
||||
warn(ap->logopt, MODPREFIX
|
||||
- "failed to parse mount %s", head->entry);
|
||||
+ "failed to parse mount %s", entries->entry);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
- head = head->next;
|
||||
+ entries = entries->next;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
autofs-5.1.8 - fix memory leak in xdr_exports()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Converting xdr_exports() to not be recursive introduced a memory leak
|
||||
if an error is encountered, fix it.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
lib/rpc_subs.c | 7 ++++++-
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- autofs-5.1.7.orig/CHANGELOG
|
||||
+++ autofs-5.1.7/CHANGELOG
|
||||
@@ -91,6 +91,7 @@
|
||||
- fix loop under run in cache_get_offset_parent().
|
||||
- simplify cache_add() a little.
|
||||
- fix use after free in tree_mapent_delete_offset_tree().
|
||||
+- fix memory leak in xdr_exports().
|
||||
|
||||
25/01/2021 autofs-5.1.7
|
||||
- make bind mounts propagation slave by default.
|
||||
--- autofs-5.1.7.orig/lib/rpc_subs.c
|
||||
+++ autofs-5.1.7/lib/rpc_subs.c
|
||||
@@ -1151,8 +1151,13 @@ bool_t xdr_exports(XDR *xdrs, struct exp
|
||||
|
||||
export = (char **) exports;
|
||||
while (1) {
|
||||
- if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export))
|
||||
+ if (!xdr_pointer(xdrs, export, size, (xdrproc_t) xdr_export)) {
|
||||
+ if (*exports) {
|
||||
+ rpc_exports_free(*exports);
|
||||
+ *exports = NULL;
|
||||
+ }
|
||||
return FALSE;
|
||||
+ }
|
||||
if (!*export)
|
||||
break;
|
||||
export = (char **) &((struct exportinfo *) *export)->next;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue