import autofs-5.1.4-69.el8
This commit is contained in:
parent
f719b745d3
commit
cb3938c254
@ -0,0 +1,82 @@
|
||||
autofs-5.1.7 - eliminate redundant cache lookup in tree_mapent_add_node()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Since we need to create the offset tree after adding the offset entries
|
||||
to the mapent cache (from a list.h list) there's no need to lookup the
|
||||
mapent in tree_mapent_add_node() and validate it. Just use it directly
|
||||
when calling tree_mapent_add_node() and avoid a cache lookup on every
|
||||
node addition.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
include/mounts.h | 2 +-
|
||||
lib/mounts.c | 13 ++-----------
|
||||
modules/parse_sun.c | 2 +-
|
||||
4 files changed, 5 insertions(+), 13 deletions(-)
|
||||
|
||||
--- autofs-5.1.4.orig/CHANGELOG
|
||||
+++ autofs-5.1.4/CHANGELOG
|
||||
@@ -70,6 +70,7 @@
|
||||
- fix amd hosts mount expire.
|
||||
- fix offset entries order.
|
||||
- use mapent tree root for tree_mapent_add_node().
|
||||
+- eliminate redundant cache lookup in tree_mapent_add_node().
|
||||
|
||||
xx/xx/2018 autofs-5.1.5
|
||||
- fix flag file permission.
|
||||
--- autofs-5.1.4.orig/include/mounts.h
|
||||
+++ autofs-5.1.4/include/mounts.h
|
||||
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
|
||||
void mnts_put_expire_list(struct list_head *mnts);
|
||||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
||||
struct tree_node *tree_mapent_root(struct mapent *me);
|
||||
-int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
|
||||
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
|
||||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
|
||||
void tree_mapent_cleanup_offsets(struct mapent *oe);
|
||||
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
|
||||
--- autofs-5.1.4.orig/lib/mounts.c
|
||||
+++ autofs-5.1.4/lib/mounts.c
|
||||
@@ -1519,19 +1519,10 @@ static void tree_mapent_free(struct tree
|
||||
}
|
||||
|
||||
int tree_mapent_add_node(struct mapent_cache *mc,
|
||||
- struct tree_node *root, const char *key)
|
||||
+ struct tree_node *root, struct mapent *me)
|
||||
{
|
||||
- unsigned int logopt = mc->ap->logopt;
|
||||
struct tree_node *n;
|
||||
struct mapent *parent;
|
||||
- struct mapent *me;
|
||||
-
|
||||
- me = cache_lookup_distinct(mc, key);
|
||||
- if (!me) {
|
||||
- error(logopt,
|
||||
- "failed to find key %s of multi-mount", key);
|
||||
- return 0;
|
||||
- }
|
||||
|
||||
n = tree_add_node(root, me);
|
||||
if (!n)
|
||||
@@ -1540,7 +1531,7 @@ int tree_mapent_add_node(struct mapent_c
|
||||
MAPENT_SET_ROOT(me, root)
|
||||
|
||||
/* Set the subtree parent */
|
||||
- parent = cache_get_offset_parent(mc, key);
|
||||
+ parent = cache_get_offset_parent(mc, me->key);
|
||||
if (!parent)
|
||||
MAPENT_SET_PARENT(me, root)
|
||||
else
|
||||
--- autofs-5.1.4.orig/modules/parse_sun.c
|
||||
+++ autofs-5.1.4/modules/parse_sun.c
|
||||
@@ -1548,7 +1548,7 @@ dont_expand:
|
||||
return 1;
|
||||
}
|
||||
list_for_each_entry_safe(oe, tmp, &offsets, work) {
|
||||
- if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
|
||||
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe))
|
||||
error(ap->logopt, "failed to add offset %s to tree", oe->key);
|
||||
list_del_init(&oe->work);
|
||||
}
|
129
SOURCES/autofs-5.1.7-fix-direct-mount-deadlock.patch
Normal file
129
SOURCES/autofs-5.1.7-fix-direct-mount-deadlock.patch
Normal file
@ -0,0 +1,129 @@
|
||||
autofs-5.1.7 - fix direct mount deadlock
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
When umounting direct mounts at exit or when umounting mounts no
|
||||
longer in the map on re-load a deadlock can occur.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/direct.c | 22 +++++++++++++++++++++-
|
||||
daemon/state.c | 14 +++++++++-----
|
||||
3 files changed, 31 insertions(+), 6 deletions(-)
|
||||
|
||||
--- autofs-5.1.4.orig/CHANGELOG
|
||||
+++ autofs-5.1.4/CHANGELOG
|
||||
@@ -72,6 +72,7 @@
|
||||
- use mapent tree root for tree_mapent_add_node().
|
||||
- eliminate redundant cache lookup in tree_mapent_add_node().
|
||||
- fix hosts map offset order.
|
||||
+- fix direct mount deadlock.
|
||||
|
||||
xx/xx/2018 autofs-5.1.5
|
||||
- fix flag file permission.
|
||||
--- autofs-5.1.4.orig/daemon/direct.c
|
||||
+++ autofs-5.1.4/daemon/direct.c
|
||||
@@ -84,11 +84,27 @@ static void mnts_cleanup(void *arg)
|
||||
int do_umount_autofs_direct(struct autofs_point *ap, struct mapent *me)
|
||||
{
|
||||
struct ioctl_ops *ops = get_ioctl_ops();
|
||||
+ struct mapent_cache *mc = me->mc;
|
||||
char buf[MAX_ERR_BUF];
|
||||
int ioctlfd = -1, rv, left, retries;
|
||||
+ char key[PATH_MAX + 1];
|
||||
+ struct mapent *tmp;
|
||||
int opened = 0;
|
||||
|
||||
- left = umount_multi(ap, me->key, 0);
|
||||
+ if (me->len > PATH_MAX) {
|
||||
+ error(ap->logopt, "path too long");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ strcpy(key, me->key);
|
||||
+
|
||||
+ cache_unlock(mc);
|
||||
+ left = umount_multi(ap, key, 0);
|
||||
+ cache_readlock(mc);
|
||||
+ tmp = cache_lookup_distinct(mc, key);
|
||||
+ if (tmp != me) {
|
||||
+ error(ap->logopt, "key %s no longer in mapent cache", key);
|
||||
+ return -1;
|
||||
+ }
|
||||
if (left) {
|
||||
warn(ap->logopt, "could not unmount %d dirs under %s",
|
||||
left, me->key);
|
||||
@@ -213,6 +229,7 @@ int umount_autofs_direct(struct autofs_p
|
||||
mc = map->mc;
|
||||
pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
cache_readlock(mc);
|
||||
+restart:
|
||||
me = cache_enumerate(mc, NULL);
|
||||
while (me) {
|
||||
int error;
|
||||
@@ -230,6 +247,9 @@ int umount_autofs_direct(struct autofs_p
|
||||
* failed umount.
|
||||
*/
|
||||
error = do_umount_autofs_direct(ap, me);
|
||||
+ /* cache became invalid, restart */
|
||||
+ if (error == -1)
|
||||
+ goto restart;
|
||||
if (!error)
|
||||
goto done;
|
||||
|
||||
--- autofs-5.1.4.orig/daemon/state.c
|
||||
+++ autofs-5.1.4/daemon/state.c
|
||||
@@ -348,11 +348,12 @@ static void do_readmap_cleanup(void *arg
|
||||
return;
|
||||
}
|
||||
|
||||
-static void do_readmap_mount(struct autofs_point *ap,
|
||||
+static int do_readmap_mount(struct autofs_point *ap,
|
||||
struct map_source *map, struct mapent *me, time_t now)
|
||||
{
|
||||
struct mapent_cache *nc;
|
||||
struct mapent *ne, *nested, *valid;
|
||||
+ int ret = 0;
|
||||
|
||||
nc = ap->entry->master->nc;
|
||||
|
||||
@@ -411,7 +412,7 @@ static void do_readmap_mount(struct auto
|
||||
cache_unlock(vmc);
|
||||
error(ap->logopt,
|
||||
"failed to find expected existing valid map entry");
|
||||
- return;
|
||||
+ return ret;
|
||||
}
|
||||
/* Take over the mount if there is one */
|
||||
valid->ioctlfd = me->ioctlfd;
|
||||
@@ -430,14 +431,14 @@ static void do_readmap_mount(struct auto
|
||||
ap->exp_runfreq = runfreq;
|
||||
}
|
||||
} else if (!is_mounted(me->key, MNTS_REAL))
|
||||
- do_umount_autofs_direct(ap, me);
|
||||
+ ret = do_umount_autofs_direct(ap, me);
|
||||
else
|
||||
debug(ap->logopt,
|
||||
"%s is mounted", me->key);
|
||||
} else
|
||||
do_mount_autofs_direct(ap, me, get_exp_timeout(ap, map));
|
||||
|
||||
- return;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static void *do_readmap(void *arg)
|
||||
@@ -504,9 +505,12 @@ static void *do_readmap(void *arg)
|
||||
mc = map->mc;
|
||||
pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
cache_readlock(mc);
|
||||
+restart:
|
||||
me = cache_enumerate(mc, NULL);
|
||||
while (me) {
|
||||
- do_readmap_mount(ap, map, me, now);
|
||||
+ int ret = do_readmap_mount(ap, map, me, now);
|
||||
+ if (ret == -1)
|
||||
+ goto restart;
|
||||
me = cache_enumerate(mc, me);
|
||||
}
|
||||
lookup_prune_one_cache(ap, map->mc, now);
|
289
SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch
Normal file
289
SOURCES/autofs-5.1.7-fix-hosts-map-offset-order.patch
Normal file
@ -0,0 +1,289 @@
|
||||
autofs-5.1.7 - fix hosts map offset order
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Map entry offset paths to be in shortest to longest order but exports
|
||||
from a server could come in any order. If there are a large number of
|
||||
exports this can result in a lot of overhead when adding the offset
|
||||
to the ordered list use to mount the offset during parsing since the
|
||||
path length of exports can cary a lot.
|
||||
|
||||
So leverage the tree implemention to sort the export offsets into
|
||||
shortest to longest order as we go when constructing the mapent from
|
||||
the exports list.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1
|
||||
include/automount.h | 2 -
|
||||
include/mounts.h | 8 +++++
|
||||
include/rpc_subs.h | 3 ++
|
||||
lib/mounts.c | 57 +++++++++++++++++++++++++++++++++++++--
|
||||
modules/lookup_hosts.c | 71 ++++++++++++++++++++++++++++++++++++++-----------
|
||||
6 files changed, 124 insertions(+), 18 deletions(-)
|
||||
|
||||
--- autofs-5.1.4.orig/CHANGELOG
|
||||
+++ autofs-5.1.4/CHANGELOG
|
||||
@@ -71,6 +71,7 @@
|
||||
- fix offset entries order.
|
||||
- use mapent tree root for tree_mapent_add_node().
|
||||
- eliminate redundant cache lookup in tree_mapent_add_node().
|
||||
+- fix hosts map offset order.
|
||||
|
||||
xx/xx/2018 autofs-5.1.5
|
||||
- fix flag file permission.
|
||||
--- autofs-5.1.4.orig/include/automount.h
|
||||
+++ autofs-5.1.4/include/automount.h
|
||||
@@ -31,9 +31,9 @@
|
||||
#include "master.h"
|
||||
#include "macros.h"
|
||||
#include "log.h"
|
||||
+#include "mounts.h"
|
||||
#include "rpc_subs.h"
|
||||
#include "parse_subs.h"
|
||||
-#include "mounts.h"
|
||||
#include "dev-ioctl-lib.h"
|
||||
#include "parse_amd.h"
|
||||
|
||||
--- autofs-5.1.4.orig/include/mounts.h
|
||||
+++ autofs-5.1.4/include/mounts.h
|
||||
@@ -52,6 +52,7 @@ extern const unsigned int t_direct;
|
||||
extern const unsigned int t_offset;
|
||||
|
||||
struct mnt_list;
|
||||
+struct exportinfo;
|
||||
struct mapent;
|
||||
|
||||
struct tree_ops;
|
||||
@@ -66,6 +67,9 @@ struct tree_node {
|
||||
#define MNT_LIST(n) (container_of(n, struct mnt_list, node))
|
||||
#define MNT_LIST_NODE(ptr) ((struct tree_node *) &((struct mnt_list *) ptr)->node)
|
||||
|
||||
+#define EXPORTINFO(n) (container_of(n, struct exportinfo, node))
|
||||
+#define EXPORT_NODE(ptr) ((struct tree_node *) &((struct exportinfo *) ptr)->node)
|
||||
+
|
||||
#define MAPENT(n) (container_of(n, struct mapent, node))
|
||||
#define MAPENT_NODE(p) ((struct tree_node *) &((struct mapent *) p)->node)
|
||||
#define MAPENT_ROOT(p) ((struct tree_node *) ((struct mapent *) p)->mm_root)
|
||||
@@ -166,9 +170,13 @@ struct mnt_list *mnts_add_mount(struct a
|
||||
void mnts_remove_mount(const char *mp, unsigned int flags);
|
||||
struct mnt_list *get_mnt_list(const char *path, int include);
|
||||
unsigned int mnts_has_mounted_mounts(struct autofs_point *ap);
|
||||
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr);
|
||||
+void tree_free(struct tree_node *root);
|
||||
void mnts_get_expire_list(struct list_head *mnts, struct autofs_point *ap);
|
||||
void mnts_put_expire_list(struct list_head *mnts);
|
||||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
||||
+struct tree_node *tree_host_root(struct exportinfo *exp);
|
||||
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp);
|
||||
struct tree_node *tree_mapent_root(struct mapent *me);
|
||||
int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, struct mapent *me);
|
||||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
|
||||
--- autofs-5.1.4.orig/include/rpc_subs.h
|
||||
+++ autofs-5.1.4/include/rpc_subs.h
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/nfs2.h>
|
||||
#include <linux/nfs3.h>
|
||||
|
||||
+#include "automount.h"
|
||||
+
|
||||
#define NFS4_VERSION 4
|
||||
|
||||
/* rpc helper subs */
|
||||
@@ -57,6 +59,7 @@ struct exportinfo {
|
||||
char *dir;
|
||||
struct hostinfo *hosts;
|
||||
struct exportinfo *next;
|
||||
+ struct tree_node node;
|
||||
};
|
||||
|
||||
struct conn_info {
|
||||
--- autofs-5.1.4.orig/lib/mounts.c
|
||||
+++ autofs-5.1.4/lib/mounts.c
|
||||
@@ -79,6 +79,17 @@ static struct tree_ops mnt_ops = {
|
||||
};
|
||||
static struct tree_ops *tree_mnt_ops = &mnt_ops;
|
||||
|
||||
+static struct tree_node *tree_host_new(void *ptr);
|
||||
+static int tree_host_cmp(struct tree_node *n, void *ptr);
|
||||
+static void tree_host_free(struct tree_node *n);
|
||||
+
|
||||
+static struct tree_ops host_ops = {
|
||||
+ .new = tree_host_new,
|
||||
+ .cmp = tree_host_cmp,
|
||||
+ .free = tree_host_free,
|
||||
+};
|
||||
+static struct tree_ops *tree_host_ops = &host_ops;
|
||||
+
|
||||
static struct tree_node *tree_mapent_new(void *ptr);
|
||||
static int tree_mapent_cmp(struct tree_node *n, void *ptr);
|
||||
static void tree_mapent_free(struct tree_node *n);
|
||||
@@ -1341,7 +1352,7 @@ static struct tree_node *tree_add_node(s
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static void tree_free(struct tree_node *root)
|
||||
+void tree_free(struct tree_node *root)
|
||||
{
|
||||
struct tree_ops *ops = root->ops;
|
||||
|
||||
@@ -1352,7 +1363,7 @@ static void tree_free(struct tree_node *
|
||||
ops->free(root);
|
||||
}
|
||||
|
||||
-static int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
||||
+int tree_traverse_inorder(struct tree_node *n, tree_work_fn_t work, void *ptr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -1479,6 +1490,48 @@ void mnts_put_expire_list(struct list_he
|
||||
mnts_hash_mutex_unlock();
|
||||
}
|
||||
|
||||
+struct tree_node *tree_host_root(struct exportinfo *exp)
|
||||
+{
|
||||
+ return tree_root(tree_host_ops, exp);
|
||||
+}
|
||||
+
|
||||
+static struct tree_node *tree_host_new(void *ptr)
|
||||
+{
|
||||
+ struct tree_node *n = EXPORT_NODE(ptr);
|
||||
+
|
||||
+ n->ops = tree_host_ops;
|
||||
+ n->left = NULL;
|
||||
+ n->right = NULL;
|
||||
+
|
||||
+ return n;
|
||||
+}
|
||||
+
|
||||
+static int tree_host_cmp(struct tree_node *n, void *ptr)
|
||||
+{
|
||||
+ struct exportinfo *n_exp = EXPORTINFO(n);
|
||||
+ size_t n_exp_len = strlen(n_exp->dir);
|
||||
+ struct exportinfo *exp = ptr;
|
||||
+ size_t exp_len = strlen(exp->dir);
|
||||
+ int eq;
|
||||
+
|
||||
+ eq = strcmp(exp->dir, n_exp->dir);
|
||||
+ if (!eq)
|
||||
+ return 0;
|
||||
+ return (exp_len < n_exp_len) ? -1 : 1;
|
||||
+}
|
||||
+
|
||||
+static void tree_host_free(struct tree_node *n)
|
||||
+{
|
||||
+ n->ops = NULL;
|
||||
+ n->left = NULL;
|
||||
+ n->right = NULL;
|
||||
+}
|
||||
+
|
||||
+struct tree_node *tree_host_add_node(struct tree_node *root, struct exportinfo *exp)
|
||||
+{
|
||||
+ return tree_add_node(root, exp);
|
||||
+}
|
||||
+
|
||||
struct tree_node *tree_mapent_root(struct mapent *me)
|
||||
{
|
||||
return tree_root(tree_mapent_ops, me);
|
||||
--- autofs-5.1.4.orig/modules/lookup_hosts.c
|
||||
+++ autofs-5.1.4/modules/lookup_hosts.c
|
||||
@@ -84,14 +84,38 @@ int lookup_read_master(struct master *ma
|
||||
return NSS_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
+struct work_info {
|
||||
+ char *mapent;
|
||||
+ const char *host;
|
||||
+ int pos;
|
||||
+};
|
||||
+
|
||||
+static int tree_host_work(struct tree_node *n, void *ptr)
|
||||
+{
|
||||
+ struct exportinfo *exp = EXPORTINFO(n);
|
||||
+ struct work_info *wi = ptr;
|
||||
+ int len;
|
||||
+
|
||||
+ if (!wi->pos)
|
||||
+ len = sprintf(wi->mapent, "\"%s\" \"%s:%s\"",
|
||||
+ exp->dir, wi->host, exp->dir);
|
||||
+ else
|
||||
+ len = sprintf(wi->mapent + wi->pos, " \"%s\" \"%s:%s\"",
|
||||
+ exp->dir, wi->host, exp->dir);
|
||||
+ wi->pos += len;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static char *get_exports(struct autofs_point *ap, const char *host)
|
||||
{
|
||||
char buf[MAX_ERR_BUF];
|
||||
char *mapent;
|
||||
struct exportinfo *exp, *this;
|
||||
+ struct tree_node *tree = NULL;
|
||||
+ struct work_info wi;
|
||||
size_t hostlen = strlen(host);
|
||||
size_t mapent_len;
|
||||
- int len, pos;
|
||||
|
||||
debug(ap->logopt, MODPREFIX "fetchng export list for %s", host);
|
||||
|
||||
@@ -100,7 +124,28 @@ static char *get_exports(struct autofs_p
|
||||
this = exp;
|
||||
mapent_len = 0;
|
||||
while (this) {
|
||||
+ struct tree_node *n;
|
||||
+
|
||||
mapent_len += hostlen + 2*(strlen(this->dir) + 2) + 3;
|
||||
+
|
||||
+ if (!tree) {
|
||||
+ tree = tree_host_root(this);
|
||||
+ if (!tree) {
|
||||
+ error(ap->logopt, "failed to create exports tree root");
|
||||
+ rpc_exports_free(exp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ n = tree_host_add_node(tree, this);
|
||||
+ if (!n) {
|
||||
+ error(ap->logopt, "failed to add exports tree node");
|
||||
+ tree_free(tree);
|
||||
+ rpc_exports_free(exp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+next:
|
||||
this = this->next;
|
||||
}
|
||||
|
||||
@@ -115,20 +160,16 @@ static char *get_exports(struct autofs_p
|
||||
}
|
||||
*mapent = 0;
|
||||
|
||||
- pos = 0;
|
||||
- this = exp;
|
||||
- if (this) {
|
||||
- len = sprintf(mapent, "\"%s\" \"%s:%s\"",
|
||||
- this->dir, host, this->dir);
|
||||
- pos += len;
|
||||
- this = this->next;
|
||||
- }
|
||||
-
|
||||
- while (this) {
|
||||
- len = sprintf(mapent + pos, " \"%s\" \"%s:%s\"",
|
||||
- this->dir, host, this->dir);
|
||||
- pos += len;
|
||||
- this = this->next;
|
||||
+ wi.mapent = mapent;
|
||||
+ wi.host = host;
|
||||
+ wi.pos = 0;
|
||||
+
|
||||
+ if (!tree) {
|
||||
+ free(mapent);
|
||||
+ mapent = NULL;
|
||||
+ } else {
|
||||
+ tree_traverse_inorder(tree, tree_host_work, &wi);
|
||||
+ tree_free(tree);
|
||||
}
|
||||
rpc_exports_free(exp);
|
||||
|
199
SOURCES/autofs-5.1.7-fix-offset-entries-order.patch
Normal file
199
SOURCES/autofs-5.1.7-fix-offset-entries-order.patch
Normal file
@ -0,0 +1,199 @@
|
||||
autofs-5.1.7 - fix offset entries order
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
While it's rare it's possible that a mapent entry might not have
|
||||
it's offsets in shortest to longest path order.
|
||||
|
||||
If this happens adding an entry to the mapent tree can result in
|
||||
an incorrect tree topology that doesn't work. That's because adding
|
||||
tree entries ensures that nodes in a sub-tree are placed below the
|
||||
containing node so the containing node must be present for that to
|
||||
work. This topology is critical to the performance of map entries
|
||||
that have a very large number of offsets such as an NFS server with
|
||||
many exports.
|
||||
|
||||
There's no other choice but make a traversal after the offset entries
|
||||
have all been added to create the mapent tree.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1
|
||||
include/automount.h | 1
|
||||
lib/cache.c | 1
|
||||
modules/parse_sun.c | 74 +++++++++++++++++++++++++++++++++++++++++-----------
|
||||
4 files changed, 62 insertions(+), 15 deletions(-)
|
||||
|
||||
--- autofs-5.1.4.orig/CHANGELOG
|
||||
+++ autofs-5.1.4/CHANGELOG
|
||||
@@ -68,6 +68,7 @@
|
||||
- add ext_mount_hash_mutex lock helpers.
|
||||
- fix amd section mounts map reload.
|
||||
- fix amd hosts mount expire.
|
||||
+- fix offset entries order.
|
||||
|
||||
xx/xx/2018 autofs-5.1.5
|
||||
- fix flag file permission.
|
||||
--- autofs-5.1.4.orig/include/automount.h
|
||||
+++ autofs-5.1.4/include/automount.h
|
||||
@@ -169,6 +169,7 @@ struct mapent {
|
||||
/* Parent nesting point within multi-mount */
|
||||
struct tree_node *mm_parent;
|
||||
struct tree_node node;
|
||||
+ struct list_head work;
|
||||
char *key;
|
||||
size_t len;
|
||||
char *mapent;
|
||||
--- autofs-5.1.4.orig/lib/cache.c
|
||||
+++ autofs-5.1.4/lib/cache.c
|
||||
@@ -559,6 +559,7 @@ int cache_add(struct mapent_cache *mc, s
|
||||
me->mm_parent = NULL;
|
||||
INIT_TREE_NODE(&me->node);
|
||||
INIT_LIST_HEAD(&me->ino_index);
|
||||
+ INIT_LIST_HEAD(&me->work);
|
||||
me->ioctlfd = -1;
|
||||
me->dev = (dev_t) -1;
|
||||
me->ino = (ino_t) -1;
|
||||
--- autofs-5.1.4.orig/modules/parse_sun.c
|
||||
+++ autofs-5.1.4/modules/parse_sun.c
|
||||
@@ -791,14 +791,15 @@ static int check_is_multi(const char *ma
|
||||
|
||||
static int
|
||||
update_offset_entry(struct autofs_point *ap,
|
||||
- struct mapent_cache *mc, const char *name,
|
||||
- const char *m_root, int m_root_len,
|
||||
+ struct mapent_cache *mc, struct list_head *offsets,
|
||||
+ const char *name, const char *m_root, int m_root_len,
|
||||
const char *m_offset, const char *myoptions,
|
||||
const char *loc, time_t age)
|
||||
{
|
||||
char m_key[PATH_MAX + 1];
|
||||
char m_mapent[MAPENT_MAX_LEN + 1];
|
||||
int o_len, m_key_len, m_options_len, m_mapent_len;
|
||||
+ struct mapent *me;
|
||||
int ret;
|
||||
|
||||
memset(m_mapent, 0, MAPENT_MAX_LEN + 1);
|
||||
@@ -864,8 +865,29 @@ update_offset_entry(struct autofs_point
|
||||
cache_writelock(mc);
|
||||
ret = cache_update_offset(mc, name, m_key, m_mapent, age);
|
||||
|
||||
- if (!tree_mapent_add_node(mc, name, m_key))
|
||||
- error(ap->logopt, "failed to add offset %s to tree", m_key);
|
||||
+ me = cache_lookup_distinct(mc, m_key);
|
||||
+ if (me && list_empty(&me->work)) {
|
||||
+ struct list_head *last;
|
||||
+
|
||||
+ /* Offset entries really need to be in shortest to
|
||||
+ * longest path order. If not and the list of offsets
|
||||
+ * is large there will be a performace hit.
|
||||
+ */
|
||||
+ list_for_each_prev(last, offsets) {
|
||||
+ struct mapent *this;
|
||||
+
|
||||
+ this = list_entry(last, struct mapent, work);
|
||||
+ if (me->len >= this->len) {
|
||||
+ if (last->next == offsets)
|
||||
+ list_add_tail(&me->work, offsets);
|
||||
+ else
|
||||
+ list_add_tail(&me->work, last);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (list_empty(&me->work))
|
||||
+ list_add(&me->work, offsets);
|
||||
+ }
|
||||
cache_unlock(mc);
|
||||
|
||||
if (ret == CHE_DUPLICATE) {
|
||||
@@ -1211,6 +1233,25 @@ static char *do_expandsunent(const char
|
||||
return mapent;
|
||||
}
|
||||
|
||||
+static void cleanup_offset_entries(struct autofs_point *ap,
|
||||
+ struct mapent_cache *mc,
|
||||
+ struct list_head *offsets)
|
||||
+{
|
||||
+ struct mapent *me, *tmp;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (list_empty(offsets))
|
||||
+ return;
|
||||
+ cache_writelock(mc);
|
||||
+ list_for_each_entry_safe(me, tmp, offsets, work) {
|
||||
+ list_del(&me->work);
|
||||
+ ret = cache_delete(mc, me->key);
|
||||
+ if (ret != CHE_OK)
|
||||
+ crit(ap->logopt, "failed to delete offset %s", me->key);
|
||||
+ }
|
||||
+ cache_unlock(mc);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* syntax is:
|
||||
* [-options] location [location] ...
|
||||
@@ -1230,7 +1271,8 @@ int parse_mount(struct autofs_point *ap,
|
||||
char buf[MAX_ERR_BUF];
|
||||
struct map_source *source;
|
||||
struct mapent_cache *mc;
|
||||
- struct mapent *me;
|
||||
+ struct mapent *me, *oe, *tmp;
|
||||
+ LIST_HEAD(offsets);
|
||||
char *pmapent, *options;
|
||||
const char *p;
|
||||
int mapent_len, rv = 0;
|
||||
@@ -1446,9 +1488,7 @@ dont_expand:
|
||||
|
||||
if (!m_offset) {
|
||||
warn(ap->logopt, MODPREFIX "null path or out of memory");
|
||||
- cache_writelock(mc);
|
||||
- tree_mapent_delete_offsets(mc, name);
|
||||
- cache_unlock(mc);
|
||||
+ cleanup_offset_entries(ap, mc, &offsets);
|
||||
free(options);
|
||||
free(pmapent);
|
||||
pthread_setcancelstate(cur_state, NULL);
|
||||
@@ -1463,9 +1503,7 @@ dont_expand:
|
||||
|
||||
l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
|
||||
if (!l) {
|
||||
- cache_writelock(mc);
|
||||
- tree_mapent_delete_offsets(mc, name);
|
||||
- cache_unlock(mc);
|
||||
+ cleanup_offset_entries(ap, mc, &offsets);
|
||||
free(m_offset);
|
||||
free(options);
|
||||
free(pmapent);
|
||||
@@ -1476,15 +1514,13 @@ dont_expand:
|
||||
p += l;
|
||||
p = skipspace(p);
|
||||
|
||||
- status = update_offset_entry(ap, mc,
|
||||
+ status = update_offset_entry(ap, mc, &offsets,
|
||||
name, m_root, m_root_len,
|
||||
m_offset, myoptions, loc, age);
|
||||
|
||||
if (status != CHE_OK) {
|
||||
warn(ap->logopt, MODPREFIX "error adding multi-mount");
|
||||
- cache_writelock(mc);
|
||||
- tree_mapent_delete_offsets(mc, name);
|
||||
- cache_unlock(mc);
|
||||
+ cleanup_offset_entries(ap, mc, &offsets);
|
||||
free(m_offset);
|
||||
free(options);
|
||||
free(pmapent);
|
||||
@@ -1501,6 +1537,14 @@ dont_expand:
|
||||
free(myoptions);
|
||||
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
|
||||
|
||||
+ cache_writelock(mc);
|
||||
+ list_for_each_entry_safe(oe, tmp, &offsets, work) {
|
||||
+ if (!tree_mapent_add_node(mc, name, oe->key))
|
||||
+ error(ap->logopt, "failed to add offset %s to tree", oe->key);
|
||||
+ list_del_init(&oe->work);
|
||||
+ }
|
||||
+ cache_unlock(mc);
|
||||
+
|
||||
rv = mount_subtree(ap, mc, name, NULL, options, ctxt);
|
||||
|
||||
free(options);
|
@ -0,0 +1,111 @@
|
||||
autofs-5.1.7 - use mapent tree root for tree_mapent_add_node()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Since we need to create the offset tree after adding the offset entries
|
||||
to the mapent cache lookup the root mapent once and use it when calling
|
||||
tree_mapent_add_node() instread of doing a cache lookup on every node
|
||||
addition.
|
||||
|
||||
Signed-off-by: Ian Kent <raven@themaw.net>
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
include/mounts.h | 2 +-
|
||||
lib/mounts.c | 24 +++++-------------------
|
||||
modules/parse_sun.c | 11 ++++++++++-
|
||||
4 files changed, 17 insertions(+), 21 deletions(-)
|
||||
|
||||
--- autofs-5.1.4.orig/CHANGELOG
|
||||
+++ autofs-5.1.4/CHANGELOG
|
||||
@@ -69,6 +69,7 @@
|
||||
- fix amd section mounts map reload.
|
||||
- fix amd hosts mount expire.
|
||||
- fix offset entries order.
|
||||
+- use mapent tree root for tree_mapent_add_node().
|
||||
|
||||
xx/xx/2018 autofs-5.1.5
|
||||
- fix flag file permission.
|
||||
--- autofs-5.1.4.orig/include/mounts.h
|
||||
+++ autofs-5.1.4/include/mounts.h
|
||||
@@ -170,7 +170,7 @@ void mnts_get_expire_list(struct list_he
|
||||
void mnts_put_expire_list(struct list_head *mnts);
|
||||
void mnts_set_mounted_mount(struct autofs_point *ap, const char *name, unsigned int flags);
|
||||
struct tree_node *tree_mapent_root(struct mapent *me);
|
||||
-int tree_mapent_add_node(struct mapent_cache *mc, const char *base, const char *key);
|
||||
+int tree_mapent_add_node(struct mapent_cache *mc, struct tree_node *root, const char *key);
|
||||
int tree_mapent_delete_offsets(struct mapent_cache *mc, const char *key);
|
||||
void tree_mapent_cleanup_offsets(struct mapent *oe);
|
||||
int tree_mapent_mount_offsets(struct mapent *oe, int nonstrict);
|
||||
--- autofs-5.1.4.orig/lib/mounts.c
|
||||
+++ autofs-5.1.4/lib/mounts.c
|
||||
@@ -1519,27 +1519,13 @@ static void tree_mapent_free(struct tree
|
||||
}
|
||||
|
||||
int tree_mapent_add_node(struct mapent_cache *mc,
|
||||
- const char *root, const char *key)
|
||||
+ struct tree_node *root, const char *key)
|
||||
{
|
||||
unsigned int logopt = mc->ap->logopt;
|
||||
- struct tree_node *tree, *n;
|
||||
- struct mapent *base;
|
||||
+ struct tree_node *n;
|
||||
struct mapent *parent;
|
||||
struct mapent *me;
|
||||
|
||||
- base = cache_lookup_distinct(mc, root);
|
||||
- if (!base) {
|
||||
- error(logopt,
|
||||
- "failed to find multi-mount root for key %s", key);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (MAPENT_ROOT(base) != MAPENT_NODE(base)) {
|
||||
- error(logopt, "key %s is not multi-mount root", root);
|
||||
- return 0;
|
||||
- }
|
||||
- tree = MAPENT_ROOT(base);
|
||||
-
|
||||
me = cache_lookup_distinct(mc, key);
|
||||
if (!me) {
|
||||
error(logopt,
|
||||
@@ -1547,16 +1533,16 @@ int tree_mapent_add_node(struct mapent_c
|
||||
return 0;
|
||||
}
|
||||
|
||||
- n = tree_add_node(tree, me);
|
||||
+ n = tree_add_node(root, me);
|
||||
if (!n)
|
||||
return 0;
|
||||
|
||||
- MAPENT_SET_ROOT(me, tree)
|
||||
+ MAPENT_SET_ROOT(me, root)
|
||||
|
||||
/* Set the subtree parent */
|
||||
parent = cache_get_offset_parent(mc, key);
|
||||
if (!parent)
|
||||
- MAPENT_SET_PARENT(me, tree)
|
||||
+ MAPENT_SET_PARENT(me, root)
|
||||
else
|
||||
MAPENT_SET_PARENT(me, MAPENT_NODE(parent))
|
||||
|
||||
--- autofs-5.1.4.orig/modules/parse_sun.c
|
||||
+++ autofs-5.1.4/modules/parse_sun.c
|
||||
@@ -1538,8 +1538,17 @@ dont_expand:
|
||||
} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
|
||||
|
||||
cache_writelock(mc);
|
||||
+ me = cache_lookup_distinct(mc, name);
|
||||
+ if (!me) {
|
||||
+ cache_unlock(mc);
|
||||
+ free(options);
|
||||
+ free(pmapent);
|
||||
+ cleanup_offset_entries(ap, mc, &offsets);
|
||||
+ pthread_setcancelstate(cur_state, NULL);
|
||||
+ return 1;
|
||||
+ }
|
||||
list_for_each_entry_safe(oe, tmp, &offsets, work) {
|
||||
- if (!tree_mapent_add_node(mc, name, oe->key))
|
||||
+ if (!tree_mapent_add_node(mc, MAPENT_ROOT(me), oe->key))
|
||||
error(ap->logopt, "failed to add offset %s to tree", oe->key);
|
||||
list_del_init(&oe->work);
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
Summary: A tool for automatically mounting and unmounting filesystems
|
||||
Name: autofs
|
||||
Version: 5.1.4
|
||||
Release: 68%{?dist}
|
||||
Release: 69%{?dist}
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
Group: System Environment/Daemons
|
||||
@ -234,6 +234,11 @@ Patch211: autofs-5.1.7-add-ext_mount_hash_mutex-lock-helpers.patch
|
||||
|
||||
Patch212: autofs-5.1.7-fix-amd-section-mounts-map-reload.patch
|
||||
Patch213: autofs-5.1.7-fix-amd-hosts-mount-expire.patch
|
||||
Patch214: autofs-5.1.7-fix-offset-entries-order.patch
|
||||
Patch215: autofs-5.1.7-use-mapent-tree-root-for-tree_mapent_add_node.patch
|
||||
Patch216: autofs-5.1.7-eliminate-redundant-cache-lookup-in-tree_mapent_add_node.patch
|
||||
Patch217: autofs-5.1.7-fix-hosts-map-offset-order.patch
|
||||
Patch218: autofs-5.1.7-fix-direct-mount-deadlock.patch
|
||||
|
||||
%if %{with_systemd}
|
||||
BuildRequires: systemd-units
|
||||
@ -510,6 +515,11 @@ echo %{version}-%{release} > .version
|
||||
|
||||
%patch212 -p1
|
||||
%patch213 -p1
|
||||
%patch214 -p1
|
||||
%patch215 -p1
|
||||
%patch216 -p1
|
||||
%patch217 -p1
|
||||
%patch218 -p1
|
||||
|
||||
%build
|
||||
LDFLAGS=-Wl,-z,now
|
||||
@ -605,6 +615,15 @@ fi
|
||||
%dir /etc/auto.master.d
|
||||
|
||||
%changelog
|
||||
* Wed May 19 2021 Ian Kent <ikent@redhat.com> - 5.1.4-69
|
||||
- bz1961492 - autofs: regression in offset ordering
|
||||
- fix offset entries order.
|
||||
- use mapent tree root for tree_mapent_add_node().
|
||||
- eliminate redundant cache lookup in tree_mapent_add_node().
|
||||
- fix hosts map offset order.
|
||||
- fix direct mount deadlock.
|
||||
- Resolves: rhbz#1961492
|
||||
|
||||
* Mon May 10 2021 Ian Kent <ikent@redhat.com> - 5.1.4-68
|
||||
- bz1958487 - autofs amd mounts present in the configuration get umounted
|
||||
on reload
|
||||
|
Loading…
Reference in New Issue
Block a user