]> git.sur5r.net Git - openldap/commitdiff
more on recovery (ITS#4429)
authorPierangelo Masarati <ando@openldap.org>
Mon, 3 Apr 2006 00:32:59 +0000 (00:32 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 3 Apr 2006 00:32:59 +0000 (00:32 +0000)
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/conn.c
servers/slapd/back-meta/search.c

index 78bc791c3c354b0d5a566bb7684554e76c53c1bd..43d5fa3da56920ec427aa6026406e7a11dfb15bf 100644 (file)
@@ -299,8 +299,9 @@ extern void
 meta_back_release_conn_lock(
                Operation               *op,
        metaconn_t              *mc,
+       int                     dofree,
        int                     dolock );
-#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 )
+#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 0, 1 )
 
 extern int
 meta_back_retry(
@@ -343,7 +344,7 @@ extern int
 meta_back_single_dobind(
        Operation               *op,
        SlapReply               *rs,
-       metaconn_t              *msc,
+       metaconn_t              **mcp,
        int                     candidate,
        ldap_back_send_t        sendok,
        int                     retries,
@@ -401,6 +402,11 @@ extern int
 meta_clear_one_candidate(
        metasingleconn_t        *mc );
 
+extern int
+meta_clear_candidates(
+       Operation               *op,
+       metaconn_t              *mc );
+
 /*
  * Dn cache stuff (experimental)
  */
index 1ec7217ab5c3eec7376056c36132e844c2f3221f..1ca6a0a9e52dcbdb2a9b83851eae7b5711cb6d49 100644 (file)
@@ -179,6 +179,10 @@ meta_back_bind( Operation *op, SlapReply *rs )
 
                if ( lerr != LDAP_SUCCESS ) {
                        rc = rs->sr_err = lerr;
+                       /* FIXME: in some cases (e.g. unavailable)
+                        * do not assume it's not candidate; rather
+                        * mark this as an error to be eventually
+                        * reported to client */
                        candidates[ i ].sr_tag = META_NOT_CANDIDATE;
                        break;
                }
@@ -214,11 +218,7 @@ retry_lock:;
                                meta_back_conndn_cmp, meta_back_conndn_dup );
                        ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
                        if ( lerr == -1 ) {
-                               for ( i = 0; i < mi->mi_ntargets; ++i ) {
-                                       if ( mc->mc_conns[ i ].msc_ld != NULL ) {
-                                               meta_clear_one_candidate( &mc->mc_conns[ i ] );
-                                       }
-                               }
+                               meta_clear_candidates( op, mc );
 
                                /* we can do this because mc_refcnt == 1 */
                                mc->mc_refcnt = 0;
@@ -305,8 +305,9 @@ meta_back_single_bind(
                dc.ctx = "bindDN";
 
                if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
-                       send_ldap_result( op, rs );
-                       return -1;
+                       rs->sr_text = "DN rewrite error";
+                       rs->sr_err = LDAP_OTHER;
+                       return rs->sr_err;
                }
 
        } else {
@@ -376,8 +377,8 @@ retry:;
                        }
 
                        snprintf( buf, sizeof( buf ),
-                               "err=%d nretries=%d",
-                               rs->sr_err, nretries );
+                               "err=%d (%s) nretries=%d",
+                               rs->sr_err, ldap_err2string( rs->sr_err ), nretries );
                        Debug( LDAP_DEBUG_ANY,
                                "### %s meta_back_single_bind[%d]: %s.\n",
                                op->o_log_prefix, candidate, buf );
@@ -442,7 +443,7 @@ int
 meta_back_single_dobind(
        Operation               *op,
        SlapReply               *rs,
-       metaconn_t              *mc,
+       metaconn_t              **mcp,
        int                     candidate,
        ldap_back_send_t        sendok,
        int                     nretries,
@@ -450,6 +451,7 @@ meta_back_single_dobind(
 {
        metainfo_t              *mi = ( metainfo_t * )op->o_bd->be_private;
        metatarget_t            *mt = &mi->mi_targets[ candidate ];
+       metaconn_t              *mc = *mcp;
        metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
        int                     rc;
        static struct berval    cred = BER_BVC( "" );
@@ -459,6 +461,24 @@ meta_back_single_dobind(
 
        assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
 
+       /*
+        * meta_back_single_dobind() calls meta_back_single_bind()
+        * if required.
+        */
+       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, *mcp, candidate, 0 );
+               goto done;
+       }
+
        /*
         * Otherwise an anonymous bind is performed
         * (note: if the target was already bound, the anonymous
@@ -533,8 +553,8 @@ retry:;
                        }
 
                        snprintf( buf, sizeof( buf ),
-                               "err=%d nretries=%d",
-                               rs->sr_err, nretries );
+                               "err=%d (%s) nretries=%d",
+                               rs->sr_err, ldap_err2string( rs->sr_err ), nretries );
                        Debug( LDAP_DEBUG_ANY,
                                "### %s meta_back_single_dobind[%d]: %s.\n",
                                op->o_log_prefix, candidate, buf );
@@ -591,9 +611,15 @@ retry:;
                rc = slap_map_api2result( rs );
        }
 
+done:;
        rs->sr_err = rc;
-       if ( rc != LDAP_SUCCESS && ( sendok & LDAP_BACK_SENDERR ) ) {
-               send_ldap_result( op, rs );
+       if ( rc != LDAP_SUCCESS && META_BACK_ONERR_STOP( mi ) ) {
+               meta_back_release_conn_lock( op, mc, 1, dolock );
+               *mcp = NULL;
+
+               if ( sendok & LDAP_BACK_SENDERR ) {
+                       send_ldap_result( op, rs );
+               }
        }
 
        return rc;
@@ -659,28 +685,21 @@ meta_back_dobind(
                }
 
 retry:;
-               if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
-               {
-                       Operation       op2 = *op;
-
-                       op2.o_tag = LDAP_REQ_BIND;
-                       op2.o_req_dn = mi->mi_targets[ i ].mt_pseudorootdn;
-                       op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn;
-                       op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
-                       op2.orb_method = LDAP_AUTH_SIMPLE;
-
-                       rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val;
-
-                       rc = meta_back_single_bind( &op2, rs, mc, i, 0 );
-
-               } else {
-                       rc = meta_back_single_dobind( op, rs, mc, i,
-                               LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
-               }
-
+               rc = meta_back_single_dobind( op, rs, &mc, i,
+                       LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
+               /*
+                * NOTE: meta_back_single_dobind() already retries;
+                * in case of failure, it resets mc...
+                */
                if ( rc != LDAP_SUCCESS ) {
                        char            buf[ SLAP_TEXT_BUFLEN ];
 
+                       if ( mc == NULL ) {
+                               /* meta_back_single_dobind() already sent 
+                                * response and released connection */
+                               goto send_err;
+                       }
+
                        if ( rc == LDAP_UNAVAILABLE && do_retry ) {
                                do_retry = 0;
                                if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
@@ -690,8 +709,9 @@ retry:;
                        }
 
                        snprintf( buf, sizeof( buf ),
-                               "meta_back_dobind[%d]: (%s) err=%d.",
-                               i, rootdn ? rootdn : "anonymous", rc );
+                               "meta_back_dobind[%d]: (%s) err=%d (%s).",
+                               i, rootdn ? rootdn : "anonymous",
+                               rc, ldap_err2string( rc ) );
                        Debug( LDAP_DEBUG_ANY,
                                "%s %s\n",
                                op->o_log_prefix, buf, 0 );
@@ -709,6 +729,7 @@ retry:;
                                bound = 0;
                                goto done;
                        }
+
                        continue;
                } /* else */
                
@@ -734,15 +755,18 @@ done:;
        if ( bound == 0 ) {
                meta_back_release_conn( op, mc );
 
+send_err:;
                if ( sendok & LDAP_BACK_SENDERR ) {
                        if ( rs->sr_err == LDAP_SUCCESS ) {
                                rs->sr_err = LDAP_BUSY;
                        }
                        send_ldap_result( op, rs );
                }
+
+               return 0;
        }
 
-       return( bound > 0 );
+       return ( bound > 0 );
 }
 
 /*
index 1986ab3bd6f45158343099039b1893463867fa8a..794d1b3a471a80289ee7da64b0f055482d216210 100644 (file)
@@ -206,3 +206,22 @@ meta_clear_one_candidate(
        return 0;
 }
 
+/*
+ * meta_clear_candidates
+ *
+ * clears all candidates
+ */
+int
+meta_clear_candidates( Operation *op, metaconn_t *mc )
+{
+       metainfo_t      *mi = ( metainfo_t * )op->o_bd->be_private;
+       int             c;
+
+       for ( c = 0; c < mi->mi_ntargets; c++ ) {
+               if ( mc->mc_conns[ c ].msc_ld != NULL ) {
+                       meta_clear_one_candidate( &mc->mc_conns[ c ] );
+               }
+       }
+
+       return 0;
+}
index 9f6313eef3d456ae1d44ee03399396ef37c4c151..dce20023bbaa2f9f7045160aa9094c230cc83f00 100644 (file)
@@ -517,26 +517,12 @@ meta_back_retry(
                        LDAP_BACK_CONN_ISPRIV( mc ), sendok );
 
                if ( rc == LDAP_SUCCESS ) {
-                       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 );
-                       }
+                       rc = meta_back_single_dobind( op, rs, mcp, candidate,
+                               sendok, mt->mt_nretries, 0 );
                }
 
        } else {
-               meta_back_release_conn_lock( op, mc, 0 );
+               meta_back_release_conn_lock( op, mc, 1, 0 );
                *mcp = NULL;
 
                if ( sendok ) {
@@ -1246,6 +1232,7 @@ void
 meta_back_release_conn_lock(
                Operation               *op,
        metaconn_t              *mc,
+       int                     dofree,
        int                     dolock )
 {
        metainfo_t      *mi = ( metainfo_t * )op->o_bd->be_private;
@@ -1258,7 +1245,8 @@ meta_back_release_conn_lock(
        assert( mc->mc_refcnt > 0 );
        mc->mc_refcnt--;
        LDAP_BACK_CONN_BINDING_CLEAR( mc );
-       if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
+       if ( dofree
+               || ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
                || ( mi->mi_idle_timeout != 0 && op->o_time > mc->mc_time + mi->mi_idle_timeout ) )
        {
                Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld expired.\n",
@@ -1266,6 +1254,7 @@ meta_back_release_conn_lock(
                (void)avl_delete( &mi->mi_conninfo.lai_tree,
                        ( caddr_t )mc, meta_back_conndnmc_cmp );
                if ( mc->mc_refcnt == 0 ) {
+                       meta_clear_candidates( op, mc );
                        meta_back_conn_free( mc );
                }
        }
index 00cd89f1f47c2404f55e628f868862cbc9c7b974..1137fe20abec5b6176a7f9e848dffe584d520e44 100644 (file)
@@ -604,29 +604,26 @@ really_bad:;
 
                                /* massage matchedDN if need be */
                                if ( candidates[ i ].sr_matched != NULL ) {
-                                       {
-                                               struct berval   match, mmatch;
-
-                                               ber_str2bv( candidates[ i ].sr_matched,
-                                                       0, 0, &match );
-                                               candidates[ i ].sr_matched = NULL;
-
-                                               dc.ctx = "matchedDN";
-                                               dc.target = &mi->mi_targets[ i ];
-                                               if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
-                                                       if ( mmatch.bv_val == match.bv_val ) {
-                                                               candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
-
-                                                       } else {
-                                                               candidates[ i ].sr_matched = mmatch.bv_val;
-                                                       }
-
-                                                       candidate_match++;
-                                               } 
-                                               ldap_memfree( match.bv_val );
-                                       }
-                               }
+                                       struct berval   match, mmatch;
+
+                                       ber_str2bv( candidates[ i ].sr_matched,
+                                               0, 0, &match );
+                                       candidates[ i ].sr_matched = NULL;
+
+                                       dc.ctx = "matchedDN";
+                                       dc.target = &mi->mi_targets[ i ];
+                                       if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
+                                               if ( mmatch.bv_val == match.bv_val ) {
+                                                       candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
+
+                                               } else {
+                                                       candidates[ i ].sr_matched = mmatch.bv_val;
+                                               }
 
+                                               candidate_match++;
+                                       } 
+                                       ldap_memfree( match.bv_val );
+                               }
 
                                /* add references to array */
                                if ( references ) {
@@ -662,13 +659,21 @@ really_bad:;
                                rs->sr_err = candidates[ i ].sr_err;
                                sres = slap_map_api2result( rs );
 
-                               snprintf( buf, sizeof( buf ),
-                                       "%s meta_back_search[%ld] "
-                                       "match=\"%s\" err=%ld\n",
-                                       op->o_log_prefix, i,
-                                       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
-                                       (long) candidates[ i ].sr_err );
-                               Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
+                               if ( LogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {
+                                       snprintf( buf, sizeof( buf ),
+                                               "%s meta_back_search[%ld] "
+                                               "match=\"%s\" err=%ld",
+                                               op->o_log_prefix, i,
+                                               candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
+                                               (long) candidates[ i ].sr_err );
+                                       if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
+                                               Debug( LDAP_DEBUG_TRACE, "%s.\n", buf, 0, 0 );
+
+                                       } else {
+                                               Debug( LDAP_DEBUG_ANY, "%s (%s).\n",
+                                                       buf, ldap_err2string( candidates[ i ].sr_err ), 0 );
+                                       }
+                               }
 
                                switch ( sres ) {
                                case LDAP_NO_SUCH_OBJECT:
@@ -1151,6 +1156,7 @@ next_attr:;
        rs->sr_entry = &ent;
        rs->sr_attrs = op->ors_attrs;
        rs->sr_flags = 0;
+       rs->sr_err = LDAP_SUCCESS;
        rc = send_search_entry( op, rs );
        switch ( rc ) {
        case LDAP_UNAVAILABLE: