[389-ds-base/el5] Bug 808770 - [abrt] 389-ds-base-1.2.10.4-2.fc16: index_range_read_ext: Process /usr/sbin/ns-slapd wa

Richard Allen Megginson rmeggins at fedoraproject.org
Tue Apr 10 19:13:40 UTC 2012


commit ebc913e0646b2b99a9d1c585cef9ac60dfca478a
Author: Rich Megginson <rmeggins at redhat.com>
Date:   Tue Apr 10 13:10:44 2012 -0600

    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)
    
    - same as Ticket #336

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


More information about the scm-commits mailing list