[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