From 13fbc1d8fe9c87ce88f0d88b79819101b04c2aa9 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Wed, 11 Dec 2013 11:25:44 -0500 Subject: [PATCH 152/225] Ticket 47627 - changelog iteration should ignore cleaned rids when getting the minCSN Description: If a change is not found in the change log the server will look for a min csn to start the replay. This minCSN should not come from a cleaned RUV element. https://fedorahosted.org/389/ticket/47627 Reviewed by: rmeggins & lkrispenz(Thanks!!) (cherry picked from commit 9c6e9bb12327a2d50e651221614d34984b605427) (cherry picked from commit e746f7e02826bce27819c1a4ca514ef3d23085c5) --- ldap/servers/plugins/replication/cl5_api.c | 2 +- ldap/servers/plugins/replication/repl5_ruv.c | 42 ++++++++++++++++++++++------ ldap/servers/plugins/replication/repl5_ruv.h | 3 ++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c index f2e038e..55bda39 100644 --- a/ldap/servers/plugins/replication/cl5_api.c +++ b/ldap/servers/plugins/replication/cl5_api.c @@ -5132,7 +5132,7 @@ static int _cl5PositionCursorForReplay (ReplicaId consumerRID, const RUV *consum { /* use the supplier min csn for the buffer start csn - we know this csn is in our changelog */ - if ((RUV_SUCCESS == ruv_get_min_csn(supplierRuv, &startCSN)) && + if ((RUV_SUCCESS == ruv_get_min_csn_ext(supplierRuv, &startCSN, 1 /* ignore cleaned rids */)) && startCSN) { /* must now free startCSN */ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) { diff --git a/ldap/servers/plugins/replication/repl5_ruv.c b/ldap/servers/plugins/replication/repl5_ruv.c index 2808c58..d9a3b26 100644 --- a/ldap/servers/plugins/replication/repl5_ruv.c +++ b/ldap/servers/plugins/replication/repl5_ruv.c @@ -986,9 +986,9 @@ ruv_covers_csn_cleanallruv(const RUV *ruv, const CSN *csn) * or max{maxcsns of all ruv elements} if get_the_max != 0. */ static int -ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid) +ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid, int ignore_cleaned_rid) { - int return_value; + int return_value = RUV_SUCCESS; if (ruv == NULL || csn == NULL) { @@ -1000,6 +1000,7 @@ ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid CSN *found = NULL; RUVElement *replica; int cookie; + slapi_rwlock_rdlock (ruv->lock); for (replica = dl_get_first (ruv->elements, &cookie); replica; replica = dl_get_next (ruv->elements, &cookie)) @@ -1016,6 +1017,10 @@ ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid { continue; } + if(ignore_cleaned_rid && is_cleaned_rid(replica->rid)){ + continue; + } + if(rid){ /* we are only interested in this rid's maxcsn */ if(replica->rid == rid){ found = replica->csn; @@ -1029,36 +1034,55 @@ ruv_get_min_or_max_csn(const RUV *ruv, CSN **csn, int get_the_max, ReplicaId rid found = replica->csn; } } - } + } + if (found == NULL) { - *csn = NULL; + *csn = NULL; } else { *csn = csn_dup (found); } slapi_rwlock_unlock (ruv->lock); - return_value = RUV_SUCCESS; } return return_value; } int -ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid){ - return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, rid); +ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid) +{ + return ruv_get_rid_max_csn_ext(ruv, csn, rid, 0); +} + +int +ruv_get_rid_max_csn_ext(const RUV *ruv, CSN **csn, ReplicaId rid, int ignore_cleaned_rid) +{ + return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, rid, ignore_cleaned_rid); } int ruv_get_max_csn(const RUV *ruv, CSN **csn) { - return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, 0 /* rid */); + return ruv_get_max_csn_ext(ruv, csn, 0); +} + +int +ruv_get_max_csn_ext(const RUV *ruv, CSN **csn, int ignore_cleaned_rid) +{ + return ruv_get_min_or_max_csn(ruv, csn, 1 /* get the max */, 0 /* rid */, ignore_cleaned_rid); } int ruv_get_min_csn(const RUV *ruv, CSN **csn) { - return ruv_get_min_or_max_csn(ruv, csn, 0 /* get the min */, 0 /* rid */); + return ruv_get_min_csn_ext(ruv, csn, 0); +} + +int +ruv_get_min_csn_ext(const RUV *ruv, CSN **csn, int ignore_cleaned_rid) +{ + return ruv_get_min_or_max_csn(ruv, csn, 0 /* get the min */, 0 /* rid */, ignore_cleaned_rid); } int diff --git a/ldap/servers/plugins/replication/repl5_ruv.h b/ldap/servers/plugins/replication/repl5_ruv.h index fdc8af2..5264395 100644 --- a/ldap/servers/plugins/replication/repl5_ruv.h +++ b/ldap/servers/plugins/replication/repl5_ruv.h @@ -118,8 +118,11 @@ PRBool ruv_covers_csn(const RUV *ruv, const CSN *csn); PRBool ruv_covers_csn_strict(const RUV *ruv, const CSN *csn); PRBool ruv_covers_csn_cleanallruv(const RUV *ruv, const CSN *csn); int ruv_get_min_csn(const RUV *ruv, CSN **csn); +int ruv_get_min_csn_ext(const RUV *ruv, CSN **csn, int ignore_cleaned_rid); int ruv_get_max_csn(const RUV *ruv, CSN **csn); +int ruv_get_max_csn_ext(const RUV *ruv, CSN **csn, int ignore_cleaned_rid); int ruv_get_rid_max_csn(const RUV *ruv, CSN **csn, ReplicaId rid); +int ruv_get_rid_max_csn_ext(const RUV *ruv, CSN **csn, ReplicaId rid, int ignore_cleaned_rid); int ruv_enumerate_elements (const RUV *ruv, FNEnumRUV fn, void *arg); int ruv_to_smod(const RUV *ruv, Slapi_Mod *smod); int ruv_last_modified_to_smod(const RUV *ruv, Slapi_Mod *smod); -- 1.8.1.4