ldap/servers/plugins/replication/csnpl.c | 23 +++++++++++++---------- ldap/servers/plugins/replication/llist.c | 8 ++++++-- ldap/servers/plugins/usn/usn.c | 4 +++- ldap/servers/slapd/back-ldbm/ldbm_add.c | 15 +++++++++++++++ ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 15 +++++++++++++++ ldap/servers/slapd/plugin.c | 10 ++++++++-- 6 files changed, 60 insertions(+), 15 deletions(-)
New commits: commit ed1ebf66451a16144563d2d3d636fee6451009a4 Author: Noriko Hosoi nhosoi@totoro.usersys.redhat.com Date: Wed May 9 15:39:17 2012 -0700
Trac Ticket #359 - Database RUV could mismatch the one in changelog under the stress
https://fedorahosted.org/389/ticket/359
Fix description: . csnplRollUp (csnpl.c) - To get the first committed csndata, if there are preceded uncommitted csn's in the csnpl list, this patch skips them and returns the first committed csn. . llistRemoveCurrentAndGetNext (llist.c) - when the last item in the list is removed, tail pointer is initialized, too. . ldbm_back_add, ldbm_back_modrdn (ldbm_add.c, ldbm_modrdn.c) - make sure SLAPI_RESULT_CODE and SLAPI_PLUGIN_OPRETURN are set not just when the transaction is started, but in general. If an error occurs the RESULT_CODE triggers to remove the CSN from the RUV element. . plugin_call_func (plugin.c) - when the plugin type is be pre/ post op, respect the fatal error code (-1) instead of OR the results from all the plugins. The error code -1 is checked in ldap_back_add and ldbm_back_modrdn to distinguish from the URP operation bits.
Ported commit f0f74b57f81998a325dc7472b9ea9b44c5ff6439.
diff --git a/ldap/servers/plugins/replication/csnpl.c b/ldap/servers/plugins/replication/csnpl.c index 62f4fc4..16cebf1 100644 --- a/ldap/servers/plugins/replication/csnpl.c +++ b/ldap/servers/plugins/replication/csnpl.c @@ -298,28 +298,31 @@ csnplRollUp(CSNPL *csnpl, CSN **first_commited) CSN *largest_committed_csn = NULL; csnpldata *data; PRBool freeit = PR_TRUE; + void *iterator;
slapi_rwlock_wrlock (csnpl->csnLock); if (first_commited) { /* Avoid non-initialization issues due to careless callers */ *first_commited = NULL; } - data = (csnpldata *)llistGetHead(csnpl->csnList); - while (NULL != data && data->committed) + data = (csnpldata *)llistGetFirst(csnpl->csnList, &iterator); + while (NULL != data) { if (NULL != largest_committed_csn && freeit) { csn_free(&largest_committed_csn); } - freeit = PR_TRUE; - largest_committed_csn = data->csn; /* Save it */ - if (first_commited && (*first_commited == NULL)) { - *first_commited = data->csn; - freeit = PR_FALSE; + if (data->committed) { + freeit = PR_TRUE; + largest_committed_csn = data->csn; /* Save it */ + if (first_commited && (*first_commited == NULL)) { + *first_commited = data->csn; + freeit = PR_FALSE; + } + data = (csnpldata *)llistRemoveCurrentAndGetNext(csnpl->csnList, &iterator); + } else { + data = (csnpldata *)llistGetNext (csnpl->csnList, &iterator); } - data = (csnpldata*)llistRemoveHead (csnpl->csnList); - slapi_ch_free((void **)&data); - data = (csnpldata *)llistGetHead(csnpl->csnList); }
#ifdef DEBUG diff --git a/ldap/servers/plugins/replication/llist.c b/ldap/servers/plugins/replication/llist.c index bd0bc1d..e80f532 100644 --- a/ldap/servers/plugins/replication/llist.c +++ b/ldap/servers/plugins/replication/llist.c @@ -167,10 +167,14 @@ void* llistRemoveCurrentAndGetNext (LList *list, void **iterator) prevNode->next = node->next; _llistDestroyNode (&node, NULL); node = prevNode->next; - if (node) + if (node) { return node->data; - else + } else { + if (list->head->next == NULL) { + list->tail = NULL; + } return NULL; + } } else return NULL; diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c index faa737c..c8672d5 100644 --- a/ldap/servers/plugins/usn/usn.c +++ b/ldap/servers/plugins/usn/usn.c @@ -455,6 +455,7 @@ bail: /* * usn_bepreop_modify - add/replace next USN to the mods; * shared by modify and modrdn + * Note: bepreop should not return other than LDAP_SUCCESS. */ static int usn_bepreop_modify (Slapi_PBlock *pb) @@ -470,7 +471,8 @@ usn_bepreop_modify (Slapi_PBlock *pb) slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); slapi_pblock_get(pb, SLAPI_BACKEND, &be); if (NULL == be) { - rc = LDAP_PARAM_ERROR; + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_bepreop_modify: no backend.\n"); goto bail; } if (LDAP_SUCCESS == _usn_mod_next_usn(&mods, be)) { diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index df09c64..132b125 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -116,6 +116,7 @@ ldbm_back_add( Slapi_PBlock *pb ) int is_ruv = 0; /* True if the current entry is RUV */ CSN *opcsn = NULL; entry_address addr = {0}; + int val = 0;
slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ); @@ -964,6 +965,20 @@ error_return: disk_full = 1; }
+ /* make sure SLAPI_RESULT_CODE and SLAPI_PLUGIN_OPRETURN are set */ + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &val); + if (!val) { + if (!ldap_result_code) { + ldap_result_code = LDAP_OPERATIONS_ERROR; + } + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); + } + slapi_pblock_get( pb, SLAPI_PLUGIN_OPRETURN, &val ); + if (!val) { + val = -1; + slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &val ); + } + diskfull_return: if (disk_full) { rc= return_on_disk_full(li); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c index 6b0fa34..0b56219 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c @@ -111,6 +111,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) entry_address *newsuperior_addr; char ebuf[BUFSIZ]; CSN *opcsn = NULL; + int val = 0;
/* sdn & parentsdn need to be initialized before "goto *_return" */ slapi_sdn_init(&dn_newdn); @@ -1065,6 +1066,20 @@ error_return: disk_full = 1; }
+ /* make sure SLAPI_RESULT_CODE and SLAPI_PLUGIN_OPRETURN are set */ + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &val); + if (!val) { + if (!ldap_result_code) { + ldap_result_code = LDAP_OPERATIONS_ERROR; + } + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); + } + slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &val); + if (!val) { + val = -1; + slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &val); + } + if (disk_full) { retval = return_on_disk_full(li); diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index 4c8e8bd..070ce54 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -1465,8 +1465,14 @@ plugin_call_func (struct slapdplugin *list, int operation, Slapi_PBlock *pb, int } else if (SLAPI_PLUGIN_BEPREOPERATION == list->plg_type || SLAPI_PLUGIN_BEPOSTOPERATION == list->plg_type) { - /* OR the result into the return value for be pre/postops */ - return_value |= rc; + /* respect fatal error (-1); should not OR it */ + if (-1 == rc) { + return_value = rc; + } else if (-1 != return_value) { + /* OR the result into the return value + * for be pre/postops */ + return_value |= rc; + } } } /* counters_to_errors_log("after plugin call"); */
389-commits@lists.fedoraproject.org