From 588822d969d77dab69b8677c4c421bb04d3e2c2f Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: Thu, 21 Jun 2018 12:31:30 +0200 Subject: [PATCH] Ticket 49591 - Improve conflict consistency in complex conflict cases and failure to do cleanup after tests Bug: in complex test cases for replication conflicts there were inconstencies on three masters. Also sometimes the cleanup after the test failed. Fix: handle the ADD and DEL cases properly where tombstones are turned into conflicts or conflicts into tombstones and where a valid entry with dn of the original conflict existes. If replication completes properly the cleanup works Reviewed by: --- ldap/servers/plugins/replication/urp.c | 4 +- ldap/servers/plugins/replication/urp.h | 2 +- ldap/servers/plugins/replication/urp_tombstone.c | 50 +++++++++++++++++++----- ldap/servers/slapd/back-ldbm/ldbm_add.c | 1 + 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c index 11c5da7..dbcc1b3 100644 --- a/ldap/servers/plugins/replication/urp.c +++ b/ldap/servers/plugins/replication/urp.c @@ -962,7 +962,7 @@ urp_fixup_add_entry(Slapi_Entry *e, const char *target_uniqueid, const char *par } int -urp_fixup_modrdn_entry (const Slapi_DN *entrydn, const char *newrdn, const Slapi_DN *newsuperior, const char *entryuniqueid, const char *parentuniqueid, CSN *opcsn, int opflags) +urp_fixup_modrdn_entry (const Slapi_DN *entrydn, const char *newrdn, const Slapi_DN *newsuperior, const char *entryuniqueid, const char *parentuniqueid, CSN *opcsn, int deloldrdn, int opflags) { Slapi_PBlock *newpb; Slapi_Operation *op; @@ -979,7 +979,7 @@ urp_fixup_modrdn_entry (const Slapi_DN *entrydn, const char *newrdn, const Slapi entrydn, newrdn, newsuperior, - 0, + deloldrdn, NULL, entryuniqueid, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), diff --git a/ldap/servers/plugins/replication/urp.h b/ldap/servers/plugins/replication/urp.h index d88dfbc..c09ceb6 100644 --- a/ldap/servers/plugins/replication/urp.h +++ b/ldap/servers/plugins/replication/urp.h @@ -34,7 +34,7 @@ int urp_fixup_add_entry(Slapi_Entry *e, const char *target_uniqueid, const char int urp_fixup_delete_entry(const char *uniqueid, const char *dn, CSN *opcsn, int opflags); int urp_fixup_rename_entry(const Slapi_Entry *entry, const char *newrdn, const char *parentuniqueid, int opflags); int urp_fixup_modify_entry(const char *uniqueid, const Slapi_DN *sdn, CSN *opcsn, Slapi_Mods *smods, int opflags); -int urp_fixup_modrdn_entry(const Slapi_DN *entrydn, const char *newrdn, const Slapi_DN *newsuperior, const char *entryuniqueid, const char *parentuniqueid, CSN *opcsn, int opflags); +int urp_fixup_modrdn_entry(const Slapi_DN *entrydn, const char *newrdn, const Slapi_DN *newsuperior, const char *entryuniqueid, const char *parentuniqueid, CSN *opcsn, int deloldrdn, int opflags); int is_suffix_dn(Slapi_PBlock *pb, const Slapi_DN *dn, Slapi_DN **parenddn); int is_suffix_dn_ext(Slapi_PBlock *pb, const Slapi_DN *dn, Slapi_DN **parenddn, int is_tombstone); diff --git a/ldap/servers/plugins/replication/urp_tombstone.c b/ldap/servers/plugins/replication/urp_tombstone.c index 4e96275..e047c71 100644 --- a/ldap/servers/plugins/replication/urp_tombstone.c +++ b/ldap/servers/plugins/replication/urp_tombstone.c @@ -126,6 +126,7 @@ tombstone_to_conflict_check_parent( uniqueid, NULL, NULL, + 0, OP_FLAG_NOOP); slapi_rdn_free(&rdn); slapi_sdn_free(&newsuperior); @@ -206,21 +207,21 @@ conflict_to_tombstone(char *sessionid, Slapi_Entry *entry, CSN *opcsn) Slapi_RDN *srdn = slapi_rdn_new(); const char *uniqueid = slapi_entry_get_uniqueid(entry); const char *newrdn = NULL; - char *conflictdn = NULL; + char *validdn = NULL; char *replconflict = slapi_entry_attr_get_charptr(entry, ATTR_NSDS5_REPLCONFLICT); if (replconflict) { - conflictdn = strstr(replconflict, " (ADD) "); - if (conflictdn == NULL) { + validdn = strstr(replconflict, " (ADD) "); + if (validdn == NULL) { /* error, wrong type of conflict */ op_result = 1; } else { - conflictdn += 7; - slapi_rdn_init_all_dn(srdn, conflictdn); + validdn += 7; + slapi_rdn_init_all_dn(srdn, validdn); newrdn = slapi_rdn_get_nrdn(srdn); slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "conflict_to_tombstone - %s - valid entry dn: %s newrdn: %s\n", - sessionid, conflictdn, newrdn); + sessionid, validdn, newrdn); } } @@ -230,12 +231,41 @@ conflict_to_tombstone(char *sessionid, Slapi_Entry *entry, CSN *opcsn) slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "conflict_to_tombstone - %s - Renaming entry %s to %s\n", sessionid, slapi_entry_get_dn_const(entry), newrdn); - op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP); - if (op_result) - goto done; - op_result = urp_fixup_delete_entry(uniqueid, slapi_entry_get_dn_const(entry), opcsn, 0); + op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP); + if (op_result == LDAP_SUCCESS) { + op_result = urp_fixup_delete_entry (uniqueid, slapi_entry_get_dn_const (entry), opcsn, 0); + } else if (op_result == LDAP_ALREADY_EXISTS) { + /* a entry with the valid dn exists, we need to temporarily move it + * out of the way and retry + */ + char *tmprdn = slapi_ch_smprintf("cn=tmprdn_%s",uniqueid); + char *parentdn = slapi_dn_parent(validdn); + char *tmpdn = slapi_ch_smprintf("%s,%s", tmprdn, parentdn); + Slapi_DN *tmp_sdn = slapi_sdn_new_dn_byval(tmpdn); + Slapi_DN *valid_sdn = slapi_sdn_new_dn_byval(validdn) ; + op_result = urp_fixup_modrdn_entry(valid_sdn, + tmprdn, NULL, NULL, NULL, NULL, 0, OP_FLAG_NOOP); + if (0 == op_result) { + int op_result2 = 0; + op_result = urp_fixup_rename_entry(entry, newrdn, NULL, OP_FLAG_NOOP); + if (0 == op_result) { + op_result = urp_fixup_delete_entry (uniqueid, slapi_entry_get_dn_const (entry), opcsn, 0); + } + op_result2 = urp_fixup_modrdn_entry(tmp_sdn, + newrdn, NULL, NULL, NULL, NULL, 1, OP_FLAG_NOOP); + if (op_result2) { + op_result = op_result2; + } + } + slapi_ch_free_string(&tmprdn); + slapi_ch_free_string(&parentdn); + slapi_ch_free_string(&tmpdn); + slapi_sdn_free(&tmp_sdn); + slapi_sdn_free(&valid_sdn); + } + done: slapi_ch_free_string(&replconflict); slapi_rdn_free(&srdn); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index f269115..cf5f073 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -344,6 +344,7 @@ ldbm_back_add(Slapi_PBlock *pb) is_tombstone_operation = 1; is_noop = 1; op_plugin_call = 0; + done_with_pblock_entry(pb, SLAPI_ADD_EXISTING_DN_ENTRY); rc = LDAP_SUCCESS; } else if (rc < 0) { int opreturn = 0; -- 2.9.5