X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsyncrepl.c;h=b12ecd2cb6ff869b8fa77b20558b3ef373ea903b;hb=9184d038ead9aeabff5b7c0bb2ed0d1e6bc95c8c;hp=6dd40777f5d6295b9c7dc2a670856d0e3f3961c3;hpb=45776bff04651074655474c0615f790dc1af35d3;p=openldap diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 6dd40777f5..b12ecd2cb6 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -69,6 +69,7 @@ slap_mods2entry_syncrepl( Modifications *, Entry **, int, /* callback functions */ static int cookie_callback( struct slap_op *, struct slap_rep * ); +static int dn_callback( struct slap_op *, struct slap_rep * ); static int nonpresent_callback( struct slap_op *, struct slap_rep * ); static int null_callback( struct slap_op *, struct slap_rep * ); @@ -118,7 +119,8 @@ do_syncrepl( void *ctx, void *arg ) { - Backend *be = arg; + struct re_s* rtask = arg; + Backend *be = rtask->arg; syncinfo_t *si = ( syncinfo_t * ) be->syncinfo; SlapReply rs = {REP_RESULT}; @@ -498,7 +500,7 @@ do_syncrepl( entry_free( entry ); for ( ml = modlist; ml != NULL; ml = mlnext ) { mlnext = ml->sml_next; - free( ml ); + ber_memfree( ml ); } break; @@ -634,7 +636,6 @@ do_syncrepl( Debug( LDAP_DEBUG_ANY, "do_syncrepl : unknown result\n", 0, 0, 0 ); #endif - return NULL; } done: @@ -646,6 +647,16 @@ done: if ( res ) ldap_msgfree( res ); ldap_unbind( ld ); + + ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); + ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask ); + if ( si->type == LDAP_SYNC_REFRESH_ONLY ) { + ldap_pvt_runqueue_resched( &syncrepl_rq, rtask ); + } else { + ldap_pvt_runqueue_remove( &syncrepl_rq, rtask ); + } + ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); + return NULL; } @@ -688,6 +699,8 @@ syncrepl_message_to_entry( LDAPControl** rctrls = NULL; BerElement* ctrl_ber; + ber_tag_t tag; + *modlist = NULL; if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) { @@ -721,10 +734,10 @@ syncrepl_message_to_entry( e->e_attrs = NULL; - for ( rc = ldap_get_attribute_ber( ld, msg, ber, &tmp.sml_type, &tmp.sml_bvalues); - rc == LDAP_SUCCESS; - rc = ldap_get_attribute_ber( ld, msg, ber, &tmp.sml_type, &tmp.sml_bvalues)) - { + while ( ber_remaining( ber ) ) { + tag = ber_scanf( ber, "{mW}", &tmp.sml_type, &tmp.sml_values ); + + if ( tag == LBER_ERROR ) break; if ( tmp.sml_type.bv_val == NULL ) break; mod = (Modifications *) ch_malloc( sizeof( Modifications )); @@ -851,7 +864,7 @@ done: return e; } -int +int syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) { const struct berval *uuid1 = v_uuid1; @@ -881,13 +894,12 @@ syncrepl_entry( char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; SlapReply rs = {REP_RESULT}; - int rc; + int rc = LDAP_SUCCESS; + + struct berval base_bv = {0, NULL}; -#if 0 /* FIXME : UUID search required first */ char *filterstr; - struct berval filterstr_bv; Filter *filter; -#endif Attribute *a; @@ -909,74 +921,103 @@ syncrepl_entry( attr_merge_one( e, slap_schema.si_ad_entryUUID, syncUUID, syncUUID ); } -#if 0 /* FIXME : UUID search required first */ filterstr = (char *) sl_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1, op->o_tmpmemctx ); strcpy( filterstr, "entryUUID=" ); strcat( filterstr, syncUUID->bv_val ); -#endif si->e = e; si->syncUUID = syncUUID; + si->syncUUID_ndn = NULL; -#if 0 /* FIXME : UUID search required first */ filter = str2filter( filterstr ); - ber_str2bv( filterstr, strlen(filterstr), 1, &filterstr_bv ); + ber_str2bv( filterstr, strlen(filterstr), 1, &op->ors_filterstr ); ch_free( filterstr ); -#endif + op->ors_filter = filter; + op->ors_scope = LDAP_SCOPE_SUBTREE; - op->o_req_dn = e->e_name; - op->o_req_ndn = e->e_nname; + /* get syncrepl cookie of shadow replica from subentry */ + ber_str2bv( si->base, strlen(si->base), 1, &base_bv ); + dnPrettyNormal( 0, &base_bv, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); + ch_free( base_bv.bv_val ); + /* set callback function */ op->o_callback = &cb; - cb.sc_response = null_callback; + cb.sc_response = dn_callback; cb.sc_private = si; + be->be_search( op, &rs ); + + ch_free( op->o_req_dn.bv_val ); + ch_free( op->o_req_ndn.bv_val ); + filter_free( op->ors_filter ); + ch_free( op->ors_filterstr.bv_val ); + + cb.sc_response = null_callback; + + if ( si->syncUUID_ndn ) + printf("syncUUID_ndn = %s\n", si->syncUUID_ndn ); + switch ( syncstate ) { case LDAP_SYNC_ADD : case LDAP_SYNC_MODIFY : -sync_add_retry: - op->o_tag = LDAP_REQ_MODIFY; - op->orm_modlist = modlist; - rc = be->be_modify( op, &rs ); - if ( rc != LDAP_SUCCESS ) { - if ( rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT || - rc == DB_NOTFOUND ) { - op->o_tag = LDAP_REQ_ADD; - op->ora_e = e; - rc = be->be_add( op, &rs ); - if ( rc != LDAP_SUCCESS ) { - if ( rc == LDAP_ALREADY_EXISTS ) { - goto sync_add_retry; - } else if ( rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT || - rc == DB_NOTFOUND ) { - syncrepl_add_glue(ld, op, e, - modlist, syncstate, - syncUUID, syncCookie); - } else { + + rc = LDAP_SUCCESS; + + if ( si->syncUUID_ndn ) { + op->o_req_dn = *si->syncUUID_ndn; + op->o_req_ndn = *si->syncUUID_ndn; + op->o_tag = LDAP_REQ_DELETE; + rc = be->be_delete( op, &rs ); + } + + if ( rc == LDAP_SUCCESS || + rc == LDAP_REFERRAL || + rc == LDAP_NO_SUCH_OBJECT || + rc == DB_NOTFOUND ) { + op->o_tag = LDAP_REQ_ADD; + op->ora_e = e; + op->o_req_dn = e->e_name; + op->o_req_ndn = e->e_nname; + rc = be->be_add( op, &rs ); + if ( rc != LDAP_SUCCESS ) { + if ( rc == LDAP_ALREADY_EXISTS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "be_add failed (%d)\n", - rc, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "be_add failed : already exists (%d)\n", + rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "be_add failed (%d)\n", - rc, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "be_add failed : already exists (%d)\n", + rc, 0, 0 ); #endif - } + } else if ( rc == LDAP_REFERRAL || + rc == LDAP_NO_SUCH_OBJECT || + rc == DB_NOTFOUND ) { + syncrepl_add_glue(ld, op, e, + modlist, syncstate, + syncUUID, syncCookie); } else { - return 0; +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, + "be_add failed (%d)\n", + rc, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "be_add failed (%d)\n", + rc, 0, 0 ); +#endif } } else { + return 0; + } + } else { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "be_modify failed (%d)\n", rc, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "be_modify/be_delete failed (%d)\n", rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "be_modify failed (%d)\n", rc, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "be_modify/be_delete failed (%d)\n", rc, 0, 0 ); #endif - } } si->e = NULL; @@ -1906,6 +1947,21 @@ cookie_callback( return LDAP_SUCCESS; } +static int +dn_callback( + Operation* op, + SlapReply* rs +) +{ + syncinfo_t *si = op->o_callback->sc_private; + + if ( rs->sr_type == REP_SEARCH ) { + si->syncUUID_ndn = &rs->sr_entry->e_nname; + } + + return LDAP_SUCCESS; +} + static int nonpresent_callback( Operation* op, @@ -1972,4 +2028,44 @@ null_callback( return LDAP_SUCCESS; } + +char ** +str2clist( char **out, char *in, const char *brkstr ) +{ + char *str; + char *s; + char *lasts; + int i, j; + const char *text; + char **new; + + /* find last element in list */ + for (i = 0; out && out[i]; i++); + + /* protect the input string from strtok */ + str = ch_strdup( in ); + + /* Count words in string */ + j=1; + for ( s = str; *s; s++ ) { + if ( strchr( brkstr, *s ) != NULL ) { + j++; + } + } + + out = ch_realloc( out, ( i + j + 1 ) * sizeof( char * ) ); + new = out + i; + for ( s = ldap_pvt_strtok( str, brkstr, &lasts ); + s != NULL; + s = ldap_pvt_strtok( NULL, brkstr, &lasts ) ) + { + *new = ch_strdup( s ); + new++; + } + + *new = NULL; + free( str ); + return( out ); +} + #endif