Issue 39 - Cache corruption caused by delete
Summary: Cache corruption caused by delete
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 1999-01-12 14:53 UTC by rwroth@netdox.com
Modified: 2014-08-01 21:06 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description rwroth@netdox.com 1999-01-12 14:53:12 UTC
Full_Name: Robert Rothlisberger
Version: 1.1.2
OS: SunOS 2.5.1
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (208.220.157.29)


#
# slapd ldbm cache problem.
#
# This script will cause slapd to hang in a loop
# after deleting the one entry.
#
# To cause the hanging loop you have to decrease the cache
# size to 5 in slapd/back-ldbm/back-ldbm.h
# sinze th loop is caused only when the system tries to free up
# the corrupted cache entry that was caused by the delete.
#
# The problem is that the cache is sorted by using the dn's
# however some dn's are normalized and others are not.
# Using the data below the cache is not built in
# normalized dn order, it's built based on the dn's
# used by the calling routine. ldapsearch populates the
# cache with non-normalized dn's, but delete search based on the
# cache being sorted based on a normalized dn.  So if the
# cache is out of order based on the noramlized dn the delete
# fails to remove the item from the cache. (id2entry.c)
# This corrupts the cache so that latter when the cache has reached
# max size and the corrupted entry is tring to be cleared.
# an infinite loop is encountered (back-ldbm/cache.c)

#		 /*
#       * found at least one to delete - try to get back under
#       * the max cache size.
#       */
#      while ( cache->c_lrutail != NULL && cache->c_lrutail->e_refcnt
#                    == 0 && cache->c_cursize > cache->c_maxsize ) {
#
#         e = cache->c_lrutail;
#
#         /* XXX check for writer lock - should also check no readers pending
*/
##ifdef LDAP_DEBUG
#         assert(!pthread_rdwr_rwchk_np(&e->e_rdwr));
##endif
#         /* delete from cache and lru q */
#
#			// This code fails, on the corrupted entry. RWR
#         rc = cache_delete_entry_internal( cache, e );
#
#			// Since the above fails the conditions for this loop
#			// this will be done until crash
#         entry_free( e );
#
#      }

#
# Fixes
#   The easiest way for me was to add:
#		dn_normalize( e->e_dn );
#	at the start of cache_add_entry_lock() (back-ldbm/cache.c)
#
#  The problem with this is that all dn  entries in the database
#	will be stored in normalized form.  ( not really a problem at least for
#	me).  But ldif2ldbm should also reflect this since any existing
#	dn's need to be changed.
#
#
#  Anyways, if you run the script below it will cause the error.
#  The last search is commented out since it will loop slapd,
#  but if you search the err file you will see the could not delete from
#  cache entry.
#


cat > testdata <<!
dn: c=US
objectclass: country
c: US

dn: o=Cache Test1,c=Us
objectclass: organization
o: Cache Test1

dn: o=Cache Test2,c=Us
objectclass: organization
o: Cache Test2

dn: o=Cache Test3, c=Us
objectclass: organization
o: Cache Test3

dn: cn=CacheTest,o=Cache Test1,c=US
cn: CacheTest
sn: CacheTest
o: Cache Test1

dn: cn=CacheTest,o=Cache Test2,c=US
cn: CacheTest
sn: CacheTest
o: Cache Test2

dn: cn=CacheTest, o=Cache Test3, c=US
cn: CacheTest
sn: CacheTest
o: Cache Test3

dn: cn=CacheTesta, o=Cache Test3, c=US
cn: CacheTest
sn: CacheTest
o: Cache Test3
!

ldif2ldbm -i testdata -f slapd.conf

./slapd -d129 -f slapd.conf 2>err &

ldapsearch "cn=Ca*"

# This delete will cause slapd to generate a could not delete from cache
# error.
ldapdelete -D cn=xyzzy -w password "cn=CacheTest, o=Cache Test3, c=US"



# Warning on my system this search will cause slapd to hang
# in a loop generating a large err file.
# I had to kill it with a kill -9
# ldapsearch "cn=Ca*"

Comment 1 Kurt Zeilenga 1999-01-12 20:00:49 UTC
changed notes
changed state Open to Feedback
moved from Incoming to Software
Comment 2 Kurt Zeilenga 1999-01-13 00:16:29 UTC
I made the following commit to -devel which may resolve this
and related delete/search issues.

At 12:17 AM 1/13/99 GMT, kurt@OpenLDAP.org wrote:
>Update of /repo/OpenLDAP/pkg/ldap/servers/slapd/back-ldbm
>
>Modified Files:
>	cache.c 	1.7 -> 1.8
>

>Update of /repo/OpenLDAP/pkg/ldap/servers/slapd
>
>Modified Files:
>	add.c 	1.11 -> 1.12
>	entry.c 	1.8 -> 1.9
>	monitor.c 	1.11 -> 1.12
>	slap.h 	1.17 -> 1.18

>Update of /repo/OpenLDAP/pkg/ldap/servers/slapd/back-passwd
>
>Modified Files:
>	search.c 	1.5 -> 1.6
>

>Log Message:
>Add normalized dn to Entry structure as field e_ndn.  Entry
>creation codes to provide this field.  Update cache_entrydn_cmp
>to strcasecmp() the e_ndn instead of e_dn.  Note: strcasecmp()
>is still used as e_ndn isn't in uppercase.  Maybe it should
>be.  Did not update other codes to use e_ndn.  Hence, there
>are lots of dn_normalize() calls that could be eliminated.
>(The case determination of e_ndn should be made first).


Comment 3 Kurt Zeilenga 1999-01-13 17:55:29 UTC
moved from Software to Software Bugs
Comment 4 Kurt Zeilenga 1999-01-14 20:41:04 UTC
I've committed changes to OPENLDAP_REL_ENG_1_1 branch that may
have an impact on this issue.  The version is only available
via AnonCVS.  Would appreciate any testing you might be able to
accomplish.
Comment 5 Kurt Zeilenga 1999-01-14 20:41:33 UTC
changed notes
Comment 6 Kurt Zeilenga 1999-01-14 20:43:47 UTC
changed notes
changed state Feedback to Test
Comment 7 Kurt Zeilenga 1999-01-18 17:47:48 UTC
changed notes
Comment 8 Kurt Zeilenga 1999-01-20 06:18:08 UTC
changed notes
changed state Test to Release
Comment 9 Kurt Zeilenga 1999-01-21 18:27:40 UTC
changed notes
changed state Release to Closed
Comment 10 OpenLDAP project 2014-08-01 21:06:51 UTC
Investigating.
Fix applied to -devel and rel_eng_1_1.