From 5b209bdfc9824f59e08a0b11825bb5c6f6fcd15f Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Tue, 20 Nov 2007 20:11:27 +0000 Subject: [PATCH] ITS#5238 --- CHANGES | 1 + servers/slapd/bconfig.c | 12 +- servers/slapd/connection.c | 1 + servers/slapd/syncrepl.c | 1 + tests/scripts/defines.sh | 2 + tests/scripts/test050-syncrepl-multimaster | 178 ++++++++++++++++++++- 6 files changed, 190 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index e38d4d45c8..95c3c1cde4 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ OpenLDAP 2.4.7 Engineering Fixed slapd paged results handling when using rootdn (ITS#5230) Fixed slapd syncrepl presentlist handling (ITS#5231) Fixed slapd core schema 'c' definition for RFC4519 (ITS#5236) + Fixed slapd 3-way Multi-Master Replication (ITS#5238) Fixed slapd-bdb to report and fail on internal errors (ITS#5232) Fixed slapo-pcache op->o_abandon handling (ITS#5187) Fixed slapo-ppolicy single password check on modify (ITS#5146) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 4564a6f503..7aa86fbbad 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -4909,6 +4909,7 @@ config_back_modify( Operation *op, SlapReply *rs ) struct berval rdn; char *ptr; AttributeDescription *rad = NULL; + int do_pause = 1; cfb = (CfBackInfo *)op->o_bd->be_private; @@ -4939,11 +4940,17 @@ config_back_modify( Operation *op, SlapReply *rs ) rs->sr_text = "Use modrdn to change the entry name"; goto out; } + /* Internal update of contextCSN? */ + if ( ml->sml_desc == slap_schema.si_ad_contextCSN && op->o_conn->c_conn_idx == -1 ) { + do_pause = 0; + break; + } } slap_mods_opattrs( op, &op->orm_modlist, 1 ); - ldap_pvt_thread_pool_pause( &connection_pool ); + if ( do_pause ) + ldap_pvt_thread_pool_pause( &connection_pool ); /* Strategy: * 1) perform the Modify on the cached Entry. @@ -4975,7 +4982,8 @@ config_back_modify( Operation *op, SlapReply *rs ) op->o_ndn = ndn; } - ldap_pvt_thread_pool_resume( &connection_pool ); + if ( do_pause ) + ldap_pvt_thread_pool_resume( &connection_pool ); out: send_ldap_result( op, rs ); slap_graduate_commit_csn( op ); diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index c2e5a74318..1b8f87381f 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -1257,6 +1257,7 @@ void connection_client_stop( c->c_listener = NULL; c->c_conn_state = SLAP_C_INVALID; c->c_struct_state = SLAP_C_UNUSED; + c->c_sd = AC_SOCKET_INVALID; c->c_close_reason = "?"; /* should never be needed */ sb = c->c_sb; c->c_sb = ber_sockbuf_alloc( ); diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 085e59f12d..951fb34099 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -522,6 +522,7 @@ do_syncrep1( if ( ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn, si->si_cookieState->cs_vals, NULL )) { rc = LDAP_NO_MEMORY; + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); goto done; } si->si_syncCookie.numcsns = si->si_cookieState->cs_num; diff --git a/tests/scripts/defines.sh b/tests/scripts/defines.sh index e2e611554d..7bfd2e6503 100755 --- a/tests/scripts/defines.sh +++ b/tests/scripts/defines.sh @@ -291,7 +291,9 @@ SERVER6FLT=$TESTDIR/server6.flt MASTEROUT=$SERVER1OUT MASTERFLT=$SERVER1FLT SLAVEOUT=$SERVER2OUT +SLAVE2OUT=$SERVER3OUT SLAVEFLT=$SERVER2FLT +SLAVE2FLT=$SERVER3FLT # original outputs for cmp PROXYCACHEOUT=$DATADIR/proxycache.out diff --git a/tests/scripts/test050-syncrepl-multimaster b/tests/scripts/test050-syncrepl-multimaster index ee2989c45d..8b2d4baee2 100755 --- a/tests/scripts/test050-syncrepl-multimaster +++ b/tests/scripts/test050-syncrepl-multimaster @@ -23,12 +23,15 @@ fi PRODIR=$TESTDIR/pro CONDIR=$TESTDIR/con +CONDIR2=$TESTDIR/con2 DBPRO=$PRODIR/db DBCON=$CONDIR/db +DBCON2=$CONDIR2/db CFPRO=$PRODIR/slapd.d CFCON=$CONDIR/slapd.d +CFCON2=$CONDIR2/slapd.d -mkdir -p $TESTDIR $PRODIR $CONDIR $DBPRO $DBCON $CFPRO $CFCON +mkdir -p $TESTDIR $PRODIR $CONDIR $CONDIR2 $DBPRO $DBCON $DBCON2 $CFPRO $CFCON $CFCON2 $SLAPPASSWD -g -n >$CONFIGPWF @@ -36,6 +39,7 @@ $SLAPPASSWD -g -n >$CONFIGPWF # Test replication of dynamic config: # - start producer # - start consumer +# - start consumer2 # - configure over ldap # - populate over ldap # - configure syncrepl over ldap @@ -43,6 +47,18 @@ $SLAPPASSWD -g -n >$CONFIGPWF # echo "Initializing server configurations..." +$SLAPADD -F $CFCON2 -n 0 < $LOG3 2>&1 & +SLAVE2PID=$! +if test $WAIT != 0 ; then + echo SLAVE2PID $SLAVE2PID + read foo +fi +KILLPIDS="$KILLPIDS $SLAVE2PID" +cd $TESTWD + +sleep 1 + +echo "Using ldapsearch to check that consumer2 slapd is running..." +for i in 0 1 2 3 4 5; do + $LDAPSEARCH -s base -b "" -H $URI3 \ + 'objectclass=*' > /dev/null 2>&1 + RC=$? + if test $RC = 0 ; then + break + fi + echo "Waiting 5 seconds for slapd to start..." + sleep 5 +done + +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + +echo "Configuring syncrepl on consumer2..." +$LDAPMODIFY -D cn=config -H $URI3 -y $CONFIGPWF <>$TESTOUT 2>&1 +dn: olcDatabase={0}config,cn=config +changetype: modify +add: olcSyncRepl +olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config" bindmethod=simple + credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist + retry="5 5 300 5" timeout=1 +olcSyncRepl: rid=002 provider=$URI2 binddn="cn=config" bindmethod=simple + credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist + retry="5 5 300 5" timeout=1 +olcSyncRepl: rid=003 provider=$URI3 binddn="cn=config" bindmethod=simple + credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist + retry="5 5 300 5" timeout=1 - add: olcMirrorMode olcMirrorMode: TRUE @@ -246,10 +319,13 @@ olcSuffix: $BASEDN olcDbDirectory: ./db olcRootDN: $MANAGERDN olcRootPW: $PASSWD -olcSyncRepl: rid=003 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple +olcSyncRepl: rid=004 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1 -olcSyncRepl: rid=004 provider=$URI2 binddn="$MANAGERDN" bindmethod=simple +olcSyncRepl: rid=005 provider=$URI2 binddn="$MANAGERDN" bindmethod=simple + credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly + interval=00:00:00:10 retry="5 5 300 5" timeout=1 +olcSyncRepl: rid=006 provider=$URI3 binddn="$MANAGERDN" bindmethod=simple credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly interval=00:00:00:10 retry="5 5 300 5" timeout=1 olcMirrorMode: TRUE @@ -301,6 +377,26 @@ if test $RC != 0 ; then exit $RC fi +echo "Using ldapsearch to check that syncrepl received database changes on consumer2..." +RC=32 +for i in 0 1 2 3 4 5; do + RESULT=`$LDAPSEARCH -H $URI3 \ + -s base -b "cn=Ursula Hampster,ou=Alumni Association,ou=People,dc=example,dc=com" \ + '(objectClass=*)' 2>&1 | awk '/^dn:/ {print "OK"}'` + if test "x$RESULT" = "xOK" ; then + RC=0 + break + fi + echo "Waiting 5 seconds for syncrepl to receive changes..." + sleep 5 +done + +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + echo "Using ldapsearch to read config from the producer..." $LDAPSEARCH -b cn=config -D cn=config -H $URI1 -y $CONFIGPWF \ 'objectclass=*' > $MASTEROUT 2>&1 @@ -323,10 +419,23 @@ if test $RC != 0 ; then exit $RC fi +echo "Using ldapsearch to read config from consumer2..." +$LDAPSEARCH -b cn=config -D cn=config -H $URI3 -y $CONFIGPWF \ + 'objectclass=*' > $SLAVE2OUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at consumer2 ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + echo "Filtering producer results..." . $LDIFFILTER < $MASTEROUT > $MASTERFLT echo "Filtering consumer results..." . $LDIFFILTER < $SLAVEOUT > $SLAVEFLT +echo "Filtering consumer2 results..." +. $LDIFFILTER < $SLAVE2OUT > $SLAVE2FLT echo "Comparing retrieved configs from producer and consumer..." $CMP $MASTERFLT $SLAVEFLT > $CMPOUT @@ -337,6 +446,15 @@ if test $? != 0 ; then exit 1 fi +echo "Comparing retrieved configs from producer and consumer2..." +$CMP $MASTERFLT $SLAVE2FLT > $CMPOUT + +if test $? != 0 ; then + echo "test failed - producer and consumer2 configs differ" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 1 +fi + echo "Using ldapsearch to read all the entries from the producer..." $LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI1 -w $PASSWD \ 'objectclass=*' > $MASTEROUT 2>&1 @@ -359,12 +477,26 @@ if test $RC != 0 ; then exit $RC fi +echo "Using ldapsearch to read all the entries from the consumer2..." +$LDAPSEARCH -S "" -b "$BASEDN" -D "$MANAGERDN" -H $URI3 -w $PASSWD \ + 'objectclass=*' > $SLAVE2OUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at consumer2 ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + + test $KILLSERVERS != no && kill -HUP $KILLPIDS echo "Filtering producer results..." . $LDIFFILTER < $MASTEROUT > $MASTERFLT echo "Filtering consumer results..." . $LDIFFILTER < $SLAVEOUT > $SLAVEFLT +echo "Filtering consumer2 results..." +. $LDIFFILTER < $SLAVE2OUT > $SLAVE2FLT echo "Comparing retrieved entries from producer and consumer..." $CMP $MASTERFLT $SLAVEFLT > $CMPOUT @@ -374,6 +506,14 @@ if test $? != 0 ; then exit 1 fi +echo "Comparing retrieved entries from producer and consumer2..." +$CMP $MASTERFLT $SLAVE2FLT > $CMPOUT + +if test $? != 0 ; then + echo "test failed - producer and consumer2 databases differ" + exit 1 +fi + test $KILLSERVERS != no && wait echo "Restarting servers..." @@ -438,6 +578,38 @@ if test $RC != 0 ; then exit $RC fi +echo "Starting consumer2 slapd on TCP/IP port $PORT3..." +cd $CONDIR2 +echo "======================= RESTART =======================" >> $LOG3 +$SLAPD -F ./slapd.d -h $URI3 -d $LVL $TIMING >> $LOG3 2>&1 & +SLAVE2PID=$! +if test $WAIT != 0 ; then + echo SLAVE2PID $SLAVE2PID + read foo +fi +KILLPIDS="$KILLPIDS $SLAVE2PID" +cd $TESTWD + +sleep 1 + +echo "Using ldapsearch to check that consumer2 slapd is running..." +for i in 0 1 2 3 4 5; do + $LDAPSEARCH -s base -b "" -H $URI3 \ + 'objectclass=*' > /dev/null 2>&1 + RC=$? + if test $RC = 0 ; then + break + fi + echo "Waiting 5 seconds for slapd to start..." + sleep 5 +done + +if test $RC != 0 ; then + echo "ldapsearch failed ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + # Insert modifications and more tests here. SLEEP=10 echo "Waiting $SLEEP seconds for servers to resync..." -- 2.39.2