]> git.sur5r.net Git - openldap/commitdiff
improve back-meta retry capabilities (ITS#4328)
authorPierangelo Masarati <ando@openldap.org>
Wed, 11 Jan 2006 19:33:44 +0000 (19:33 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 11 Jan 2006 19:33:44 +0000 (19:33 +0000)
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/conn.c

index 4f27415c37a323e92054fc8b56ebd0857d977213..a667e865671ed83155776987fc692c099c85f23a 100644 (file)
@@ -301,12 +301,15 @@ meta_back_release_conn(
        metaconn_t              *mc );
 
 extern int
-meta_back_retry(
+meta_back_retry_lock(
        Operation               *op,
        SlapReply               *rs,
        metaconn_t              *mc,
        int                     candidate,
-       ldap_back_send_t        sendok );
+       ldap_back_send_t        sendok,
+       int                     dolock );
+#define meta_back_retry(op, rs, mc, candidate, sendok) \
+       meta_back_retry_lock((op), (rs), (mc), (candidate), (sendok), 1)
 
 extern void
 meta_back_conn_free(
@@ -322,6 +325,14 @@ meta_back_init_one_conn(
        int                     ispriv,
        ldap_back_send_t        sendok );
 
+extern int
+meta_back_single_bind(
+       Operation               *op,
+       SlapReply               *rs,
+       metaconn_t              *mc,
+       int                     candidate,
+       int                     massage );
+
 extern int
 meta_back_dobind(
        Operation               *op,
@@ -329,7 +340,7 @@ meta_back_dobind(
        metaconn_t              *mc,
        ldap_back_send_t        sendok );
 
-int
+extern int
 meta_back_single_dobind(
        Operation               *op,
        SlapReply               *rs,
index 32389a75c15adaf5da917c4cde0fb127be27d90c..36e12ba0fc8c09d4ed33d7ae15a6f7d93b73e190 100644 (file)
@@ -41,14 +41,6 @@ static LDAP_REBIND_PROC      meta_back_default_rebind;
  */
 LDAP_REBIND_PROC       *meta_back_rebind_f = meta_back_default_rebind;
 
-static int
-meta_back_single_bind(
-       Operation               *op,
-       SlapReply               *rs,
-       metaconn_t              *mc,
-       int                     candidate,
-       int                     massage );
-
 int
 meta_back_bind( Operation *op, SlapReply *rs )
 {
@@ -272,7 +264,7 @@ retry_lock:;
  *
  * attempts to perform a bind with creds
  */
-static int
+int
 meta_back_single_bind(
        Operation               *op,
        SlapReply               *rs,
@@ -648,7 +640,7 @@ meta_back_dobind(
        for ( i = 0; i < mi->mi_ntargets; i++ ) {
                metatarget_t            *mt = &mi->mi_targets[ i ];
                metasingleconn_t        *msc = &mc->mc_conns[ i ];
-               int                     rc;
+               int                     rc, do_retry = 1;
                char                    *rootdn = NULL;
 
                /*
@@ -668,6 +660,7 @@ meta_back_dobind(
                        continue;
                }
 
+retry:;
                if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
                {
                        Operation       op2 = *op;
@@ -690,6 +683,13 @@ meta_back_dobind(
                if ( rc != LDAP_SUCCESS ) {
                        char            buf[ SLAP_TEXT_BUFLEN ];
 
+                       if ( rc == LDAP_UNAVAILABLE && do_retry ) {
+                               do_retry = 0;
+                               if ( meta_back_retry_lock( op, rs, mc, i, LDAP_BACK_DONTSEND, 0 ) ) {
+                                       goto retry;
+                               }
+                       }
+
                        snprintf( buf, sizeof( buf ),
                                "meta_back_dobind[%d]: (%s) err=%d.",
                                i, rootdn ? rootdn : "anonymous", rc );
index 08fcbea92c0f71447d372c62bda9d01a9079e112..cd5bad958ac8095aba21d9477a9dac9f5f4306c5 100644 (file)
@@ -444,17 +444,18 @@ error_return:;
 }
 
 /*
- * meta_back_retry
+ * meta_back_retry_lock
  * 
  * Retries one connection
  */
 int
-meta_back_retry(
+meta_back_retry_lock(
        Operation               *op,
        SlapReply               *rs,
        metaconn_t              *mc,
        int                     candidate,
-       ldap_back_send_t        sendok )
+       ldap_back_send_t        sendok,
+       int                     dolock )
 {
        metainfo_t              *mi = ( metainfo_t * )op->o_bd->be_private;
        metatarget_t            *mt = &mi->mi_targets[ candidate ];
@@ -469,7 +470,7 @@ retry_lock:;
        if ( mc->mc_refcnt == 1 ) {
                char    buf[ SLAP_TEXT_BUFLEN ];
 
-               while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) {
+               while ( dolock && ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) {
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
                        ldap_pvt_thread_yield();
                        goto retry_lock;
@@ -494,11 +495,27 @@ retry_lock:;
                        LDAP_BACK_CONN_ISPRIV( mc ), sendok );
 
                if ( rc == LDAP_SUCCESS ) {
-                       rc = meta_back_single_dobind( op, rs, mc, candidate,
+                       if ( be_isroot( op ) && !BER_BVISNULL( &mi->mi_targets[ candidate ].mt_pseudorootdn ) )
+                       {
+                               Operation       op2 = *op;
+
+                               op2.o_tag = LDAP_REQ_BIND;
+                               op2.o_req_dn = mi->mi_targets[ candidate ].mt_pseudorootdn;
+                               op2.o_req_ndn = mi->mi_targets[ candidate ].mt_pseudorootdn;
+                               op2.orb_cred = mi->mi_targets[ candidate ].mt_pseudorootpw;
+                               op2.orb_method = LDAP_AUTH_SIMPLE;
+
+                               rc = meta_back_single_bind( &op2, rs, mc, candidate, 0 );
+
+                       } else {
+                               rc = meta_back_single_dobind( op, rs, mc, candidate,
                                        sendok, mt->mt_nretries, 0 );
+                       }
                }
 
-               ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
+               if ( dolock ) {
+                       ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
+               }
        }
 
        if ( rc != LDAP_SUCCESS ) {