1 autofs-5.0.4 - uris list locking fix
3 From: Ian Kent <raven@themaw.net>
5 The ldap uris list doesn't need to change we just need to keep
6 track of current server uri in the list and try to connect in
7 a round robin order. Also it's possible multiple concurrent
8 connection attempts may not be able to use the full list of
9 servers (if one is present).
13 include/lookup_ldap.h | 3 +-
14 modules/lookup_ldap.c | 68 ++++++++++++++++++++++---------------------------
15 3 files changed, 33 insertions(+), 39 deletions(-)
18 diff --git a/CHANGELOG b/CHANGELOG
19 index 3199e4d..b093451 100644
23 - clear the quoted flag after each character from program map input.
24 - use CLOEXEC flag for setmntent also.
25 - fix hosts map use after free.
26 +- fix uri list locking (again).
28 4/11/2008 autofs-5.0.4
29 -----------------------
30 diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
31 index f9ed778..b47bf5d 100644
32 --- a/include/lookup_ldap.h
33 +++ b/include/lookup_ldap.h
34 @@ -55,7 +55,8 @@ struct lookup_context {
35 * given in configuration.
37 pthread_mutex_t uris_mutex;
38 - struct list_head *uri;
39 + struct list_head *uris;
40 + struct ldap_uri *uri;
42 struct ldap_searchdn *sdns;
44 diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
45 index 6ba80eb..b6784e1 100644
46 --- a/modules/lookup_ldap.c
47 +++ b/modules/lookup_ldap.c
48 @@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt)
52 -int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
53 +int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
57 @@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
58 rv = ldap_simple_bind_s(ldap, NULL, NULL);
60 if (rv != LDAP_SUCCESS) {
63 crit(logopt, MODPREFIX
64 "Unable to bind to the LDAP server: "
65 "%s, error %s", ctxt->server ? "" : "(default)",
68 - struct ldap_uri *uri;
69 - uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
70 info(logopt, MODPREFIX "Unable to bind to the LDAP server: "
71 - "%s, error %s", uri->uri, ldap_err2string(rv));
72 + "%s, error %s", uri, ldap_err2string(rv));
76 @@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
80 -static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
81 +static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
83 char *host = NULL, *nhost;
84 int rv, need_base = 1;
85 @@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
86 rv = autofs_sasl_bind(logopt, ldap, ctxt);
87 debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
89 - rv = bind_ldap_anonymous(logopt, ldap, ctxt);
90 + rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
91 debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
94 - rv = bind_ldap_anonymous(logopt, ldap, ctxt);
95 + rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
96 debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
99 @@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
103 - if (!do_bind(logopt, ldap, ctxt)) {
104 + if (!do_bind(logopt, ldap, uri, ctxt)) {
105 unbind_ldap_connection(logopt, ldap, ctxt);
108 @@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
112 - if (!do_bind(logopt, ldap, ctxt)) {
113 + if (!do_bind(logopt, ldap, uri, ctxt)) {
114 unbind_ldap_connection(logopt, ldap, ctxt);
115 autofs_sasl_dispose(ctxt);
116 error(logopt, MODPREFIX "cannot bind to server");
117 @@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
120 struct ldap_uri *this;
121 - struct list_head *p;
123 + struct list_head *p, *first;
125 /* Try each uri in list, add connect fails to tmp list */
126 uris_mutex_lock(ctxt);
127 - p = ctxt->uri->next;
128 - while(p != ctxt->uri) {
130 + first = ctxt->uris;
132 + first = &ctxt->uri->list;
133 + uris_mutex_unlock(ctxt);
135 + while(p != first) {
136 + /* Skip list head */
137 + if (p == ctxt->uris) {
141 this = list_entry(p, struct ldap_uri, list);
142 - uris_mutex_unlock(ctxt);
143 debug(logopt, "trying server %s", this->uri);
144 ldap = connect_to_server(logopt, this->uri, ctxt);
146 info(logopt, "connected to uri %s", this->uri);
147 uris_mutex_lock(ctxt);
149 + uris_mutex_unlock(ctxt);
152 - uris_mutex_lock(ctxt);
154 - list_del_init(&this->list);
155 - list_add_tail(&this->list, &tmp);
158 - * Successfuly connected uri (head of list) and untried uris are
159 - * in ctxt->uri list. Make list of remainder and failed uris with
160 - * failed uris at end and assign back to ctxt-uri.
162 - list_splice(ctxt->uri, &tmp);
163 - INIT_LIST_HEAD(ctxt->uri);
164 - list_splice(&tmp, ctxt->uri);
165 - uris_mutex_unlock(ctxt);
169 @@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
170 struct ldap_uri *this;
173 - if (ctxt->server || !ctxt->uri) {
174 + if (ctxt->server || !ctxt->uris) {
175 ldap = do_connect(logopt, ctxt->server, ctxt);
179 uris_mutex_lock(ctxt);
180 - this = list_entry(ctxt->uri->next, struct ldap_uri, list);
182 uris_mutex_unlock(ctxt);
183 ldap = do_connect(logopt, this->uri, ctxt);
187 - /* Failed to connect, put at end of list */
188 - uris_mutex_lock(ctxt);
189 - list_del_init(&this->list);
190 - list_add_tail(&this->list, ctxt->uri);
191 - uris_mutex_unlock(ctxt);
192 + /* Failed to connect, try to find a new server */
195 autofs_sasl_dispose(ctxt);
196 @@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt)
197 free(ctxt->cur_host);
201 - defaults_free_uris(ctxt->uri);
203 + defaults_free_uris(ctxt->uris);
204 ret = pthread_mutex_destroy(&ctxt->uris_mutex);
207 @@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
210 if (!list_empty(uris))
215 "no valid uris found in config list"
216 @@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
220 - if (ctxt->server || !ctxt->uri) {
221 + if (ctxt->server || !ctxt->uris) {
222 ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);