From f97dc983ac25cd6b8f78ba48c067621b53037afd Mon Sep 17 00:00:00 2001 From: Jong Hyuk Choi Date: Thu, 20 Nov 2003 02:14:47 +0000 Subject: [PATCH] Collective entryUUID transmission of PRESENT messages in a single PDU (refer to draft-zeilenga-ldup-sync-04.txt) --- servers/slapd/back-bdb/search.c | 81 ++++++++++++++++++++++++--------- servers/slapd/ldapsync.c | 32 ++++++++++++- servers/slapd/proto-slap.h | 2 + servers/slapd/sessionlog.c | 4 +- servers/slapd/slap.h | 1 + servers/slapd/syncrepl.c | 52 ++++++++++++--------- 6 files changed, 126 insertions(+), 46 deletions(-) diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index a3952cd652..f7eed19933 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -402,6 +402,9 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, const char *text; int slog_found = 0; + BerVarray syncUUID_set = NULL; + int syncUUID_set_cnt = 0; + #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "bdb_search\n", 0, 0, 0 ); #else @@ -1250,8 +1253,9 @@ id2entry_retry: result = send_search_entry( sop, rs ); if ( cookie.bv_val ) ch_free( cookie.bv_val ); - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); - ch_free( ctrls[--num_ctrls] ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, + sop->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); ctrls[num_ctrls] = NULL; rs->sr_ctrls = NULL; } @@ -1276,29 +1280,47 @@ id2entry_retry: } } else { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { - rs->sr_err = slap_build_sync_state_ctrl( sop, - rs, e, entry_sync_state, ctrls, - num_ctrls++, 0, NULL ); - - if ( rs->sr_err != LDAP_SUCCESS ) goto done; - rs->sr_ctrls = ctrls; if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */ + rs->sr_err = slap_build_sync_state_ctrl( sop, + rs, e, entry_sync_state, ctrls, + num_ctrls++, 0, NULL ); + if ( rs->sr_err != LDAP_SUCCESS ) goto done; + rs->sr_ctrls = ctrls; rs->sr_attrs = sop->oq_search.rs_attrs; result = send_search_entry( sop, rs ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, + sop->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); + ctrls[num_ctrls] = NULL; + rs->sr_ctrls = NULL; } else { /* PRESENT */ if ( sync_send_present_mode ) { - rs->sr_attrs = &null_attr; - result = send_search_entry( sop, rs ); + result = slap_build_syncUUID_set( sop, + &syncUUID_set, e ); + if ( result <= 0 ) { + result = -1; + } else { + syncUUID_set_cnt++; + if ( syncUUID_set_cnt == SLAP_SYNCUUID_SET_SIZE ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + result = slap_send_syncinfo( sop, rs, + LDAP_TAG_SYNC_ID_SET, + NULL, 0, syncUUID_set, 0 ); + if ( result != LDAP_SUCCESS ) + result = -1; + ber_bvarray_free_x( syncUUID_set, + sop->o_tmpmemctx ); + syncUUID_set = NULL; + syncUUID_set_cnt = 0; + } + } } else { result = 1; } } - - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); - ch_free( ctrls[--num_ctrls] ); - ctrls[num_ctrls] = NULL; - rs->sr_ctrls = NULL; } else { rs->sr_attrs = sop->oq_search.rs_attrs; rs->sr_ctrls = NULL; @@ -1349,13 +1371,19 @@ loop_continue: ldap_pvt_thread_yield(); } + if ( syncUUID_set_cnt > 0 ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + slap_send_syncinfo( sop, rs, LDAP_TAG_SYNC_ID_SET, + NULL, 0, syncUUID_set, 0 ); + ber_bvarray_free_x( syncUUID_set, sop->o_tmpmemctx ); + syncUUID_set_cnt = 0; + } + nochange: if (!IS_PSEARCH) { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { - rs->sr_err = LDAP_SUCCESS; - rs->sr_rspoid = LDAP_SYNC_INFO; - rs->sr_ctrls = NULL; - if ( sop->o_sync_mode & SLAP_SYNC_PERSIST ) { struct berval cookie; slap_compose_sync_cookie( sop, &cookie, @@ -1363,6 +1391,9 @@ nochange: sop->o_sync_state.sid ); if ( sync_send_present_mode ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; slap_send_syncinfo( sop, rs, LDAP_TAG_SYNC_REFRESH_PRESENT, &cookie, 1, NULL, 0 ); } else { @@ -1379,10 +1410,16 @@ nochange: } if ( slog_found ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = NULL; + rs->sr_ctrls = NULL; slap_send_session_log( op, ps_list, rs ); } ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex ); } + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; slap_send_syncinfo( sop, rs, LDAP_TAG_SYNC_REFRESH_DELETE, &cookie, 1, NULL, 0 ); } @@ -1427,11 +1464,12 @@ nochange: rs->sr_ctrls = ctrls; rs->sr_ref = rs->sr_v2ref; rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; + rs->sr_rspoid = NULL; send_ldap_result( sop, rs ); if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL ) { - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, sop->o_tmpmemctx ); } - ch_free( ctrls[--num_ctrls] ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); ctrls[num_ctrls] = NULL; if ( cookie.bv_val ) ch_free( cookie.bv_val ); @@ -1440,6 +1478,7 @@ nochange: rs->sr_ctrls = NULL; rs->sr_ref = rs->sr_v2ref; rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; + rs->sr_rspoid = NULL; send_ldap_result( sop, rs ); } } diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 9be438a13e..7d62ef860f 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -58,8 +58,9 @@ slap_build_sync_state_ctrl( struct berval entryuuid_bv = { 0, NULL }; ber_init2( ber, 0, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); - ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); + ctrls[num_ctrls] = sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx ); for ( a = e->e_attrs; a != NULL; a = a->a_next ) { AttributeDescription *desc = a->a_desc; @@ -117,6 +118,7 @@ slap_build_sync_done_ctrl( BerElement *ber = (BerElement *)&berbuf; ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); @@ -174,7 +176,8 @@ slap_build_sync_state_ctrl_from_slog( struct berval entryuuid_bv = { 0, NULL }; - ber_init2( ber, 0, LBER_USE_DER ); + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); @@ -231,6 +234,7 @@ slap_send_syncinfo( int ret; ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); if ( type ) { switch ( type ) { @@ -470,3 +474,27 @@ slap_dup_sync_cookie( return new; } + +int +slap_build_syncUUID_set( + Operation *op, + BerVarray *set, + Entry *e +) +{ + int ret; + Attribute* a; + + struct berval entryuuid_bv = { 0, NULL }; + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + AttributeDescription *desc = a->a_desc; + if ( desc == slap_schema.si_ad_entryUUID ) { + ber_dupbv_x( &entryuuid_bv, &a->a_nvals[0], op->o_tmpmemctx ); + } + } + + ret = ber_bvarray_add_x( set, &entryuuid_bv, op->o_tmpmemctx ); + + return ret; +} diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 7d5d27c152..f65144c3e2 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -601,6 +601,8 @@ LDAP_SLAPD_F (int) slap_init_sync_cookie_ctxcsn LDAP_P(( struct sync_cookie * )); LDAP_SLAPD_F (struct sync_cookie *) slap_dup_sync_cookie LDAP_P(( struct sync_cookie *, struct sync_cookie * )); +LDAP_SLAPD_F (int) slap_build_syncUUID_set LDAP_P(( + Operation *, BerVarray *, Entry * )); /* * limits.c diff --git a/servers/slapd/sessionlog.c b/servers/slapd/sessionlog.c index 30d52a09f1..3e4c30987d 100644 --- a/servers/slapd/sessionlog.c +++ b/servers/slapd/sessionlog.c @@ -96,8 +96,8 @@ slap_send_session_log( rs->sr_attrs = uuid_attr; rs->sr_ctrls = ctrls; result = send_search_entry( op, rs ); - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); - ch_free( ctrls[--num_ctrls] ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, op->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], op->o_tmpmemctx ); ctrls[num_ctrls] = NULL; rs->sr_ctrls = NULL; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 9a43d20ce3..4185bba5fc 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1292,6 +1292,7 @@ typedef BackendDB Backend; */ #define SLAP_SYNC_SID_SIZE 3 +#define SLAP_SYNCUUID_SET_SIZE 256 struct nonpresent_entry { struct berval *npe_name; diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index abeed6ca53..ef28f922cd 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -50,10 +50,9 @@ static const struct berval slap_syncrepl_bvc = BER_BVC(SYNCREPL_STR); static const struct berval slap_syncrepl_cn_bvc = BER_BVC(CN_STR SYNCREPL_STR); +static int syncuuid_cmp( const void *, const void * ); static void avl_ber_bvfree( void * ); - -static void -syncrepl_del_nonpresent( Operation *, syncinfo_t * ); +static void syncrepl_del_nonpresent( Operation *, syncinfo_t * ); /* callback functions */ static int dn_callback( struct slap_op *, struct slap_rep * ); @@ -425,8 +424,7 @@ do_syncrep2( struct sync_cookie syncCookie_req = { NULL, -1, NULL }; struct berval cookie = { 0, NULL }; - int rc; - int err; + int rc, err, i; ber_len_t len; slap_callback cb; @@ -444,7 +442,7 @@ do_syncrep2( int refreshDeletes = 0; int refreshDone = 1; - BerVarray syncUUIDs; + BerVarray syncUUIDs = NULL; ber_tag_t si_tag; if ( slapd_abrupt_shutdown ) { @@ -452,6 +450,9 @@ do_syncrep2( goto done; } + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "do_syncrep2\n", 0, 0, 0 ); #else @@ -626,15 +627,15 @@ do_syncrep2( ber_scanf( ber, "}" ); break; case LDAP_TAG_SYNC_ID_SET: - /* FIXME : to be supported */ ber_scanf( ber, "t{", &tag ); - if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) - { + if ( ber_peek_tag( ber, &len ) == + LDAP_TAG_SYNC_COOKIE ) { ber_scanf( ber, "m", &cookie ); if ( cookie.bv_val ) { struct berval tmp_bv; ber_dupbv( &tmp_bv, &cookie ); - ber_bvarray_add( &syncCookie.octet_str, &tmp_bv); + ber_bvarray_add( &syncCookie.octet_str, + &tmp_bv ); } if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) @@ -647,6 +648,14 @@ do_syncrep2( } ber_scanf( ber, "[W]", &syncUUIDs ); ber_scanf( ber, "}" ); + for ( i = 0; syncUUIDs[i].bv_val; i++ ) { + struct berval *syncuuid_bv; + syncuuid_bv = ber_dupbv( NULL, &syncUUIDs[i] ); + avl_insert( &si->si_presentlist, + (caddr_t) syncuuid_bv, + syncuuid_cmp, avl_dup_error ); + } + ber_memfree_x( syncUUIDs, op->o_tmpmemctx ); break; default: #ifdef NEW_LOGGING @@ -939,7 +948,8 @@ syncrepl_message_to_entry( sl_free( ndn.bv_val, op->o_tmpmemctx ); sl_free( dn.bv_val, op->o_tmpmemctx ); - if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) { + if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) + { return NULL; } @@ -1011,16 +1021,6 @@ done: return e; } -int -syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) -{ - const struct berval *uuid1 = v_uuid1; - const struct berval *uuid2 = v_uuid2; - int rc = uuid1->bv_len - uuid2->bv_len; - if ( rc ) return rc; - return ( strcmp( uuid1->bv_val, uuid2->bv_val ) ); -} - int syncrepl_entry( syncinfo_t* si, @@ -1822,6 +1822,16 @@ slap_uuidstr_from_normalized( return new; } +static int +syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) +{ + const struct berval *uuid1 = v_uuid1; + const struct berval *uuid2 = v_uuid2; + int rc = uuid1->bv_len - uuid2->bv_len; + if ( rc ) return rc; + return ( strcmp( uuid1->bv_val, uuid2->bv_val ) ); +} + static void avl_ber_bvfree( void *bv ) { -- 2.39.5