--- servers/slapd/overlays/syncprov.c 2008/03/12 21:31:28 1.219 +++ servers/slapd/overlays/syncprov.c 2008/03/20 23:09:24 1.224 @@ -1,4 +1,4 @@ -/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.218 2008/03/08 22:51:07 hyc Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/syncprov.c,v 1.223 2008/03/19 23:31:42 hyc Exp $ */ /* syncprov.c - syncrepl provider */ /* This work is part of OpenLDAP Software . * @@ -696,7 +696,10 @@ again: break; } - fop.o_bd->bd_info = on->on_info->oi_orig; + if ( on->on_next ) + fop.o_bd->bd_info = (BackendInfo *)on->on_next; + else + fop.o_bd->bd_info = on->on_info->oi_orig; fop.o_bd->be_search( &fop, &frs ); fop.o_bd->bd_info = (BackendInfo *)on; @@ -840,7 +843,7 @@ static int syncprov_qplay( Operation *op, struct re_s *rtask ) { syncops *so = rtask->arg; - slap_overinst *on = so->s_op->o_private; + slap_overinst *on = LDAP_SLIST_FIRST(&so->s_op->o_extra)->oe_key; syncres *sr; Entry *e; opcookie opc; @@ -933,7 +936,7 @@ syncprov_qtask( void *ctx, void *arg ) be = *so->s_op->o_bd; be.be_flags |= SLAP_DBFLAG_OVERLAY; op->o_bd = &be; - op->o_private = NULL; + LDAP_SLIST_FIRST(&op->o_extra) = NULL; op->o_callback = NULL; rc = syncprov_qplay( op, rtask ); @@ -1306,6 +1309,7 @@ syncprov_checkpoint( Operation *op, Slap Operation opm; SlapReply rsm = { 0 }; slap_callback cb = {0}; + BackendDB be; mod.sml_numvals = si->si_numcsns; mod.sml_values = si->si_ctxcsn; @@ -1321,8 +1325,12 @@ syncprov_checkpoint( Operation *op, Slap opm.o_callback = &cb; opm.orm_modlist = &mod; opm.orm_no_opattrs = 1; - opm.o_req_dn = op->o_bd->be_suffix[0]; - opm.o_req_ndn = op->o_bd->be_nsuffix[0]; + if ( SLAP_GLUE_SUBORDINATE( op->o_bd )) { + be = *on->on_info->oi_origdb; + opm.o_bd = &be; + } + opm.o_req_dn = opm.o_bd->be_suffix[0]; + opm.o_req_ndn = opm.o_bd->be_nsuffix[0]; opm.o_bd->bd_info = on->on_info->oi_orig; opm.o_managedsait = SLAP_CONTROL_NONCRITICAL; opm.o_no_schema_check = 1; @@ -1330,7 +1338,6 @@ syncprov_checkpoint( Operation *op, Slap if ( mod.sml_next != NULL ) { slap_mods_free( mod.sml_next, 1 ); } - opm.orm_no_opattrs = 0; } static void @@ -1524,7 +1531,10 @@ syncprov_playlog( Operation *op, SlapRep fop.ors_filter = ⁡ cb.sc_response = playlog_cb; - fop.o_bd->bd_info = on->on_info->oi_orig; + if ( on->on_next ) + fop.o_bd->bd_info = (BackendInfo *)on->on_next; + else + fop.o_bd->bd_info = on->on_info->oi_orig; for ( i=ndel; isr_state.rid, - srs->sr_state.sid ); + if ( delcsn[0].bv_len ) { + slap_compose_sync_cookie( op, &cookie, delcsn, srs->sr_state.rid, + srs->sr_state.sid ); + } Debug( LDAP_DEBUG_SYNC, "syncprov_playlog: cookie=%s\n", cookie.bv_val, 0, 0 ); uuids[ndel].bv_val = NULL; - syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 ); + syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, + delcsn[0].bv_len ? &cookie : NULL, 0, uuids, 1 ); op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx ); } op->o_tmpfree( uuids, op->o_tmpmemctx ); @@ -1854,6 +1867,7 @@ syncprov_search_cleanup( Operation *op, typedef struct SyncOperationBuffer { Operation sob_op; Opheader sob_hdr; + OpExtra sob_oe; AttributeName sob_extra; /* not always present */ /* Further data allocated here */ } SyncOperationBuffer; @@ -1882,6 +1896,7 @@ syncprov_detach_op( Operation *op, synco sopbuf2 = ch_calloc( 1, size ); op2 = &sopbuf2->sob_op; op2->o_hdr = &sopbuf2->sob_hdr; + LDAP_SLIST_FIRST(&op2->o_extra) = &sopbuf2->sob_oe; /* Copy the fields we care about explicitly, leave the rest alone */ *op2->o_hdr = *op->o_hdr; @@ -1889,7 +1904,8 @@ syncprov_detach_op( Operation *op, synco op2->o_time = op->o_time; op2->o_bd = on->on_info->oi_origdb; op2->o_request = op->o_request; - op2->o_private = on; + LDAP_SLIST_FIRST(&op2->o_extra)->oe_key = on; + LDAP_SLIST_NEXT(LDAP_SLIST_FIRST(&op2->o_extra), oe_next) = NULL; ptr = (char *) sopbuf2 + offsetof( SyncOperationBuffer, sob_extra ); if ( i ) { @@ -1940,12 +1956,10 @@ syncprov_detach_op( Operation *op, synco op2->o_do_not_cache = 1; /* Add op2 to conn so abandon will find us */ - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); op->o_conn->c_n_ops_executing++; op->o_conn->c_n_ops_completed--; LDAP_STAILQ_INSERT_TAIL( &op->o_conn->c_ops, op2, o_next ); so->s_flags |= PS_IS_DETACHED; - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); /* Prevent anyone else from trying to send a result for this op */ op->o_abandon = 1; @@ -2055,15 +2069,27 @@ syncprov_search_response( Operation *op, /* Detach this Op from frontend control */ ldap_pvt_thread_mutex_lock( &ss->ss_so->s_mutex ); + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - /* Turn off the refreshing flag */ - ss->ss_so->s_flags ^= PS_IS_REFRESHING; + /* But not if this connection was closed along the way */ + if ( op->o_abandon ) { + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + ldap_pvt_thread_mutex_unlock( &ss->ss_so->s_mutex ); + syncprov_free_syncop( ss->ss_so ); + return SLAPD_ABANDON; - syncprov_detach_op( op, ss->ss_so, on ); + } else { + /* Turn off the refreshing flag */ + ss->ss_so->s_flags ^= PS_IS_REFRESHING; + + syncprov_detach_op( op, ss->ss_so, on ); - /* If there are queued responses, fire them off */ - if ( ss->ss_so->s_res ) - syncprov_qstart( ss->ss_so ); + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + + /* If there are queued responses, fire them off */ + if ( ss->ss_so->s_res ) + syncprov_qstart( ss->ss_so ); + } ldap_pvt_thread_mutex_unlock( &ss->ss_so->s_mutex ); return LDAP_SUCCESS;