Tuesday, January 24, 2017

[389-commits] Branch '389-ds-base-1.3.5' - ldap/servers

ldap/servers/plugins/replication/csnpl.c | 75 ++++++++++++++++++++---
ldap/servers/plugins/replication/csnpl.h | 5 +
ldap/servers/plugins/replication/repl5.h | 2
ldap/servers/plugins/replication/repl5_init.c | 22 ++++++
ldap/servers/plugins/replication/repl5_plugins.c | 40 +++++++-----
ldap/servers/plugins/replication/repl5_replica.c | 6 -
ldap/servers/plugins/replication/repl5_ruv.c | 74 ++++++++++++++++------
ldap/servers/plugins/replication/repl5_ruv.h | 4 -
ldap/servers/slapd/csn.c | 15 ++++
ldap/servers/slapd/slapi-private.h | 2
10 files changed, 195 insertions(+), 50 deletions(-)

New commits:
commit 79a3deafe943a3ce5c31c50272939146d17bd7ac
Author: Ludwig Krispenz <lkrispen@redhat.com>
Date: Tue Jan 24 15:07:19 2017 +0100

Ticket 49008 backport 1.3.5 : aborted operation can leave RUV in incorrect state

Bug description:
If a plugin operation succeeded, but the operation itself fails and is aborted the RUV is in an incorrect state (rolled up to the succesful plugin op)

Fix Decription:
Introduce a "primary_csn", this is the csn of the main operation, either a client operation or a replicated operation.
csns generated by internal operations, eg by plugins are secondary csn.

Maintain the primary csn in thread local data, like it is used for the agreement name (or txn stack): prim_csn.

Extend the data structure of the pending list to keep prim_csn for each inserted csn

If a csn is created or received check prim_csn: if it exists use it, if it doesn't exist set it

when inserting a csn to the pending list pass the prim_csn

when cancelling a csn, if it is the prim_csn also cancell all secondary csns

when committing a csn,

if it is not the primary csn, do nothing

if it is the prim_csn trigger the pending list rollup, stop at the first not committed csn

if the RID of the prim_csn is not the local RID also rollup the pending list for the local RID.

Reviewed by: Thierry, Thanks

diff --git a/ldap/servers/plugins/replication/csnpl.c b/ldap/servers/plugins/replication/csnpl.c
index acd38d0..db1ae13 100644
--- a/ldap/servers/plugins/replication/csnpl.c
+++ b/ldap/servers/plugins/replication/csnpl.c
@@ -24,8 +24,9 @@ struct csnpl

typedef struct _csnpldata
{
- PRBool committed; /* True if CSN committed */
- CSN *csn; /* The actual CSN */
+ PRBool committed; /* True if CSN committed */
+ CSN *csn; /* The actual CSN */
+ const CSN *prim_csn; /* The primary CSN of an operation consising of multiple sub ops*/
} csnpldata;

/* forward declarations */
@@ -103,7 +104,7 @@ void csnplFree (CSNPL **csnpl)
* 1 if the csn has already been seen
* -1 for any other kind of errors
*/
-int csnplInsert (CSNPL *csnpl, const CSN *csn)
+int csnplInsert (CSNPL *csnpl, const CSN *csn, const CSN *prim_csn)
{
int rc;
csnpldata *csnplnode;
@@ -131,6 +132,7 @@ int csnplInsert (CSNPL *csnpl, const CSN *csn)
csnplnode = (csnpldata *)slapi_ch_malloc(sizeof(csnpldata));
csnplnode->committed = PR_FALSE;
csnplnode->csn = csn_dup(csn);
+ csnplnode->prim_csn = prim_csn;
csn_as_string(csn, PR_FALSE, csn_str);
rc = llistInsertTail (csnpl->csnList, csn_str, csnplnode);

@@ -186,6 +188,57 @@ int csnplRemove (CSNPL *csnpl, const CSN *csn)
return 0;
}

+int csnplRemoveAll (CSNPL *csnpl, const CSN *csn)
+{
+ csnpldata *data;
+ void *iterator;
+
+ slapi_rwlock_wrlock (csnpl->csnLock);
+ data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator);
+ while (NULL != data)
+ {
+ if (csn_is_equal(data->csn, csn) ||
+ csn_is_equal(data->prim_csn, csn)) {
+ csnpldata_free(&data);
+ data = (csnpldata *)llistRemoveCurrentAndGetNext(csnpl->csnList, &iterator);
+ } else {
+ data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator);
+ }
+ }
+#ifdef DEBUG
+ _csnplDumpContentNoLock(csnpl, "csnplRemoveAll");
+

No comments:

Post a Comment