]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index 6379d18..a9e509d 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -48,6 +48,7 @@ | |
6 | - eliminate NULL proc ping for singleton host or local mounts. | |
7 | - fix incorrect read/write size of startup status token (Matthias Koenig). | |
8 | - fix off-by-one error for lookup of map keys exactly 255 characters long. | |
9 | +- improve handling of server not available. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/daemon/lookup.c b/daemon/lookup.c | |
14 | index 0be10d3..eb72411 100644 | |
15 | --- a/daemon/lookup.c | |
16 | +++ b/daemon/lookup.c | |
17 | @@ -298,8 +298,6 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a | |
18 | ||
19 | status = lookup->lookup_read_map(ap, age, lookup->context); | |
20 | ||
21 | - map->stale = 0; | |
22 | - | |
23 | /* | |
24 | * For maps that don't support enumeration return success | |
25 | * and do whatever we must to have autofs function with an | |
26 | @@ -533,6 +531,10 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time | |
27 | if (result == NSS_STATUS_UNKNOWN) | |
28 | continue; | |
29 | ||
30 | + /* Don't try to update the map cache if it's unavailable */ | |
31 | + if (result == NSS_STATUS_UNAVAIL) | |
32 | + map->stale = 0; | |
33 | + | |
34 | if (result == NSS_STATUS_SUCCESS) { | |
35 | at_least_one = 1; | |
36 | result = NSS_STATUS_TRYAGAIN; | |
37 | @@ -553,7 +555,7 @@ int lookup_nss_read_map(struct autofs_point *ap, struct map_source *source, time | |
38 | } | |
39 | pthread_cleanup_pop(1); | |
40 | ||
41 | - if (!result || at_least_one) | |
42 | + if (!result || at_least_one) | |
43 | return 1; | |
44 | ||
45 | return 0; | |
46 | diff --git a/daemon/state.c b/daemon/state.c | |
47 | index cf07aac..5bccfef 100644 | |
48 | --- a/daemon/state.c | |
49 | +++ b/daemon/state.c | |
50 | @@ -432,6 +432,7 @@ static void *do_readmap(void *arg) | |
51 | me = cache_enumerate(mc, me); | |
52 | } | |
53 | pthread_cleanup_pop(1); | |
54 | + map->stale = 0; | |
55 | map = map->next; | |
56 | } | |
57 | pthread_cleanup_pop(1); | |
58 | diff --git a/include/automount.h b/include/automount.h | |
59 | index fa5cd97..133fd32 100644 | |
60 | --- a/include/automount.h | |
61 | +++ b/include/automount.h | |
62 | @@ -121,6 +121,7 @@ struct autofs_point; | |
63 | #define CHE_MISSING 0x0008 | |
64 | #define CHE_COMPLETED 0x0010 | |
65 | #define CHE_DUPLICATE 0x0020 | |
66 | +#define CHE_UNAVAIL 0x0040 | |
67 | ||
68 | #define HASHSIZE 77 | |
69 | #define NEGATIVE_TIMEOUT 10 | |
70 | diff --git a/modules/lookup_file.c b/modules/lookup_file.c | |
71 | index 550bf5c..a77068a 100644 | |
72 | --- a/modules/lookup_file.c | |
73 | +++ b/modules/lookup_file.c | |
74 | @@ -469,11 +469,14 @@ int lookup_read_master(struct master *master, time_t age, void *context) | |
75 | master->recurse = 1;; | |
76 | master->depth++; | |
77 | status = lookup_nss_read_master(master, age); | |
78 | - if (!status) | |
79 | + if (!status) { | |
80 | warn(logopt, | |
81 | MODPREFIX | |
82 | "failed to read included master map %s", | |
83 | master->name); | |
84 | + fclose(f); | |
85 | + return NSS_STATUS_UNAVAIL; | |
86 | + } | |
87 | master->depth--; | |
88 | master->recurse = 0; | |
89 | ||
90 | @@ -484,6 +487,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) | |
91 | if (!buffer) { | |
92 | error(logopt, | |
93 | MODPREFIX "could not malloc parse buffer"); | |
94 | + fclose(f); | |
95 | return NSS_STATUS_UNAVAIL; | |
96 | } | |
97 | memset(buffer, 0, blen); | |
98 | @@ -721,9 +725,12 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) | |
99 | ||
100 | /* Gim'ee some o' that 16k stack baby !! */ | |
101 | status = lookup_nss_read_map(ap, inc_source, age); | |
102 | - if (!status) | |
103 | + if (!status) { | |
104 | warn(ap->logopt, | |
105 | "failed to read included map %s", key); | |
106 | + fclose(f); | |
107 | + return NSS_STATUS_UNAVAIL; | |
108 | + } | |
109 | } else { | |
110 | char *s_key; | |
111 | ||
112 | diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c | |
113 | index b8484a2..7effbf1 100644 | |
114 | --- a/modules/lookup_ldap.c | |
115 | +++ b/modules/lookup_ldap.c | |
116 | @@ -1755,7 +1755,7 @@ static int lookup_one(struct autofs_point *ap, | |
117 | /* Initialize the LDAP context. */ | |
118 | ldap = do_reconnect(ap->logopt, ctxt); | |
119 | if (!ldap) | |
120 | - return CHE_FAIL; | |
121 | + return CHE_UNAVAIL; | |
122 | ||
123 | debug(ap->logopt, | |
124 | MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->qdn); | |
125 | @@ -1999,6 +1999,21 @@ static int check_map_indirect(struct autofs_point *ap, | |
126 | if (ret == CHE_FAIL) { | |
127 | pthread_setcancelstate(cur_state, NULL); | |
128 | return NSS_STATUS_NOTFOUND; | |
129 | + } else if (ret == CHE_UNAVAIL) { | |
130 | + /* | |
131 | + * If the server is down and the entry exists in the cache | |
132 | + * and belongs to this map return success and use the entry. | |
133 | + */ | |
134 | + struct mapent *exists = cache_lookup(mc, key); | |
135 | + if (exists && exists->source == source) { | |
136 | + pthread_setcancelstate(cur_state, NULL); | |
137 | + return NSS_STATUS_SUCCESS; | |
138 | + } | |
139 | + | |
140 | + warn(ap->logopt, | |
141 | + MODPREFIX "lookup for %s failed: connection failed", key); | |
142 | + | |
143 | + return NSS_STATUS_UNAVAIL; | |
144 | } | |
145 | pthread_setcancelstate(cur_state, NULL); | |
146 | ||
147 | diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c | |
148 | index fee8b16..628ffcf 100644 | |
149 | --- a/modules/lookup_nisplus.c | |
150 | +++ b/modules/lookup_nisplus.c | |
151 | @@ -385,9 +385,18 @@ static int check_map_indirect(struct autofs_point *ap, | |
152 | return NSS_STATUS_NOTFOUND; | |
153 | ||
154 | if (ret < 0) { | |
155 | + /* | |
156 | + * If the server is down and the entry exists in the cache | |
157 | + * and belongs to this map return success and use the entry. | |
158 | + */ | |
159 | + exists = cache_lookup(mc, key); | |
160 | + if (exists && exists->source == source) | |
161 | + return NSS_STATUS_SUCCESS; | |
162 | + | |
163 | warn(ap->logopt, | |
164 | MODPREFIX "lookup for %s failed: %s", | |
165 | key, nis_sperrno(-ret)); | |
166 | + | |
167 | return NSS_STATUS_UNAVAIL; | |
168 | } | |
169 | ||
170 | diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c | |
171 | index 5f4f95f..f5097dc 100644 | |
172 | --- a/modules/lookup_yp.c | |
173 | +++ b/modules/lookup_yp.c | |
174 | @@ -239,6 +239,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) | |
175 | MODPREFIX "read of master map %s failed: %s", | |
176 | mapname, yperr_string(err)); | |
177 | ||
178 | + if (err == YPERR_PMAP || err == YPERR_YPSERV) | |
179 | + return NSS_STATUS_UNAVAIL; | |
180 | + | |
181 | return NSS_STATUS_NOTFOUND; | |
182 | } | |
183 | ||
184 | @@ -336,6 +339,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) | |
185 | MODPREFIX "read of map %s failed: %s", | |
186 | ap->path, yperr_string(err)); | |
187 | ||
188 | + if (err == YPERR_PMAP || err == YPERR_YPSERV) | |
189 | + return NSS_STATUS_UNAVAIL; | |
190 | + | |
191 | return NSS_STATUS_NOTFOUND; | |
192 | } | |
193 | ||
194 | @@ -481,9 +487,18 @@ static int check_map_indirect(struct autofs_point *ap, | |
195 | return NSS_STATUS_NOTFOUND; | |
196 | ||
197 | if (ret < 0) { | |
198 | + /* | |
199 | + * If the server is down and the entry exists in the cache | |
200 | + * and belongs to this map return success and use the entry. | |
201 | + */ | |
202 | + exists = cache_lookup(mc, key); | |
203 | + if (exists && exists->source == source) | |
204 | + return NSS_STATUS_SUCCESS; | |
205 | + | |
206 | warn(ap->logopt, | |
207 | MODPREFIX "lookup for %s failed: %s", | |
208 | key, yperr_string(-ret)); | |
209 | + | |
210 | return NSS_STATUS_UNAVAIL; | |
211 | } | |
212 |