1 file changed, 64 insertions(+), 28 deletions(-)
New commits:
commit efa23ced2a6e3de3389d9b801329066f511bc38c
Author: Noriko Hosoi <nhosoi@redhat.com>
Date: Fri May 9 10:10:49 2014 -0700
Ticket #47764 - Problem with deletion while replicated
Bug description: When checking a child entry on a node, it only
checked the first position, which was normally "deleted" if there
were no more children. But in some cases, a tombstoned child was
placed there. If it occurred, even though there were no live child
any more, _entryrdn_delete_key returned "has children" and the delete
operation failed.
Fix description: This patch checks all the children of the to-be-
deleted node and if there is no child or all of them are tombstones,
it goes to the next process. Also, the fixed a typo reported by
chatfield (Thank you!!)
https://fedorahosted.org/389/ticket/47764
Reviewed by chatfield and mreynolds@redhat.com (Thank you both!!)
(cherry picked from commit 832253ea96b83e7ebc16fe507d77090e87aed1c2)
(cherry picked from commit 86b34ca0a002715a263a56b1e8c870dd3035bce4)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
index 34b7f70..292f4fd 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
@@ -2802,6 +2802,8 @@ _entryrdn_delete_key(backend *be,
int issuffix = 0;
Slapi_RDN *tmpsrdn = NULL;
int db_retry = 0;
+ int done = 0;
+ char buffer[RDN_BULK_FETCH_BUFFER_SIZE];
slapi_log_error(SLAPI_LOG_TRACE, ENTRYRDN_TAG,
"--> _entryrdn_delete_key\n");
@@ -2835,45 +2837,79 @@ _entryrdn_delete_key(backend *be,
/* check if the target element has a child or not */
keybuf = slapi_ch_smprintf("%c%u", RDN_INDEX_CHILD, id);
key.data = (void *)keybuf;
- key.size = key.ulen = strlen(nrdn) + 1;
+ key.size = key.ulen = strlen(keybuf) + 1;
key.flags = DB_DBT_USERMEM;
+ /* Setting the bulk fetch buffer */
memset(&data, 0, sizeof(data));
- data.flags = DB_DBT_MALLOC;
+ data.ulen = sizeof(buffer);
+ data.size = sizeof(buffer);
+ data.data = buffer;
+ data.flags = DB_DBT_USERMEM;
- for (db_retry = 0; db_retry < RETRY_TIMES; db_retry++) {
- rc = cursor->c_get(cursor, &key, &data, DB_SET);
- if (rc) {
+ done = 0;
+ while (!done) {
+ rc = cursor->c_get(cursor, &key, &data, DB_SET|DB_MULTIPLE);
+ if (DB_LOCK_DEADLOCK == rc) {
+ slapi_log_error(ENTRYRDN_LOGLEVEL(rc), ENTRYRDN_TAG,
+ "_entryrdn_delete_key: cursor get deadlock\n");
+#ifdef FIX_TXN_DEADLOCKS
+#error if txn != NULL, have to retry the entire transaction
+
No comments:
Post a Comment