From: Howard Chu Date: Wed, 1 Jun 2011 18:29:39 +0000 (-0700) Subject: More for ITS#6961 - deadlock checking X-Git-Tag: OPENLDAP_REL_ENG_2_5_0ALPHA~1371 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce9bbd2;p=thirdparty%2Fopenldap.git More for ITS#6961 - deadlock checking --- diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index b152c2b296..cc41b963e1 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -313,7 +313,7 @@ sameido: /* Get the next ID from the DB. Used if the candidate list is * a range and simple iteration hits missing entryIDs */ -static ID +static int bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor) { DBC *curs; @@ -326,7 +326,7 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor) rc = bdb->bi_id2entry->bdi_db->cursor( bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags ); if ( rc ) - return NOID; + return rc; key.data = &nid; key.size = key.ulen = sizeof(ID); key.flags = DB_DBT_USERMEM; @@ -335,9 +335,8 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor) rc = curs->c_get( curs, &key, &data, DB_SET_RANGE ); curs->c_close( curs ); if ( rc ) - return NOID; + return rc; BDB_DISK2ID( &nid, cursor ); - return *cursor; } int @@ -747,6 +746,7 @@ fetch_entry_retry: ltid->flags &= ~TXN_DEADLOCK; goto fetch_entry_retry; } +txnfail: opinfo->boi_err = rs->sr_err; send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" ); goto done; @@ -775,8 +775,25 @@ fetch_entry_retry: (long) id, 0, 0 ); } else { /* get the next ID from the DB */ - id = bdb_get_nextid( bdb, ltid, &cursor ); - cursor = id - 1; +id_retry: + rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor ); + if ( rs->sr_err == DB_NOTFOUND ) { + break; + } else if ( rs->sr_err == DB_LOCK_DEADLOCK ) { + if ( opinfo ) + goto txnfail; + ltid->flags &= ~TXN_DEADLOCK; + goto id_retry; + } else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) { + goto id_retry; + } + if ( rs->sr_err ) { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "internal error in get_nextid"; + send_ldap_result( op, rs ); + goto done; + } + cursor--; } goto loop_continue;