[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Openldap ldbm cache corruption
FYI, Same as previous just added the subject line (RWR)
> #
> # slapd ldbm cache problem. ITS#39
> #
> # 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*"