|
|
ebc913e |
From dcb46ca16114e51108c1a0549235af5623f7596b Mon Sep 17 00:00:00 2001
|
|
|
ebc913e |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
ebc913e |
Date: Sat, 7 Apr 2012 09:05:18 -0600
|
|
|
ebc913e |
Subject: [PATCH 2/4] Bug 808770 - [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
|
|
|
ebc913e |
|
|
|
ebc913e |
https://bugzilla.redhat.com/show_bug.cgi?id=808770
|
|
|
ebc913e |
Resolves: bug 808770
|
|
|
ebc913e |
Bug Description: [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd was killed by signal 11 (SIGSEGV)
|
|
|
ebc913e |
Reviewed by: ???
|
|
|
ebc913e |
Branch: master
|
|
|
ebc913e |
Fix Description:
|
|
|
ebc913e |
1) Entries can be deleted out from under a search operation. The range read
|
|
|
ebc913e |
code was not handling this situation correctly. The code should notice that
|
|
|
ebc913e |
the index query was empty, and continue to the next highest key in the range.
|
|
|
ebc913e |
2) DB cursor c_close() functions can return DB_LOCK_DEADLOCK that must be
|
|
|
ebc913e |
reported to the higher level operation functions. If not, then subsequent
|
|
|
ebc913e |
operations in the same transaction fail. When a DB_LOCK_DEADLOCK is returned
|
|
|
ebc913e |
by any DB update operation in the transaction, the transaction must be aborted
|
|
|
ebc913e |
and a new transaction begun before any other transacted db operations can
|
|
|
ebc913e |
occur.
|
|
|
ebc913e |
Platforms tested: RHEL6 x86_64
|
|
|
ebc913e |
Flag Day: no
|
|
|
ebc913e |
Doc impact: no
|
|
|
ebc913e |
---
|
|
|
ebc913e |
ldap/servers/slapd/back-ldbm/idl_new.c | 44 ++++++++++++++-----
|
|
|
ebc913e |
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 31 +++++++++++--
|
|
|
ebc913e |
ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c | 60 ++++++++++++++++++++-----
|
|
|
ebc913e |
3 files changed, 107 insertions(+), 28 deletions(-)
|
|
|
ebc913e |
|
|
|
ebc913e |
diff --git a/ldap/servers/slapd/back-ldbm/idl_new.c b/ldap/servers/slapd/back-ldbm/idl_new.c
|
|
|
ebc913e |
index 4667c87..d62511c 100644
|
|
|
ebc913e |
--- a/ldap/servers/slapd/back-ldbm/idl_new.c
|
|
|
ebc913e |
+++ b/ldap/servers/slapd/back-ldbm/idl_new.c
|
|
|
ebc913e |
@@ -333,8 +333,14 @@ IDList * idl_new_fetch(
|
|
|
ebc913e |
error:
|
|
|
ebc913e |
/* Close the cursor */
|
|
|
ebc913e |
if (NULL != cursor) {
|
|
|
ebc913e |
- if (0 != cursor->c_close(cursor)) {
|
|
|
ebc913e |
- ldbm_nasty(filename,3,ret);
|
|
|
ebc913e |
+ int ret2 = cursor->c_close(cursor);
|
|
|
ebc913e |
+ if (ret2) {
|
|
|
ebc913e |
+ ldbm_nasty(filename,3,ret2);
|
|
|
ebc913e |
+ if (!ret) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ ret = ret2;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
*flag_err = ret;
|
|
|
ebc913e |
@@ -418,8 +424,9 @@ int idl_new_insert_key(
|
|
|
ebc913e |
error:
|
|
|
ebc913e |
/* Close the cursor */
|
|
|
ebc913e |
if (NULL != cursor) {
|
|
|
ebc913e |
- if (0 != cursor->c_close(cursor)) {
|
|
|
ebc913e |
- ldbm_nasty(filename,56,ret);
|
|
|
ebc913e |
+ int ret2 = cursor->c_close(cursor);
|
|
|
ebc913e |
+ if (ret2) {
|
|
|
ebc913e |
+ ldbm_nasty(filename,56,ret2);
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
#else
|
|
|
ebc913e |
@@ -439,7 +446,7 @@ error:
|
|
|
ebc913e |
/* this is okay */
|
|
|
ebc913e |
ret = 0;
|
|
|
ebc913e |
} else {
|
|
|
ebc913e |
- ldbm_nasty(filename,50,ret);
|
|
|
ebc913e |
+ ldbm_nasty(filename,60,ret);
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
#endif
|
|
|
ebc913e |
@@ -491,8 +498,14 @@ int idl_new_delete_key(
|
|
|
ebc913e |
error:
|
|
|
ebc913e |
/* Close the cursor */
|
|
|
ebc913e |
if (NULL != cursor) {
|
|
|
ebc913e |
- if (0 != cursor->c_close(cursor)) {
|
|
|
ebc913e |
- ldbm_nasty(filename,24,ret);
|
|
|
ebc913e |
+ int ret2 = cursor->c_close(cursor);
|
|
|
ebc913e |
+ if (ret2) {
|
|
|
ebc913e |
+ ldbm_nasty(filename,24,ret2);
|
|
|
ebc913e |
+ if (!ret) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ ret = ret2;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
return ret;
|
|
|
ebc913e |
@@ -559,14 +572,17 @@ static int idl_new_store_allids(backend *be, DB *db, DBT *key, DB_TXN *txn)
|
|
|
ebc913e |
error:
|
|
|
ebc913e |
/* Close the cursor */
|
|
|
ebc913e |
if (NULL != cursor) {
|
|
|
ebc913e |
- if (0 != cursor->c_close(cursor)) {
|
|
|
ebc913e |
- ldbm_nasty(filename,33,ret);
|
|
|
ebc913e |
+ int ret2 = cursor->c_close(cursor);
|
|
|
ebc913e |
+ if (ret2) {
|
|
|
ebc913e |
+ ldbm_nasty(filename,33,ret2);
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
return ret;
|
|
|
ebc913e |
+#ifdef KRAZY_K0DE
|
|
|
ebc913e |
/* If this function is called in "no-allids" mode, then it's a bug */
|
|
|
ebc913e |
ldbm_nasty(filename,63,0);
|
|
|
ebc913e |
return -1;
|
|
|
ebc913e |
+#endif
|
|
|
ebc913e |
}
|
|
|
ebc913e |
#endif
|
|
|
ebc913e |
|
|
|
ebc913e |
@@ -662,8 +678,14 @@ int idl_new_store_block(
|
|
|
ebc913e |
error:
|
|
|
ebc913e |
/* Close the cursor */
|
|
|
ebc913e |
if (NULL != cursor) {
|
|
|
ebc913e |
- if (0 != cursor->c_close(cursor)) {
|
|
|
ebc913e |
- ldbm_nasty(filename,49,ret);
|
|
|
ebc913e |
+ int ret2 = cursor->c_close(cursor);
|
|
|
ebc913e |
+ if (ret2) {
|
|
|
ebc913e |
+ ldbm_nasty(filename,49,ret2);
|
|
|
ebc913e |
+ if (!ret) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ ret = ret2;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
return ret;
|
|
|
ebc913e |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
ebc913e |
index b07f634..014af73 100644
|
|
|
ebc913e |
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
ebc913e |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
ebc913e |
@@ -692,6 +692,12 @@ ldbm_back_delete( Slapi_PBlock *pb )
|
|
|
ebc913e |
retval = index_addordel_values_sv(be, LDBM_PARENTID_STR,
|
|
|
ebc913e |
svals, NULL, e->ep_id,
|
|
|
ebc913e |
BE_INDEX_ADD, &txn);
|
|
|
ebc913e |
+ if (DB_LOCK_DEADLOCK == retval) {
|
|
|
ebc913e |
+ LDAPDebug0Args( LDAP_DEBUG_ARGS,
|
|
|
ebc913e |
+ "delete (updating " LDBM_PARENTID_STR ") DB_LOCK_DEADLOCK\n");
|
|
|
ebc913e |
+ /* Retry txn */
|
|
|
ebc913e |
+ continue;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
if ( retval ) {
|
|
|
ebc913e |
LDAPDebug( LDAP_DEBUG_TRACE,
|
|
|
ebc913e |
"delete (deleting %s) failed, err=%d %s\n",
|
|
|
ebc913e |
@@ -703,18 +709,33 @@ ldbm_back_delete( Slapi_PBlock *pb )
|
|
|
ebc913e |
goto error_return;
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
- entryrdn_index_entry(be, e, BE_INDEX_DEL, &txn);
|
|
|
ebc913e |
- retval =
|
|
|
ebc913e |
- entryrdn_index_entry(be, tombstone, BE_INDEX_ADD, &txn);
|
|
|
ebc913e |
+ retval = entryrdn_index_entry(be, e, BE_INDEX_DEL, &txn);
|
|
|
ebc913e |
+ if (DB_LOCK_DEADLOCK == retval) {
|
|
|
ebc913e |
+ LDAPDebug0Args( LDAP_DEBUG_ARGS,
|
|
|
ebc913e |
+ "delete (deleting entryrdn) DB_LOCK_DEADLOCK\n");
|
|
|
ebc913e |
+ /* Retry txn */
|
|
|
ebc913e |
+ continue;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
+ if (0 != retval) {
|
|
|
ebc913e |
+ LDAPDebug2Args( LDAP_DEBUG_TRACE,
|
|
|
ebc913e |
+ "delete (deleting entryrdn) failed, err=%d %s\n",
|
|
|
ebc913e |
+ retval,
|
|
|
ebc913e |
+ (msg = dblayer_strerror( retval )) ? msg : "" );
|
|
|
ebc913e |
+ if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
|
|
|
ebc913e |
+ DEL_SET_ERROR(ldap_result_code,
|
|
|
ebc913e |
+ LDAP_OPERATIONS_ERROR, retry_count);
|
|
|
ebc913e |
+ goto error_return;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
+ retval = entryrdn_index_entry(be, tombstone, BE_INDEX_ADD, &txn);
|
|
|
ebc913e |
if (DB_LOCK_DEADLOCK == retval) {
|
|
|
ebc913e |
LDAPDebug0Args( LDAP_DEBUG_ARGS,
|
|
|
ebc913e |
- "delete (adding entryrdn) DB_LOCK_DEADLOCK\n");
|
|
|
ebc913e |
+ "adding (adding tombstone entryrdn) DB_LOCK_DEADLOCK\n");
|
|
|
ebc913e |
/* Retry txn */
|
|
|
ebc913e |
continue;
|
|
|
ebc913e |
}
|
|
|
ebc913e |
if (0 != retval) {
|
|
|
ebc913e |
LDAPDebug2Args( LDAP_DEBUG_TRACE,
|
|
|
ebc913e |
- "delete (adding entryrdn) failed, err=%d %s\n",
|
|
|
ebc913e |
+ "adding (adding tombstone entryrdn) failed, err=%d %s\n",
|
|
|
ebc913e |
retval,
|
|
|
ebc913e |
(msg = dblayer_strerror( retval )) ? msg : "" );
|
|
|
ebc913e |
if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1;
|
|
|
ebc913e |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
|
|
ebc913e |
index 2a7b1e4..4eba4ed 100644
|
|
|
ebc913e |
--- a/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
|
|
ebc913e |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_entryrdn.c
|
|
|
ebc913e |
@@ -280,9 +280,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
"entryrdn_index_entry: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
- dblayer_strerror(rc), rc);
|
|
|
ebc913e |
+ dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
if (db) {
|
|
|
ebc913e |
@@ -388,9 +394,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
- "entryrdn_index_read: Failed to close cursor: "
|
|
|
ebc913e |
- "%s(%d)\n", dblayer_strerror(rc), rc);
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ "entryrdn_index_read: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
+ dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
if (db) {
|
|
|
ebc913e |
@@ -841,9 +853,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
"entryrdn_rename_subtree: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
- dblayer_strerror(rc), rc);
|
|
|
ebc913e |
+ dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
if (db) {
|
|
|
ebc913e |
@@ -983,9 +1001,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
"entryrdn_get_subordinates: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
- dblayer_strerror(rc), rc);
|
|
|
ebc913e |
+ dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
if (db) {
|
|
|
ebc913e |
@@ -1147,9 +1171,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
"entryrdn_lookup_dn: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
/* it is guaranteed that db is not NULL. */
|
|
|
ebc913e |
@@ -1294,9 +1324,15 @@ bail:
|
|
|
ebc913e |
if (cursor) {
|
|
|
ebc913e |
int myrc = cursor->c_close(cursor);
|
|
|
ebc913e |
if (0 != myrc) {
|
|
|
ebc913e |
- slapi_log_error(SLAPI_LOG_FATAL, ENTRYRDN_TAG,
|
|
|
ebc913e |
+ int loglevel = (myrc == DB_LOCK_DEADLOCK) ? SLAPI_LOG_TRACE : SLAPI_LOG_FATAL;
|
|
|
ebc913e |
+ slapi_log_error(loglevel, ENTRYRDN_TAG,
|
|
|
ebc913e |
"entryrdn_get_parent: Failed to close cursor: %s(%d)\n",
|
|
|
ebc913e |
- dblayer_strerror(rc), rc);
|
|
|
ebc913e |
+ dblayer_strerror(myrc), myrc);
|
|
|
ebc913e |
+ if (!rc) {
|
|
|
ebc913e |
+ /* if cursor close returns DEADLOCK, we must bubble that up
|
|
|
ebc913e |
+ to the higher layers for retries */
|
|
|
ebc913e |
+ rc = myrc;
|
|
|
ebc913e |
+ }
|
|
|
ebc913e |
}
|
|
|
ebc913e |
}
|
|
|
ebc913e |
/* it is guaranteed that db is not NULL. */
|
|
|
ebc913e |
--
|
|
|
ebc913e |
1.7.1
|
|
|
ebc913e |
|