From 1e859528438857aebb31efef4cb983b65719ef08 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 11 Nov 2009 03:06:32 +0000 Subject: [PATCH] ITS#6373 add sync_use_subentry keyword --- servers/slapd/bconfig.c | 18 +++++++++++++++++- servers/slapd/slap.h | 2 ++ servers/slapd/syncrepl.c | 35 +++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 8d5ca2a6fb..0fbb9e22da 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -190,6 +190,7 @@ enum { CFG_IX_INTLEN, CFG_SYNTAX, CFG_ACL_ADD, + CFG_SYNC_SUBENTRY, CFG_LAST }; @@ -604,6 +605,10 @@ static ConfigTable config_back_cf_table[] = { &config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' " "EQUALITY distinguishedNameMatch " "SYNTAX OMsDN )", NULL, NULL }, + { "sync_use_subentry", NULL, 0, 0, 0, ARG_ON_OFF|ARG_DB|ARG_MAGIC, + &config_generic, "( OLcfgDbAt:0.19 NAME 'olcSyncUseSubentry' " + "DESC 'Store sync context in a subentry' " + "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, { "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC, &syncrepl_config, "( OLcfgDbAt:0.11 NAME 'olcSyncrepl' " "EQUALITY caseIgnoreMatch " @@ -815,7 +820,7 @@ static ConfigOCs cf_ocs[] = { "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ " "olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ " "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ " - "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncrepl $ " + "olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ " "olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ " "olcMonitoring ) )", Cft_Database, NULL, cfAddDatabase }, @@ -1085,6 +1090,9 @@ config_generic(ConfigArgs *c) { case CFG_LASTMOD: c->value_int = (SLAP_NOLASTMOD(c->be) == 0); break; + case CFG_SYNC_SUBENTRY: + c->value_int = (SLAP_SYNC_SUBENTRY(c->be) != 0); + break; case CFG_MIRRORMODE: if ( SLAP_SHADOW(c->be)) c->value_int = (SLAP_SINGLE_SHADOW(c->be) == 0); @@ -1197,6 +1205,7 @@ config_generic(ConfigArgs *c) { case CFG_SSTR_IF_MAX: case CFG_SSTR_IF_MIN: case CFG_ACL_ADD: + case CFG_SYNC_SUBENTRY: break; /* no-ops, requires slapd restart */ @@ -1901,6 +1910,13 @@ sortval_reject: SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_HIDDEN; break; + case CFG_SYNC_SUBENTRY: + if (c->value_int) + SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_SYNC_SUBENTRY; + else + SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_SYNC_SUBENTRY; + break; + case CFG_SSTR_IF_MAX: if (c->value_uint < index_substr_if_minlen) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> invalid value", c->argv[0] ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 18e11a6e58..ef9c40f7b9 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1804,6 +1804,7 @@ struct BackendDB { #define SLAP_DBFLAG_SHADOW_MASK (SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SINGLE_SHADOW|SLAP_DBFLAG_SYNC_SHADOW|SLAP_DBFLAG_SLURP_SHADOW) #define SLAP_DBFLAG_CLEAN 0x10000U /* was cleanly shutdown */ #define SLAP_DBFLAG_ACL_ADD 0x20000U /* check attr ACLs on adds */ +#define SLAP_DBFLAG_SYNC_SUBENTRY 0x40000U /* use subentry for context */ slap_mask_t be_flags; #define SLAP_DBFLAGS(be) ((be)->be_flags) #define SLAP_NOLASTMOD(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_NOLASTMOD) @@ -1830,6 +1831,7 @@ struct BackendDB { #define SLAP_MULTIMASTER(be) (!SLAP_SINGLE_SHADOW(be)) #define SLAP_DBCLEAN(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_CLEAN) #define SLAP_DBACL_ADD(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_ACL_ADD) +#define SLAP_SYNC_SUBENTRY(be) (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SYNC_SUBENTRY) slap_mask_t be_restrictops; /* restriction operations */ #define SLAP_RESTRICT_OP_ADD 0x0001U diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 22496b66b3..b6dacb0122 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -70,6 +70,7 @@ typedef struct syncinfo_s { struct berval si_logbase; struct berval si_filterstr; struct berval si_logfilterstr; + struct berval si_contextdn; int si_scope; int si_attrsonly; char *si_anfile; @@ -119,7 +120,7 @@ static int syncrepl_entry( Modifications**,int, struct berval*, struct berval *cookieCSN ); static int syncrepl_updateCookie( - syncinfo_t *, Operation *, struct berval *, + syncinfo_t *, Operation *, struct sync_cookie * ); static struct berval * slap_uuidstr_from_normalized( struct berval *, struct berval *, void * ); @@ -164,6 +165,13 @@ init_syncrepl(syncinfo_t *si) sync_descs[3] = NULL; } + if ( SLAP_SYNC_SUBENTRY( si->si_be )) { + build_new_dn( &si->si_contextdn, &si->si_be->be_nsuffix[0], + (struct berval *)&slap_ldapsync_cn_bv, NULL ); + } else { + si->si_contextdn = si->si_be->be_nsuffix[0]; + } + if ( si->si_allattrs && si->si_allopattrs ) attrs = NULL; else @@ -458,8 +466,8 @@ check_syncprov( */ a.a_desc = slap_schema.si_ad_contextCSN; e.e_attrs = &a; - e.e_name = op->o_bd->be_suffix[0]; - e.e_nname = op->o_bd->be_nsuffix[0]; + e.e_name = si->si_contextdn; + e.e_nname = si->si_contextdn; at[0].an_name = a.a_desc->ad_cname; at[0].an_desc = a.a_desc; BER_BVZERO( &at[1].an_name ); @@ -627,7 +635,7 @@ do_syncrep1( BerVarray csn = NULL; void *ctx = op->o_tmpmemctx; - op->o_req_ndn = op->o_bd->be_nsuffix[0]; + op->o_req_ndn = si->si_contextdn; op->o_req_dn = op->o_req_ndn; /* try to read stored contextCSN */ @@ -753,7 +761,6 @@ do_syncrep2( err = LDAP_SUCCESS; ber_len_t len; - struct berval *psub; Modifications *modlist = NULL; int match, m; @@ -775,8 +782,6 @@ do_syncrep2( Debug( LDAP_DEBUG_TRACE, "=>do_syncrep2 %s\n", si->si_ridtxt, 0, 0 ); - psub = &si->si_be->be_nsuffix[0]; - slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie ); if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) { @@ -873,7 +878,7 @@ do_syncrep2( if ( ( rc = syncrepl_message_to_op( si, op, msg ) ) == LDAP_SUCCESS && syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, psub, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie ); } else switch ( rc ) { case LDAP_ALREADY_EXISTS: case LDAP_NO_SUCH_OBJECT: @@ -893,7 +898,7 @@ do_syncrep2( syncstate, &syncUUID, syncCookie.ctxcsn ) ) == LDAP_SUCCESS && syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, psub, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie ); } } ldap_controls_free( rctrls ); @@ -1013,7 +1018,7 @@ do_syncrep2( } if ( syncCookie.ctxcsn && match < 0 && err == LDAP_SUCCESS ) { - rc = syncrepl_updateCookie( si, op, psub, &syncCookie ); + rc = syncrepl_updateCookie( si, op, &syncCookie ); } if ( err == LDAP_SUCCESS && si->si_logstate == SYNCLOG_FALLBACK ) { @@ -1174,7 +1179,7 @@ do_syncrep2( if ( syncCookie.ctxcsn ) { - rc = syncrepl_updateCookie( si, op, psub, &syncCookie); + rc = syncrepl_updateCookie( si, op, &syncCookie); } } @@ -2957,7 +2962,6 @@ static int syncrepl_updateCookie( syncinfo_t *si, Operation *op, - struct berval *pdn, struct sync_cookie *syncCookie ) { Backend *be = op->o_bd; @@ -3048,8 +3052,8 @@ syncrepl_updateCookie( cb.sc_private = si; op->o_callback = &cb; - op->o_req_dn = op->o_bd->be_suffix[0]; - op->o_req_ndn = op->o_bd->be_nsuffix[0]; + op->o_req_dn = si->si_contextdn; + op->o_req_ndn = si->si_contextdn; /* update contextCSN */ op->o_dont_replicate = 1; @@ -3695,6 +3699,9 @@ syncinfo_free( syncinfo_t *sie, int free_all ) if ( sie->si_logbase.bv_val ) { ch_free( sie->si_logbase.bv_val ); } + if ( SLAP_SYNC_SUBENTRY( sie->si_be )) { + ch_free( sie->si_contextdn.bv_val ); + } if ( sie->si_attrs ) { int i = 0; while ( sie->si_attrs[i] != NULL ) {