From ec5af7b5e73b26ad6d330a33f629c051b5b0334c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Tue, 4 Apr 2017 18:24:57 +0100 Subject: [PATCH] ITS#6545 Update accesslog format and syncrepl consumer Make two successive modifications of the same attribute separate. This lets the consumer interpret the log entry the same way as the server that produced it. Still depends on the log entry attributes being read in the same order as they were written. --- servers/slapd/overlays/accesslog.c | 11 ++++++++++- servers/slapd/syncrepl.c | 5 +++++ tests/scripts/test043-delta-syncrepl | 3 +++ tests/scripts/test063-delta-multimaster | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index fb5d88989a..50aaa116e8 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -1586,7 +1586,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { case LOG_EN_MODRDN: case LOG_EN_MODIFY: - /* count all the mods */ + /* count all the mods + attributes (ITS#6545) */ i = 0; for ( m = op->orm_modlist; m; m = m->sml_next ) { if ( m->sml_values ) { @@ -1596,6 +1596,9 @@ static int accesslog_response(Operation *op, SlapReply *rs) { { i++; } + if ( m->sml_next && m->sml_desc == m->sml_next->sml_desc ) { + i++; + } } vals = ch_malloc( (i+1) * sizeof( struct berval )); i = 0; @@ -1666,6 +1669,12 @@ static int accesslog_response(Operation *op, SlapReply *rs) { *ptr = '\0'; i++; } + /* ITS#6545: when the same attribute is edited multiple times, + * record the transition */ + if ( m->sml_next && m->sml_desc == m->sml_next->sml_desc ) { + ber_str2bv( ":", STRLENOF(":"), 1, &vals[i] ); + i++; + } } if ( i > 0 ) { diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index e0dfbc9670..91f4d3a6b7 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1795,6 +1795,11 @@ syncrepl_accesslog_mods( if ( !colon ) { /* Invalid */ continue; + } else if ( colon == bv.bv_val ) { + /* ITS#6545: An empty attribute signals that a new mod + * is about to start */ + mod = NULL; + continue; } bv.bv_len = colon - bv.bv_val; diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl index b0e6eb4303..368181d331 100755 --- a/tests/scripts/test043-delta-syncrepl +++ b/tests/scripts/test043-delta-syncrepl @@ -308,6 +308,9 @@ cn: Rosco P. Coltrane dn: cn=Mark Elliot,ou=Alumni Association,ou=People,dc=example,dc=com changetype: modify replace: drink +drink: Red Wine +- +replace: drink dn: cn=All Staff,ou=Groups,dc=example,dc=com changetype: modrdn diff --git a/tests/scripts/test063-delta-multimaster b/tests/scripts/test063-delta-multimaster index e4e158fc1b..5e5247055b 100755 --- a/tests/scripts/test063-delta-multimaster +++ b/tests/scripts/test063-delta-multimaster @@ -473,6 +473,23 @@ if test $RC != 0 ; then exit $RC fi +$LDAPMODIFY -D "$MANAGERDN" -H $URI1 -w $PASSWD \ + >> $TESTOUT 2>&1 << EOF +dn: $THEDN +changetype: modify +replace: sn +sn: Replaced later +- +replace: sn +sn: Surname +EOF +RC=$? +if test $RC != 0 ; then + echo "ldapmodify failed for server 1 database ($RC)!" + test $KILLSERVERS != no && kill -HUP $KILLPIDS + exit $RC +fi + echo "Restoring replication between server 1 and 2..." n=1 while [ $n -le $MMR ]; do -- 2.39.2