X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsyncrepl.c;h=07e9dd78577fb08c33b472ac2a67a339204a7b06;hb=861441fcf7661e6a13dfe236537dd318a58492d1;hp=e7daf54db5cf8a4738bcc8eb45636a54661928e1;hpb=d44a75ff401146a1b64e6c3643f4b38ab7081420;p=openldap diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index e7daf54db5..07e9dd7857 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1256,7 +1256,7 @@ do_syncrepl( int rc = LDAP_SUCCESS; int dostop = 0; ber_socket_t s; - int i, defer = 1, fail = 0; + int i, defer = 1, fail = 0, freeinfo = 0; Backend *be; if ( si == NULL ) @@ -1274,8 +1274,9 @@ do_syncrepl( ldap_pvt_thread_yield(); } - if ( !si->si_ctype ) + if ( si->si_ctype < 1 ) { goto deleted; + } switch( abs( si->si_type ) ) { case LDAP_SYNC_REFRESH_ONLY: @@ -1302,10 +1303,6 @@ do_syncrepl( connection_fake_init( &conn, &opbuf, ctx ); op = &opbuf.ob_op; - /* use global malloc for now */ - op->o_tmpmemctx = NULL; - op->o_tmpmfuncs = &ch_mfuncs; - op->o_managedsait = SLAP_CONTROL_NONCRITICAL; be = si->si_be; @@ -1366,7 +1363,11 @@ reload: deleted: /* We got deleted while running on cn=config */ - if ( !si->si_ctype ) { + if ( si->si_ctype < 1 ) { + if ( si->si_ctype == -1 ) { + si->si_ctype = 0; + freeinfo = 1; + } if ( si->si_conn ) dostop = 1; rc = -1; @@ -1433,7 +1434,7 @@ deleted: break; } - if ( !si->si_ctype + if ( si->si_ctype < 1 || !si->si_retrynum || si->si_retrynum[i] == RETRYNUM_TAIL ) { if ( si->si_re ) { ldap_pvt_runqueue_remove( &slapd_rq, rtask ); @@ -1470,7 +1471,7 @@ deleted: } /* Do final delete cleanup */ - if ( !si->si_ctype ) { + if ( freeinfo ) { syncinfo_free( si, 0 ); } return NULL; @@ -1626,7 +1627,16 @@ syncrepl_message_to_op( if ( !ber_bvstrcasecmp( &bv, &ls->ls_dn ) ) { bdn = bvals[0]; - dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx ); + rc = dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx ); + if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "syncrepl_message_to_op: %s " + "dn \"%s\" normalization failed (%d)", + si->si_ridtxt, bdn.bv_val, rc ); + rc = -1; + ch_free( bvals ); + goto done; + } ber_dupbv( &op->o_req_dn, &dn ); ber_dupbv( &op->o_req_ndn, &ndn ); slap_sl_free( ndn.bv_val, op->o_tmpmemctx ); @@ -1858,7 +1868,21 @@ syncrepl_message_to_entry( return -1; } - dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx ); + rc = dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx ); + if ( rc != LDAP_SUCCESS ) { + /* One of the things that could happen is that the schema + * is not lined-up; this could result in unknown attributes. + * A value non conformant to the syntax should be unlikely, + * except when replicating between different versions + * of the software, or when syntax validation bugs are fixed + */ + Debug( LDAP_DEBUG_ANY, + "syncrepl_message_to_entry: " + "%s dn \"%s\" normalization failed (%d)", + si->si_ridtxt, bdn.bv_val, rc ); + return rc; + } + ber_dupbv( &op->o_req_dn, &dn ); ber_dupbv( &op->o_req_ndn, &ndn ); slap_sl_free( ndn.bv_val, op->o_tmpmemctx ); @@ -3607,8 +3631,6 @@ syncinfo_free( syncinfo_t *sie, int free_all ) do { si_next = sie->si_next; - sie->si_re = NULL; - if ( sie->si_ld ) { if ( sie->si_conn ) { connection_client_stop( sie->si_conn ); @@ -4383,7 +4405,7 @@ add_syncrepl( si->si_cookieState = c->be->be_syncinfo->si_cookieState; - // add new syncrepl to end of list (same order as when deleting) + /* add new syncrepl to end of list (same order as when deleting) */ for ( sip = c->be->be_syncinfo; sip->si_next; sip = sip->si_next ); sip->si_next = si; } else { @@ -4607,29 +4629,21 @@ syncrepl_config( ConfigArgs *c ) if ( si->si_re ) { if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) { isrunning = 1; - } else if ( si->si_conn ) { - isrunning = 1; - /* If there's a persistent connection, we don't - * know if it's already got a thread queued. - * so defer the free, but reschedule the task. - * If there's a connection thread queued, it - * will cleanup as necessary. If not, then the - * runqueue task will cleanup. - */ - ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); - if ( !ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re )) { - si->si_re->interval.tv_sec = 0; - ldap_pvt_runqueue_resched( &slapd_rq, si->si_re, 0 ); - si->si_re->interval.tv_sec = si->si_interval; - } - ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); - } else { + if ( si->si_conn ) { + /* If there's a persistent connection, it may + * already have a thread queued. We know it's + * not active, so it must be pending and we + * can simply cancel it now. + */ + ldap_pvt_thread_pool_retract( &connection_pool, + si->si_re->routine, si->si_re ); + } ldap_pvt_thread_mutex_unlock( &si->si_mutex ); } } if ( isrunning ) { - si->si_ctype = 0; + si->si_ctype = -1; si->si_next = NULL; } else { syncinfo_free( si, 0 );