[Fedora-directory-commits] ldapserver/ldap/servers/slapd/back-ldbm proto-back-ldbm.h, 1.5, 1.5.2.1 idl.c, 1.4, 1.4.2.1 sort.c, 1.5.2.1, 1.5.2.2 vlv.c, 1.6.2.1, 1.6.2.2
Noriko Hosoi (nhosoi)
fedora-directory-commits at redhat.com
Thu Jan 10 19:44:23 UTC 2008
Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv14329/servers/slapd/back-ldbm
Modified Files:
Tag: Directory71RtmBranch
proto-back-ldbm.h idl.c sort.c vlv.c
Log Message:
Resolves: #183222
Summary: Directory Server hangs when running VLV search and update operations
Description: applied the patch to Directory71RtmBranch
Index: proto-back-ldbm.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
--- proto-back-ldbm.h 19 Apr 2005 22:07:38 -0000 1.5
+++ proto-back-ldbm.h 10 Jan 2008 19:44:21 -0000 1.5.2.1
@@ -213,6 +213,15 @@
int idl_is_allids(IDList *idl);
int idl_append( IDList *idl, ID id);
void idl_insert(IDList **idl, ID id);
+/*
+ * idl_delete - delete an id from an id list.
+ * returns 0 id deleted
+ * 1 id deleted, first id in block has changed
+ * 2 id deleted, block is empty
+ * 3 id not there
+ * 4 cannot delete from allids block
+ */
+int idl_delete( IDList **idl, ID id );
IDList * idl_allids( backend *be );
IDList * idl_fetch( backend *be, DB* db, DBT *key, DB_TXN *txn, struct attrinfo *a, int *err );
int idl_insert_key( backend *be, DB* db, DBT *key, ID id, DB_TXN *txn, struct attrinfo *a,int *disposition );
Index: idl.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/idl.c,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -r1.4 -r1.4.2.1
--- idl.c 19 Apr 2005 22:07:38 -0000 1.4
+++ idl.c 10 Jan 2008 19:44:21 -0000 1.4.2.1
@@ -44,7 +44,6 @@
*/
#undef IDL_LOCKING_ENABLE
-static int idl_delete( IDList **idl, ID id ) ;
static void make_cont_key( DBT *contkey, DBT *key, ID id );
static int idl_insert_maxids( IDList **idl, ID id, int maxids );
@@ -1591,7 +1590,7 @@
* 4 cannot delete from allids block
*/
-static int
+int
idl_delete( IDList **idl, ID id )
{
ID i, delpos;
Index: sort.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/sort.c,v
retrieving revision 1.5.2.1
retrieving revision 1.5.2.2
diff -u -r1.5.2.1 -r1.5.2.2
--- sort.c 2 Mar 2006 01:12:31 -0000 1.5.2.1
+++ sort.c 10 Jan 2008 19:44:21 -0000 1.5.2.2
@@ -677,7 +677,7 @@
a = id2entry(be,*id_a,NULL,&err);
if (NULL == a) {
if (0 != err ) {
- LDAPDebug(LDAP_DEBUG_ANY,"compare_entries db err %d\n",err,0,0);
+ LDAPDebug(LDAP_DEBUG_TRACE,"compare_entries db err %d\n",err,0,0);
}
/* Were up a creek without paddle here */
/* Best to log error and set some flag */
@@ -686,7 +686,7 @@
b = id2entry(be,*id_b,NULL,&err);
if (NULL == b) {
if (0 != err ) {
- LDAPDebug(LDAP_DEBUG_ANY,"compare_entries db err %d\n",err,0,0);
+ LDAPDebug(LDAP_DEBUG_TRACE,"compare_entries db err %d\n",err,0,0);
}
return 0;
}
Index: vlv.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/vlv.c,v
retrieving revision 1.6.2.1
retrieving revision 1.6.2.2
diff -u -r1.6.2.1 -r1.6.2.2
--- vlv.c 14 Mar 2007 16:25:34 -0000 1.6.2.1
+++ vlv.c 10 Jan 2008 19:44:21 -0000 1.6.2.2
@@ -54,7 +54,7 @@
static PRUint32 vlv_trim_candidates_byindex(PRUint32 length, const struct vlv_request *vlv_request_control);
static PRUint32 vlv_trim_candidates_byvalue(backend *be, const IDList *candidates, const sort_spec* sort_control, const struct vlv_request *vlv_request_control);
-static int vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control);
+static int vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked);
/* New mutex for vlv locking
PRRWLock * vlvSearchList_lock=NULL;
@@ -72,6 +72,7 @@
backend *be = inst->inst_be;
vlvSearch_init(newVlvSearch, pb, entryBefore, inst);
+ /* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
vlvSearch_addtolist(newVlvSearch, (struct vlvSearch **)&be->vlvSearchList);
PR_RWLock_Unlock(be->vlvSearchList_lock);
@@ -81,24 +82,25 @@
/* Callback to add a new VLV Index specification. Added write lock.*/
int vlv_AddIndexEntry(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg)
-{
- struct vlvSearch *parent;
- backend *be= ((ldbm_instance*)arg)->inst_be;
- Slapi_DN parentdn;
-
- slapi_sdn_init(&parentdn);
- slapi_sdn_get_parent(slapi_entry_get_sdn(entryBefore),&parentdn);
+{
+ struct vlvSearch *parent;
+ backend *be= ((ldbm_instance*)arg)->inst_be;
+ Slapi_DN parentdn;
+
+ slapi_sdn_init(&parentdn);
+ slapi_sdn_get_parent(slapi_entry_get_sdn(entryBefore),&parentdn);
{
- PR_RWLock_Wlock(be->vlvSearchList_lock);
+ /* vlvSearchList is modified; need Wlock */
+ PR_RWLock_Wlock(be->vlvSearchList_lock);
parent= vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, &parentdn);
if(parent!=NULL)
{
struct vlvIndex* newVlvIndex= vlvIndex_new();
- newVlvIndex->vlv_be=be;
+ newVlvIndex->vlv_be=be;
vlvIndex_init(newVlvIndex, be, parent, entryBefore);
- vlvSearch_addIndex(parent, newVlvIndex);
+ vlvSearch_addIndex(parent, newVlvIndex);
}
- PR_RWLock_Unlock(be->vlvSearchList_lock);
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
}
slapi_sdn_done(&parentdn);
return SLAPI_DSE_CALLBACK_OK;
@@ -111,6 +113,7 @@
struct vlvSearch* p=NULL;
backend *be= ((ldbm_instance*)arg)->inst_be;
+ /* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
p = vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, slapi_entry_get_sdn(entryBefore));
if(p!=NULL)
@@ -320,6 +323,7 @@
{
struct vlvSearch *t = NULL;
struct vlvSearch *nt = NULL;
+ /* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
for (t = (struct vlvSearch *)be->vlvSearchList; NULL != t; )
{
@@ -762,7 +766,7 @@
*
* JCM: If only non-sorted attributes are changed, then the indexes don't need updating.
* JCM: Detecting this fact, given multi-valued atribibutes, might be tricky...
- * Added write lock
+ * Read lock (traverse vlvSearchList; no change on vlvSearchList/vlvIndex lists)
*/
int
@@ -772,7 +776,7 @@
struct vlvSearch* ps=NULL;
struct ldbminfo *li = ((ldbm_instance *)be->be_instance_info)->inst_li;
- PR_RWLock_Wlock(be->vlvSearchList_lock);
+ PR_RWLock_Rlock(be->vlvSearchList_lock);
ps = (struct vlvSearch *)be->vlvSearchList;
for(;ps!=NULL;ps= ps->vlv_next)
{
@@ -1059,15 +1063,16 @@
PR_RWLock_Rlock(be->vlvSearchList_lock);
if((pi=vlv_find_search(be, base, scope, fstr, sort_control)) == NULL) {
unsigned int opnote = SLAPI_OP_NOTE_UNINDEXED;
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote );
rc = VLV_FIND_SEARCH_FAILED;
} else if((*vlv_rc=vlvIndex_accessallowed(pi, pb)) != LDAP_SUCCESS) {
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
rc = VLV_ACCESS_DENIED;
- } else if ((*vlv_rc=vlv_build_candidate_list(be,pi,vlv_request_control,candidates,vlv_response_control)) != LDAP_SUCCESS) {
+ } else if ((*vlv_rc=vlv_build_candidate_list(be,pi,vlv_request_control,candidates,vlv_response_control, 1)) != LDAP_SUCCESS) {
rc = VLV_BLD_LIST_FAILED;
vlv_response_control->result=*vlv_rc;
}
- PR_RWLock_Unlock(be->vlvSearchList_lock);
return rc;
}
@@ -1087,7 +1092,7 @@
static int
-vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control)
+vlv_build_candidate_list( backend *be, struct vlvIndex* p, const struct vlv_request *vlv_request_control, IDList** candidates, struct vlv_response *vlv_response_control, int is_srchlist_locked)
{
int return_value = LDAP_SUCCESS;
DB *db = NULL;
@@ -1102,6 +1107,9 @@
slapi_sdn_get_dn(vlvIndex_getBase(p)), p->vlv_search->vlv_filter,
vlvIndex_getName(p));
if (!vlvIndex_online(p)) {
+ if (is_srchlist_locked) {
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ }
return -1;
}
rc = dblayer_get_index_file(be, p->vlv_attrinfo, &db, 0);
@@ -1109,9 +1117,20 @@
/* shouldn't happen */
LDAPDebug(LDAP_DEBUG_ANY, "VLV: can't get index file '%s' (err %d)\n",
p->vlv_attrinfo->ai_type, rc, 0);
+ if (is_srchlist_locked) {
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ }
return -1;
}
+ length = vlvIndex_get_indexlength(p, db, 0 /* txn */);
+
+ /* Increment the usage counter */
+ vlvIndex_incrementUsage(p);
+
+ if (is_srchlist_locked) {
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
+ }
err = db->cursor(db, 0 /* txn */, &dbc, 0);
if (err != 0) {
/* shouldn't happen */
@@ -1120,11 +1139,6 @@
return -1;
}
- length = vlvIndex_get_indexlength(p, db, 0 /* txn */);
-
- /* Increment the usage counter */
- vlvIndex_incrementUsage(p);
-
if (vlv_request_control)
{
switch(vlv_request_control->tag) {
@@ -1454,9 +1468,17 @@
typedown_value= vlv_create_matching_rule_value(sort_control->mr_pb,(struct berval *)&vlv_request_control->value);
compare_fn= slapi_berval_cmp;
}
+retry:
/*
* Perform a binary search over the candidate list
*/
+ if (0 == candidates->b_nids) { /* idlist is empty */
+ LDAPDebug( LDAP_DEBUG_ANY, "vlv_trim_candidates_byvalue: Candidate ID List is empty.\n", 0, 0, 0 );
+ ber_bvecfree((struct berval**)typedown_value);
+ return candidates->b_nids; /* not found */
+ }
+ low= 0;
+ high= candidates->b_nids-1;
do {
int err= 0;
struct backentry *e= NULL;
@@ -1472,7 +1494,15 @@
e = id2entry( be, id, NULL, &err );
if ( e == NULL )
{
+ int rval;
LDAPDebug( LDAP_DEBUG_ANY, "vlv_trim_candidates_byvalue: Candidate ID %lu not found err=%d\n", (u_long)id, err, 0 );
+ rval = idl_delete(&candidates, id);
+ if (0 == rval || 1 == rval || 2 == rval) {
+ goto retry;
+ } else {
+ ber_bvecfree((struct berval**)typedown_value);
+ return candidates->b_nids; /* not found */
+ }
}
else
{
@@ -1820,8 +1850,8 @@
IDList *idl;
Slapi_Filter *vlv_f;
- PR_RWLock_Rlock(be->vlvSearchList_lock);
slapi_sdn_init_dn_byref(&base_sdn, base);
+ PR_RWLock_Rlock(be->vlvSearchList_lock);
for (t = (struct vlvSearch *)be->vlvSearchList; t; t = t->vlv_next) {
/* all vlv "filters" start with (|(xxx)(objectclass=referral)).
* we only care about the (xxx) part.
@@ -1847,9 +1877,10 @@
}
if (dblayer_get_index_file(be, vi->vlv_attrinfo, &db, 0) == 0) {
+ length = vlvIndex_get_indexlength(vi, db, 0 /* txn */);
+ PR_RWLock_Unlock(be->vlvSearchList_lock);
err = db->cursor(db, 0 /* txn */, &dbc, 0);
if (err == 0) {
- length = vlvIndex_get_indexlength(vi, db, 0 /* txn */);
if (length == 0) /* 609377: index size could be 0 */
{
LDAPDebug(LDAP_DEBUG_TRACE, "vlv: index %s is empty\n",
@@ -1864,12 +1895,10 @@
}
dblayer_release_index_file(be, vi->vlv_attrinfo, db);
if (err == 0) {
- PR_RWLock_Unlock(be->vlvSearchList_lock);
return idl;
} else {
LDAPDebug(LDAP_DEBUG_ANY, "vlv find index: err %d\n",
err, 0, 0);
- PR_RWLock_Unlock(be->vlvSearchList_lock);
return NULL;
}
}
@@ -1927,6 +1956,7 @@
tag1=create_vlv_search_tag(dn);
buf=slapi_ch_smprintf("%s%s%s%s%s","cn=MCC ",tag1,", cn=",inst->inst_name,LDBM_PLUGIN_ROOT);
newdn=slapi_sdn_new_dn_byval(buf);
+ /* vlvSearchList is modified; need Wlock */
PR_RWLock_Wlock(be->vlvSearchList_lock);
p = vlvSearch_finddn((struct vlvSearch *)be->vlvSearchList, newdn);
if(p!=NULL)
More information about the Fedora-directory-commits
mailing list