|
Ian Kent |
c5187b |
autofs-5.0.4 - always read file maps
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
From: Ian Kent <raven@themaw.net>
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
autofs tries to not load an entire map into the internal cache unless it
|
|
Ian Kent |
c5187b |
has to. For maps that do get loaded into the cache it relies on checks to
|
|
Ian Kent |
c5187b |
work out if a map is up to date in order to trigger a map read. This is
|
|
Ian Kent |
c5187b |
fine for maps that can do direct key lookups but file maps need to do a
|
|
Ian Kent |
c5187b |
linear search through the file when locating an entry for a key. For large
|
|
Ian Kent |
c5187b |
maps this can be a huge overhead. This patch make autofs always load file
|
|
Ian Kent |
c5187b |
based maps at start and makes use of the map file mtime to discover if the
|
|
Ian Kent |
c5187b |
cache needs to be refreshed.
|
|
Ian Kent |
c5187b |
---
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
CHANGELOG | 1 +
|
|
Ian Kent |
c5187b |
daemon/lookup.c | 9 +++++--
|
|
Ian Kent |
c5187b |
modules/lookup_file.c | 65 ++++++++++++++++---------------------------------
|
|
Ian Kent |
c5187b |
3 files changed, 28 insertions(+), 47 deletions(-)
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
diff --git a/CHANGELOG b/CHANGELOG
|
|
Ian Kent |
c5187b |
index d4dd70b..afd1335 100644
|
|
Ian Kent |
c5187b |
--- a/CHANGELOG
|
|
Ian Kent |
c5187b |
+++ b/CHANGELOG
|
|
Ian Kent |
c5187b |
@@ -14,6 +14,7 @@
|
|
Ian Kent |
c5187b |
- check for stale SASL credentials upon connect fail.
|
|
Ian Kent |
c5187b |
- add "forcestart" and "forcerestart" init script options to allow
|
|
Ian Kent |
c5187b |
use of 5.0.3 strartup behavior if required.
|
|
Ian Kent |
c5187b |
+- always read entire file map into cache to speed lookups.
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
4/11/2008 autofs-5.0.4
|
|
Ian Kent |
c5187b |
-----------------------
|
|
Ian Kent |
c5187b |
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
|
Ian Kent |
c5187b |
index 741d846..e034348 100644
|
|
Ian Kent |
c5187b |
--- a/daemon/lookup.c
|
|
Ian Kent |
c5187b |
+++ b/daemon/lookup.c
|
|
Ian Kent |
c5187b |
@@ -283,10 +283,13 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
|
|
Ian Kent |
c5187b |
* for the fail cases to function correctly and to cache the
|
|
Ian Kent |
c5187b |
* lookup handle.
|
|
Ian Kent |
c5187b |
*
|
|
Ian Kent |
c5187b |
- * We always need to whole map for direct mounts in order to
|
|
Ian Kent |
c5187b |
- * mount the triggers.
|
|
Ian Kent |
c5187b |
+ * We always need to read the whole map for direct mounts in
|
|
Ian Kent |
c5187b |
+ * order to mount the triggers. We also want to read the whole
|
|
Ian Kent |
c5187b |
+ * map if it's a file map to avoid potentially lengthy linear
|
|
Ian Kent |
c5187b |
+ * file scanning.
|
|
Ian Kent |
c5187b |
*/
|
|
Ian Kent |
c5187b |
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
|
|
Ian Kent |
c5187b |
+ if (strcmp(map->type, "file") &&
|
|
Ian Kent |
c5187b |
+ !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
|
|
Ian Kent |
c5187b |
return NSS_STATUS_SUCCESS;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
if (!map->stale)
|
|
Ian Kent |
c5187b |
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
|
Ian Kent |
c5187b |
index 95b9f6f..aafeb8b 100644
|
|
Ian Kent |
c5187b |
--- a/modules/lookup_file.c
|
|
Ian Kent |
c5187b |
+++ b/modules/lookup_file.c
|
|
Ian Kent |
c5187b |
@@ -44,7 +44,6 @@ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
struct lookup_context {
|
|
Ian Kent |
c5187b |
const char *mapname;
|
|
Ian Kent |
c5187b |
- time_t mtime;
|
|
Ian Kent |
c5187b |
struct parse_mod *parse;
|
|
Ian Kent |
c5187b |
};
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -54,7 +53,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
c5187b |
{
|
|
Ian Kent |
c5187b |
struct lookup_context *ctxt;
|
|
Ian Kent |
c5187b |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
c5187b |
- struct stat st;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
*context = NULL;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -87,15 +85,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
c5187b |
return 1;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (stat(ctxt->mapname, &st)) {
|
|
Ian Kent |
c5187b |
- free(ctxt);
|
|
Ian Kent |
c5187b |
- logmsg(MODPREFIX "file map %s, could not stat",
|
|
Ian Kent |
c5187b |
- argv[0]);
|
|
Ian Kent |
c5187b |
- return 1;
|
|
Ian Kent |
c5187b |
- }
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
- ctxt->mtime = st.st_mtime;
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
if (!mapfmt)
|
|
Ian Kent |
c5187b |
mapfmt = MAPFMT_DEFAULT;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -391,9 +380,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
Ian Kent |
c5187b |
int blen;
|
|
Ian Kent |
c5187b |
char *path;
|
|
Ian Kent |
c5187b |
char *ent;
|
|
Ian Kent |
c5187b |
- struct stat st;
|
|
Ian Kent |
c5187b |
FILE *f;
|
|
Ian Kent |
c5187b |
- int fd;
|
|
Ian Kent |
c5187b |
unsigned int path_len, ent_len;
|
|
Ian Kent |
c5187b |
int entry, cur_state;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -428,8 +415,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
Ian Kent |
c5187b |
return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- fd = fileno(f);
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
while(1) {
|
|
Ian Kent |
c5187b |
entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
|
|
Ian Kent |
c5187b |
if (!entry) {
|
|
Ian Kent |
c5187b |
@@ -504,13 +489,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
Ian Kent |
c5187b |
break;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (fstat(fd, &st)) {
|
|
Ian Kent |
c5187b |
- crit(logopt, MODPREFIX "file map %s, could not stat",
|
|
Ian Kent |
c5187b |
- ctxt->mapname);
|
|
Ian Kent |
c5187b |
- return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
c5187b |
- }
|
|
Ian Kent |
c5187b |
- ctxt->mtime = st.st_mtime;
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
fclose(f);
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
return NSS_STATUS_SUCCESS;
|
|
Ian Kent |
c5187b |
@@ -642,9 +620,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
Ian Kent |
c5187b |
struct mapent_cache *mc;
|
|
Ian Kent |
c5187b |
char *key;
|
|
Ian Kent |
c5187b |
char *mapent;
|
|
Ian Kent |
c5187b |
- struct stat st;
|
|
Ian Kent |
c5187b |
FILE *f;
|
|
Ian Kent |
c5187b |
- int fd;
|
|
Ian Kent |
c5187b |
unsigned int k_len, m_len;
|
|
Ian Kent |
c5187b |
int entry;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -684,8 +660,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
Ian Kent |
c5187b |
return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- fd = fileno(f);
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
while(1) {
|
|
Ian Kent |
c5187b |
entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
|
|
Ian Kent |
c5187b |
if (!entry) {
|
|
Ian Kent |
c5187b |
@@ -748,13 +722,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
Ian Kent |
c5187b |
break;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (fstat(fd, &st)) {
|
|
Ian Kent |
c5187b |
- crit(ap->logopt,
|
|
Ian Kent |
c5187b |
- MODPREFIX "file map %s, could not stat",
|
|
Ian Kent |
c5187b |
- ctxt->mapname);
|
|
Ian Kent |
c5187b |
- return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
c5187b |
- }
|
|
Ian Kent |
c5187b |
- ctxt->mtime = st.st_mtime;
|
|
Ian Kent |
c5187b |
source->age = age;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
fclose(f);
|
|
Ian Kent |
c5187b |
@@ -951,9 +918,6 @@ static int check_map_indirect(struct autofs_point *ap,
|
|
Ian Kent |
c5187b |
if (ret == CHE_FAIL)
|
|
Ian Kent |
c5187b |
return NSS_STATUS_NOTFOUND;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
- if (ret & CHE_UPDATED)
|
|
Ian Kent |
c5187b |
- source->stale = 1;
|
|
Ian Kent |
c5187b |
-
|
|
Ian Kent |
c5187b |
pthread_cleanup_push(cache_lock_cleanup, mc);
|
|
Ian Kent |
c5187b |
cache_writelock(mc);
|
|
Ian Kent |
c5187b |
exists = cache_lookup_distinct(mc, key);
|
|
Ian Kent |
c5187b |
@@ -963,7 +927,6 @@ static int check_map_indirect(struct autofs_point *ap,
|
|
Ian Kent |
c5187b |
free(exists->mapent);
|
|
Ian Kent |
c5187b |
exists->mapent = NULL;
|
|
Ian Kent |
c5187b |
exists->status = 0;
|
|
Ian Kent |
c5187b |
- source->stale = 1;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
pthread_cleanup_pop(1);
|
|
Ian Kent |
c5187b |
@@ -985,14 +948,8 @@ static int check_map_indirect(struct autofs_point *ap,
|
|
Ian Kent |
c5187b |
we = cache_lookup_distinct(mc, "*");
|
|
Ian Kent |
c5187b |
if (we) {
|
|
Ian Kent |
c5187b |
/* Wildcard entry existed and is now gone */
|
|
Ian Kent |
c5187b |
- if (we->source == source && (wild & CHE_MISSING)) {
|
|
Ian Kent |
c5187b |
+ if (we->source == source && (wild & CHE_MISSING))
|
|
Ian Kent |
c5187b |
cache_delete(mc, "*");
|
|
Ian Kent |
c5187b |
- source->stale = 1;
|
|
Ian Kent |
c5187b |
- }
|
|
Ian Kent |
c5187b |
- } else {
|
|
Ian Kent |
c5187b |
- /* Wildcard not in map but now is */
|
|
Ian Kent |
c5187b |
- if (wild & (CHE_OK | CHE_UPDATED))
|
|
Ian Kent |
c5187b |
- source->stale = 1;
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
pthread_cleanup_pop(1);
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
@@ -1062,9 +1019,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
Ian Kent |
c5187b |
* we never know about it.
|
|
Ian Kent |
c5187b |
*/
|
|
Ian Kent |
c5187b |
if (ap->type == LKP_INDIRECT && *key != '/') {
|
|
Ian Kent |
c5187b |
+ struct stat st;
|
|
Ian Kent |
c5187b |
char *lkp_key;
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
+ /*
|
|
Ian Kent |
c5187b |
+ * We can skip the map lookup and cache update altogether
|
|
Ian Kent |
c5187b |
+ * if we know the map hasn't been modified since it was
|
|
Ian Kent |
c5187b |
+ * last read. If it has then we can mark the map stale
|
|
Ian Kent |
c5187b |
+ * so a re-read is triggered following the lookup.
|
|
Ian Kent |
c5187b |
+ */
|
|
Ian Kent |
c5187b |
+ if (stat(ctxt->mapname, &st)) {
|
|
Ian Kent |
c5187b |
+ error(ap->logopt, MODPREFIX
|
|
Ian Kent |
c5187b |
+ "file map %s, could not stat", ctxt->mapname);
|
|
Ian Kent |
c5187b |
+ return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
c5187b |
+ }
|
|
Ian Kent |
c5187b |
+
|
|
Ian Kent |
c5187b |
cache_readlock(mc);
|
|
Ian Kent |
c5187b |
+ me = cache_lookup_first(mc);
|
|
Ian Kent |
c5187b |
+ if (me && st.st_mtime <= me->age)
|
|
Ian Kent |
c5187b |
+ goto do_cache_lookup;
|
|
Ian Kent |
c5187b |
+ else
|
|
Ian Kent |
c5187b |
+ source->stale = 1;
|
|
Ian Kent |
c5187b |
+
|
|
Ian Kent |
c5187b |
me = cache_lookup_distinct(mc, key);
|
|
Ian Kent |
c5187b |
if (me && me->multi)
|
|
Ian Kent |
c5187b |
lkp_key = strdup(me->multi->key);
|
|
Ian Kent |
c5187b |
@@ -1088,6 +1064,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
|
Ian Kent |
c5187b |
}
|
|
Ian Kent |
c5187b |
|
|
Ian Kent |
c5187b |
cache_readlock(mc);
|
|
Ian Kent |
c5187b |
+do_cache_lookup:
|
|
Ian Kent |
c5187b |
me = cache_lookup(mc, key);
|
|
Ian Kent |
c5187b |
/* Stale mapent => check for entry in alternate source or wildcard */
|
|
Ian Kent |
c5187b |
if (me && !me->mapent) {
|