]> git.pld-linux.org Git - packages/autofs.git/blame - autofs-5.0.4-fix-negative-cache-non-existent-key.patch
- import latest patchset.
[packages/autofs.git] / autofs-5.0.4-fix-negative-cache-non-existent-key.patch
CommitLineData
e5fd101c
PS
1autofs-5.0.4 - fix negative cache non-existent key
2
3From: Ian Kent <raven@themaw.net>
4
5autofs was not recording map entries that don't exist for negative
6caching. This was causing unwanted network map lookups.
7---
8
9 CHANGELOG | 1 +
10 daemon/lookup.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--
11 modules/lookup_file.c | 20 ++++++++++++-------
12 modules/lookup_hosts.c | 21 ++++++++++++++++----
13 modules/lookup_ldap.c | 20 ++++++++++++-------
14 modules/lookup_nisplus.c | 19 ++++++++++++------
15 modules/lookup_program.c | 35 ++++++++++++++++++++++++++--------
16 modules/lookup_yp.c | 19 ++++++++++++------
17 8 files changed, 143 insertions(+), 40 deletions(-)
18
19
20diff --git a/CHANGELOG b/CHANGELOG
21index 88ca579..bd35b00 100644
22--- a/CHANGELOG
23+++ b/CHANGELOG
24@@ -2,6 +2,7 @@
25 -----------------------
26 - fix dumb libxml2 check
27 - fix nested submount expire deadlock.
28+- fix negative caching for non-existent map keys.
29
30 4/11/2008 autofs-5.0.4
31 -----------------------
32diff --git a/daemon/lookup.c b/daemon/lookup.c
33index 803df4f..0cf6e3f 100644
34--- a/daemon/lookup.c
35+++ b/daemon/lookup.c
36@@ -804,6 +804,45 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this,
37 return result;
38 }
39
40+static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
41+{
42+ struct master_mapent *entry = ap->entry;
43+ struct map_source *map;
44+ struct mapent *me;
45+
46+ /* Have we recorded the lookup fail for negative caching? */
47+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
48+ if (me)
49+ /*
50+ * Already exists in the cache, the mount fail updates
51+ * will update negative timeout status.
52+ */
53+ cache_unlock(me->mc);
54+ else {
55+ /* Notify only once after fail */
56+ error(ap->logopt, "key \"%s\" not found in map.", name);
57+
58+ /* Doesn't exist in any source, just add it somewhere */
59+ if (source)
60+ map = source;
61+ else
62+ map = entry->maps;
63+ if (map) {
64+ time_t now = time(NULL);
65+ int rv = CHE_FAIL;
66+
67+ cache_writelock(map->mc);
68+ rv = cache_update(map->mc, map, name, NULL, now);
69+ if (rv != CHE_FAIL) {
70+ me = cache_lookup_distinct(map->mc, name);
71+ me->status = now + ap->negative_timeout;
72+ }
73+ cache_unlock(map->mc);
74+ }
75+ }
76+ return;
77+}
78+
79 int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const char *name, int name_len)
80 {
81 struct master_mapent *entry = ap->entry;
82@@ -907,8 +946,13 @@ int lookup_nss_mount(struct autofs_point *ap, struct map_source *source, const c
83 send_map_update_request(ap);
84 pthread_cleanup_pop(1);
85
86- if (result == NSS_STATUS_NOTFOUND)
87- error(ap->logopt, "key \"%s\" not found in map.", name);
88+ /*
89+ * The last source lookup will return NSS_STATUS_NOTFOUND if the
90+ * map exits and the key has not been found but the map may also
91+ * not exist in which case the key is also not found.
92+ */
93+ if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL)
94+ update_negative_cache(ap, source, name);
95
96 return !result;
97 }
98diff --git a/modules/lookup_file.c b/modules/lookup_file.c
99index 807ceab..9e34b72 100644
100--- a/modules/lookup_file.c
101+++ b/modules/lookup_file.c
102@@ -1069,14 +1069,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
103 if (key_len > KEY_MAX_LEN)
104 return NSS_STATUS_NOTFOUND;
105
106- /* Check if we recorded a mount fail for this key */
107- cache_readlock(mc);
108- me = cache_lookup_distinct(mc, key);
109- if (me && me->status >= time(NULL)) {
110- cache_unlock(mc);
111- return NSS_STATUS_UNAVAIL;
112+ /* Check if we recorded a mount fail for this key anywhere */
113+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
114+ if (me) {
115+ if (me->status >= time(NULL)) {
116+ cache_unlock(me->mc);
117+ return NSS_STATUS_NOTFOUND;
118+ }
119+
120+ /* Negative timeout expired for non-existent entry. */
121+ if (!me->mapent)
122+ cache_delete(me->mc, key);
123+
124+ cache_unlock(me->mc);
125 }
126- cache_unlock(mc);
127
128 /*
129 * We can't check the direct mount map as if it's not in
130diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
131index bf24d7f..f8d4269 100644
132--- a/modules/lookup_hosts.c
133+++ b/modules/lookup_hosts.c
134@@ -136,12 +136,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
135
136 mc = source->mc;
137
138+ /* Check if we recorded a mount fail for this key anywhere */
139+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
140+ if (me) {
141+ if (me->status >= time(NULL)) {
142+ cache_unlock(me->mc);
143+ return NSS_STATUS_NOTFOUND;
144+ }
145+
146+ if (!me->mapent) {
147+ cache_delete(me->mc, name);
148+ me = NULL;
149+ }
150+
151+ cache_unlock(me->mc);
152+ }
153+
154 cache_readlock(mc);
155 me = cache_lookup_distinct(mc, name);
156- if (me && me->status >= time(NULL)) {
157- cache_unlock(mc);
158- return NSS_STATUS_NOTFOUND;
159- } else if (!me) {
160+ if (!me) {
161 cache_unlock(mc);
162 /*
163 * We haven't read the list of hosts into the
164diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
165index 31c2c13..42c3235 100644
166--- a/modules/lookup_ldap.c
167+++ b/modules/lookup_ldap.c
168@@ -2709,14 +2709,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
169 if (key_len > KEY_MAX_LEN)
170 return NSS_STATUS_NOTFOUND;
171
172- /* Check if we recorded a mount fail for this key */
173- cache_readlock(mc);
174- me = cache_lookup_distinct(mc, key);
175- if (me && me->status >= time(NULL)) {
176- cache_unlock(mc);
177- return NSS_STATUS_NOTFOUND;
178+ /* Check if we recorded a mount fail for this key anywhere */
179+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
180+ if (me) {
181+ if (me->status >= time(NULL)) {
182+ cache_unlock(me->mc);
183+ return NSS_STATUS_NOTFOUND;
184+ }
185+
186+ /* Negative timeout expired for non-existent entry. */
187+ if (!me->mapent)
188+ cache_delete(me->mc, key);
189+
190+ cache_unlock(me->mc);
191 }
192- cache_unlock(mc);
193
194 /*
195 * We can't check the direct mount map as if it's not in
196diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
197index 755556d..f15465f 100644
198--- a/modules/lookup_nisplus.c
199+++ b/modules/lookup_nisplus.c
200@@ -493,13 +493,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
201 if (key_len > KEY_MAX_LEN)
202 return NSS_STATUS_NOTFOUND;
203
204- cache_readlock(mc);
205- me = cache_lookup_distinct(mc, key);
206- if (me && me->status >= time(NULL)) {
207- cache_unlock(mc);
208- return NSS_STATUS_NOTFOUND;
209+ /* Check if we recorded a mount fail for this key anywhere */
210+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
211+ if (me) {
212+ if (me->status >= time(NULL)) {
213+ cache_unlock(me->mc);
214+ return NSS_STATUS_NOTFOUND;
215+ }
216+
217+ /* Negative timeout expired for non-existent entry. */
218+ if (!me->mapent)
219+ cache_delete(me->mc, key);
220+
221+ cache_unlock(me->mc);
222 }
223- cache_unlock(mc);
224
225 /*
226 * We can't check the direct mount map as if it's not in
227diff --git a/modules/lookup_program.c b/modules/lookup_program.c
228index daf874d..bf32d3b 100644
229--- a/modules/lookup_program.c
230+++ b/modules/lookup_program.c
231@@ -131,13 +131,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
232
233 mc = source->mc;
234
235+ /* Check if we recorded a mount fail for this key anywhere */
236+ me = lookup_source_mapent(ap, name, LKP_DISTINCT);
237+ if (me) {
238+ if (me->status >= time(NULL)) {
239+ cache_unlock(me->mc);
240+ return NSS_STATUS_NOTFOUND;
241+ }
242+
243+ /* Negative timeout expired for non-existent entry. */
244+ if (!me->mapent)
245+ cache_delete(me->mc, name);
246+
247+ cache_unlock(me->mc);
248+ }
249+
250 /* Catch installed direct offset triggers */
251- cache_readlock(mc);
252+ cache_writelock(mc);
253 me = cache_lookup_distinct(mc, name);
254- if (me && me->status >= time(NULL)) {
255- cache_unlock(mc);
256- return NSS_STATUS_NOTFOUND;
257- } else if (!me) {
258+ if (!me) {
259 cache_unlock(mc);
260 /*
261 * If there's a '/' in the name and the offset is not in
262@@ -149,8 +161,6 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
263 return NSS_STATUS_NOTFOUND;
264 }
265 } else {
266- cache_unlock(mc);
267-
268 /* Otherwise we found a valid offset so try mount it */
269 debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent);
270
271@@ -163,19 +173,28 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
272 */
273 if (strchr(name, '/') ||
274 me->age + ap->negative_timeout > time(NULL)) {
275+ char *ent = NULL;
276+
277+ if (me->mapent) {
278+ ent = alloca(strlen(me->mapent) + 1);
279+ strcpy(ent, me->mapent);
280+ }
281+ cache_unlock(mc);
282 master_source_current_wait(ap->entry);
283 ap->entry->current = source;
284 ret = ctxt->parse->parse_mount(ap, name,
285- name_len, me->mapent, ctxt->parse->context);
286+ name_len, ent, ctxt->parse->context);
287 goto out_free;
288 } else {
289 if (me->multi) {
290+ cache_unlock(mc);
291 warn(ap->logopt, MODPREFIX
292 "unexpected lookup for active multi-mount"
293 " key %s, returning fail", name);
294 return NSS_STATUS_UNAVAIL;
295 }
296 cache_delete(mc, name);
297+ cache_unlock(mc);
298 }
299 }
300
301diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
302index 8b6408b..1b62f57 100644
303--- a/modules/lookup_yp.c
304+++ b/modules/lookup_yp.c
305@@ -603,13 +603,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
306 if (key_len > KEY_MAX_LEN)
307 return NSS_STATUS_NOTFOUND;
308
309- cache_readlock(mc);
310- me = cache_lookup_distinct(mc, key);
311- if (me && me->status >= time(NULL)) {
312- cache_unlock(mc);
313- return NSS_STATUS_NOTFOUND;
314+ /* Check if we recorded a mount fail for this key anywhere */
315+ me = lookup_source_mapent(ap, key, LKP_DISTINCT);
316+ if (me) {
317+ if (me->status >= time(NULL)) {
318+ cache_unlock(me->mc);
319+ return NSS_STATUS_NOTFOUND;
320+ }
321+
322+ /* Negative timeout expired for non-existent entry. */
323+ if (!me->mapent)
324+ cache_delete(me->mc, key);
325+
326+ cache_unlock(me->mc);
327 }
328- cache_unlock(mc);
329
330 /*
331 * We can't check the direct mount map as if it's not in
This page took 0.06353 seconds and 4 git commands to generate.