1 autofs-5.0.4 - always read file maps
3 From: Ian Kent <raven@themaw.net>
5 autofs tries to not load an entire map into the internal cache unless it
6 has to. For maps that do get loaded into the cache it relies on checks to
7 work out if a map is up to date in order to trigger a map read. This is
8 fine for maps that can do direct key lookups but file maps need to do a
9 linear search through the file when locating an entry for a key. For large
10 maps this can be a huge overhead. This patch make autofs always load file
11 based maps at start and makes use of the map file mtime to discover if the
12 cache needs to be refreshed.
16 daemon/lookup.c | 9 +++++--
17 modules/lookup_file.c | 65 ++++++++++++++++---------------------------------
18 3 files changed, 28 insertions(+), 47 deletions(-)
21 diff --git a/CHANGELOG b/CHANGELOG
22 index d4dd70b..afd1335 100644
26 - check for stale SASL credentials upon connect fail.
27 - add "forcestart" and "forcerestart" init script options to allow
28 use of 5.0.3 strartup behavior if required.
29 +- always read entire file map into cache to speed lookups.
31 4/11/2008 autofs-5.0.4
32 -----------------------
33 diff --git a/daemon/lookup.c b/daemon/lookup.c
34 index 741d846..e034348 100644
37 @@ -283,10 +283,13 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
38 * for the fail cases to function correctly and to cache the
41 - * We always need to whole map for direct mounts in order to
42 - * mount the triggers.
43 + * We always need to read the whole map for direct mounts in
44 + * order to mount the triggers. We also want to read the whole
45 + * map if it's a file map to avoid potentially lengthy linear
48 - if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
49 + if (strcmp(map->type, "file") &&
50 + !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
51 return NSS_STATUS_SUCCESS;
54 diff --git a/modules/lookup_file.c b/modules/lookup_file.c
55 index 95b9f6f..aafeb8b 100644
56 --- a/modules/lookup_file.c
57 +++ b/modules/lookup_file.c
58 @@ -44,7 +44,6 @@ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
60 struct lookup_context {
63 struct parse_mod *parse;
66 @@ -54,7 +53,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
68 struct lookup_context *ctxt;
69 char buf[MAX_ERR_BUF];
74 @@ -87,15 +85,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
78 - if (stat(ctxt->mapname, &st)) {
80 - logmsg(MODPREFIX "file map %s, could not stat",
85 - ctxt->mtime = st.st_mtime;
88 mapfmt = MAPFMT_DEFAULT;
90 @@ -391,9 +380,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
97 unsigned int path_len, ent_len;
100 @@ -428,8 +415,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
101 return NSS_STATUS_UNAVAIL;
107 entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
109 @@ -504,13 +489,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
113 - if (fstat(fd, &st)) {
114 - crit(logopt, MODPREFIX "file map %s, could not stat",
116 - return NSS_STATUS_UNAVAIL;
118 - ctxt->mtime = st.st_mtime;
122 return NSS_STATUS_SUCCESS;
123 @@ -642,9 +620,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
124 struct mapent_cache *mc;
130 unsigned int k_len, m_len;
133 @@ -684,8 +660,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
134 return NSS_STATUS_UNAVAIL;
140 entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
142 @@ -748,13 +722,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
146 - if (fstat(fd, &st)) {
148 - MODPREFIX "file map %s, could not stat",
150 - return NSS_STATUS_UNAVAIL;
152 - ctxt->mtime = st.st_mtime;
156 @@ -951,9 +918,6 @@ static int check_map_indirect(struct autofs_point *ap,
158 return NSS_STATUS_NOTFOUND;
160 - if (ret & CHE_UPDATED)
163 pthread_cleanup_push(cache_lock_cleanup, mc);
165 exists = cache_lookup_distinct(mc, key);
166 @@ -963,7 +927,6 @@ static int check_map_indirect(struct autofs_point *ap,
167 free(exists->mapent);
168 exists->mapent = NULL;
173 pthread_cleanup_pop(1);
174 @@ -985,14 +948,8 @@ static int check_map_indirect(struct autofs_point *ap,
175 we = cache_lookup_distinct(mc, "*");
177 /* Wildcard entry existed and is now gone */
178 - if (we->source == source && (wild & CHE_MISSING)) {
179 + if (we->source == source && (wild & CHE_MISSING))
180 cache_delete(mc, "*");
184 - /* Wildcard not in map but now is */
185 - if (wild & (CHE_OK | CHE_UPDATED))
188 pthread_cleanup_pop(1);
190 @@ -1062,9 +1019,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
191 * we never know about it.
193 if (ap->type == LKP_INDIRECT && *key != '/') {
198 + * We can skip the map lookup and cache update altogether
199 + * if we know the map hasn't been modified since it was
200 + * last read. If it has then we can mark the map stale
201 + * so a re-read is triggered following the lookup.
203 + if (stat(ctxt->mapname, &st)) {
204 + error(ap->logopt, MODPREFIX
205 + "file map %s, could not stat", ctxt->mapname);
206 + return NSS_STATUS_UNAVAIL;
210 + me = cache_lookup_first(mc);
211 + if (me && st.st_mtime <= me->age)
212 + goto do_cache_lookup;
216 me = cache_lookup_distinct(mc, key);
218 lkp_key = strdup(me->multi->key);
219 @@ -1088,6 +1064,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
224 me = cache_lookup(mc, key);
225 /* Stale mapent => check for entry in alternate source or wildcard */
226 if (me && !me->mapent) {