From 4ca27dd249849ae081f2f14b90f6d631ee25b54a Mon Sep 17 00:00:00 2001 From: Quanah Gibson-Mount Date: Mon, 19 Apr 2010 21:24:41 +0000 Subject: [PATCH] ITS#6458, ITS#6472 --- CHANGES | 2 + servers/slapd/syncrepl.c | 52 +++++- tests/scripts/test018-syncreplication-persist | 151 +++++++++++++++++- 3 files changed, 197 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index a95e301485..67ba406e8e 100644 --- a/CHANGES +++ b/CHANGES @@ -22,7 +22,9 @@ OpenLDAP 2.4.22 Engineering Fixed slapd REP_ENTRY flag handling (ITS#5340) Fixed slapd sasl auxprop_lookup (ITS#6441) Fixed slapd sasl auxprop ssf (ITS#5195) + Fixed slapd syncrepl for attributes with no matching rule (ITS#6458) Fixed slapd syncrepl for unknown attrs and delta-sync (ITS#6473) + Fixed slapd syncrep loop with moddn (ITS#6472) Fixed slapo-accesslog to not replicate internal purges (ITS#6519) Fixed slapd-bdb contextCSN updates from updatedn (ITS#6469) Fixed slapd-bdb lockobj zeroing (ITS#6501) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 526cc0e47b..9b9c73e107 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -131,6 +131,8 @@ static int syncrepl_updateCookie( struct sync_cookie * ); static struct berval * slap_uuidstr_from_normalized( struct berval *, struct berval *, void * ); +static int syncrepl_add_glue_ancestors( + Operation* op, Entry *e ); /* callback functions */ static int dn_callback( Operation *, SlapReply * ); @@ -2562,7 +2564,19 @@ retry_add:; mod->sml_next = m2; } op->o_bd = si->si_wbe; +retry_modrdn:; rc = op->o_bd->be_modrdn( op, &rs_modify ); + + /* NOTE: noSuchObject should result because the new superior + * has not been added yet (ITS#6472) */ + if ( rc == LDAP_NO_SUCH_OBJECT && !BER_BVISNULL( op->orr_nnewSup )) { + Operation op2 = *op; + rc = syncrepl_add_glue_ancestors( &op2, entry ); + if ( rc == LDAP_SUCCESS ) { + goto retry_modrdn; + } + } + op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx ); @@ -2888,8 +2902,8 @@ syncrepl_del_nonpresent( return; } -int -syncrepl_add_glue( +static int +syncrepl_add_glue_ancestors( Operation* op, Entry *e ) { @@ -3023,6 +3037,34 @@ syncrepl_add_glue( ndn.bv_len = e->e_nname.bv_len - (ndn.bv_val - e->e_nname.bv_val); } + return rc; +} + +int +syncrepl_add_glue( + Operation* op, + Entry *e ) +{ + slap_callback cb = { NULL }; + int rc; + Backend *be = op->o_bd; + SlapReply rs_add = {REP_RESULT}; + + rc = syncrepl_add_glue_ancestors( op, e ); + switch ( rc ) { + case LDAP_SUCCESS: + case LDAP_ALREADY_EXISTS: + break; + + default: + return rc; + } + + op->o_tag = LDAP_REQ_ADD; + op->o_callback = &cb; + cb.sc_response = null_callback; + cb.sc_private = NULL; + op->o_req_dn = e->e_name; op->o_req_ndn = e->e_nname; op->ora_e = e; @@ -3256,10 +3298,12 @@ attr_cmp( Operation *op, Attribute *old, Attribute *new, * Also use replace op if attr has no equality matching rule. * (ITS#5781) */ - if ( nn && no < o && + if ( ( nn || ( no > 0 && no < o ) ) && ( old->a_desc == slap_schema.si_ad_objectClass || - !old->a_desc->ad_type->sat_equality )) + !old->a_desc->ad_type->sat_equality ) ) + { no = o; + } i = j; /* all old values were deleted, just use the replace op */ diff --git a/tests/scripts/test018-syncreplication-persist b/tests/scripts/test018-syncreplication-persist index 9b1059885c..3b72741bc6 100755 --- a/tests/scripts/test018-syncreplication-persist +++ b/tests/scripts/test018-syncreplication-persist @@ -16,6 +16,8 @@ echo "running defines.sh" . $SRCDIR/scripts/defines.sh +OPATTRS="entryUUID creatorsName createTimestamp modifiersName modifyTimestamp" + if test $SYNCPROV = syncprovno; then echo "Syncrepl provider overlay not available, test skipped" exit 0 @@ -116,6 +118,42 @@ fi echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..." sleep $SLEEP1 +echo "Using ldapsearch to read all the entries from the producer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ + '(objectclass=*)' '*' $OPATTRS > $MASTEROUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at producer ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + +echo "Using ldapsearch to read all the entries from the consumer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT4 \ + '(objectclass=*)' '*' $OPATTRS > $SLAVEOUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at consumer ($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 "Comparing retrieved entries from producer and consumer..." +$CMP $MASTERFLT $SLAVEFLT > $CMPOUT + +if test $? != 0 ; then + echo "test failed - producer and consumer databases differ" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 1 +fi + echo "Stopping the provider, sleeping 10 seconds and restarting it..." kill -HUP "$PID" wait $PID @@ -203,10 +241,32 @@ drink: Coffee homepostaladdress: 844 Brown St. Apt. 4 $ Ann Arbor, MI 48104 description: Very odd facsimiletelephonenumber: +1 313 555 7557 +facsimiletelephonenumber: +1 313 555 9998 +facsimiletelephonenumber: +1 313 555 9999 telephonenumber: +1 313 555 8343 mail: gjensen@mailgw.example.com homephone: +1 313 555 8844 +# modify attribute with no matching rule (ITS#6458) +dn: cn=Gern Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com +changetype: modify +replace: facsimiletelephonenumber +facsimiletelephonenumber: +1 313 555 9998 +facsimiletelephonenumber: +1 313 555 9999 + +dn: cn=Gern Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com +changetype: modify +replace: facsimiletelephonenumber +facsimiletelephonenumber: +1 313 555 9998 +facsimiletelephonenumber: +1 313 555 9999 +facsimiletelephonenumber: +1 313 555 7557 + +dn: cn=Gern Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com +changetype: modify +replace: facsimiletelephonenumber +facsimiletelephonenumber: +1 313 555 9998 +facsimiletelephonenumber: +1 313 555 9999 + dn: ou=Retired, ou=People, dc=example,dc=com changetype: add objectclass: organizationalUnit @@ -267,6 +327,42 @@ fi echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..." sleep $SLEEP1 +echo "Using ldapsearch to read all the entries from the producer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ + '(objectclass=*)' '*' $OPATTRS > $MASTEROUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at producer ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + +echo "Using ldapsearch to read all the entries from the consumer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT4 \ + '(objectclass=*)' '*' $OPATTRS > $SLAVEOUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at consumer ($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 "Comparing retrieved entries from producer and consumer..." +$CMP $MASTERFLT $SLAVEFLT > $CMPOUT + +if test $? != 0 ; then + echo "test failed - producer and consumer databases differ" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 1 +fi + echo "Stopping consumer to test recovery..." kill -HUP $SLAVEPID wait $SLAVEPID @@ -294,6 +390,18 @@ changetype: modify replace: description description: Example, Inc. itsdomain2 test domain +# rename with a newly added newSuperior while the consumer is down (ITS#6472) +dn: ou=New Branch,dc=example,dc=com +changetype: add +objectClass: organizationalUnit +ou: New Branch + +dn: cn=Dorothy Stevens, ou=Alumni Association, ou=People, dc=example,dc=com +changetype: modrdn +newrdn: cn=Dorothy Stevens +deleteoldrdn: 0 +newsuperior: ou=New Branch,dc=example,dc=com + EOMODS RC=$? @@ -316,6 +424,42 @@ KILLPIDS="$PID $SLAVEPID" echo "Waiting $SLEEP1 seconds for syncrepl to receive changes..." sleep $SLEEP1 +echo "Using ldapsearch to read all the entries from the producer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ + '(objectclass=*)' '*' $OPATTRS > $MASTEROUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at producer ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + +echo "Using ldapsearch to read all the entries from the consumer..." +$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT4 \ + '(objectclass=*)' '*' $OPATTRS > $SLAVEOUT 2>&1 +RC=$? + +if test $RC != 0 ; then + echo "ldapsearch failed at consumer ($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 "Comparing retrieved entries from producer and consumer..." +$CMP $MASTERFLT $SLAVEFLT > $CMPOUT + +if test $? != 0 ; then + echo "test failed - producer and consumer databases differ" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit 1 +fi + if test ! $BACKLDAP = "ldapno" ; then echo "Try updating the consumer slapd..." $LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT4 -w $PASSWD > \ @@ -351,8 +495,6 @@ EOMODS sleep $SLEEP1 fi -OPATTRS="entryUUID creatorsName createTimestamp modifiersName modifyTimestamp" - echo "Using ldapsearch to read all the entries from the producer..." $LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \ '(objectclass=*)' '*' $OPATTRS > $MASTEROUT 2>&1 @@ -375,8 +517,6 @@ if test $RC != 0 ; then exit $RC fi -test $KILLSERVERS != no && kill -HUP $KILLPIDS - echo "Filtering producer results..." $LDIFFILTER < $MASTEROUT > $MASTERFLT echo "Filtering consumer results..." @@ -387,9 +527,12 @@ $CMP $MASTERFLT $SLAVEFLT > $CMPOUT if test $? != 0 ; then echo "test failed - producer and consumer databases differ" + test $KILLSERVERS != no && kill -HUP $KILLPIDS exit 1 fi +test $KILLSERVERS != no && kill -HUP $KILLPIDS + echo ">>>>> Test succeeded" test $KILLSERVERS != no && wait -- 2.39.5