[Date Prev][Date Next] [Chronological] [Thread] [Top]

slapd lock deadlock



Hi,

	slapd 1.1.14

	I found a deadlock in the ldbm cache.

	When a writer activity is running it creates a writer lock
		id2entry -> entry_rdwr_loc()

	However the cache is only locked when it is accessed.

	The problem arrises when a call to cache_find_entry_id()
		tries to aquire a reader lock.
		entry_rdwr_lock() calls pthread_rdwr_rlock_np()
		this routine loops until the writer lock clears.

	The problem is that the writer can't complete because the search
locked
	the cache. So here we sit.


	Should the while loop in liblthread/rdwr.c
pthread_rdwr_rlock_np()
	be looping on  writer_writing or readers_reading?
	Currently it's waiting for the writer and that's not going to
happen.

	I don't think you can have the cache wait until the write clears
since
	the write needs to access the cache and would then be waiting on
itself.

	You can create this deadlock by running the script below. ( I
run 3 copies of it)

	Any suggestions?

	Bob Rothlisberger
	rwroth@netdox.com

#!/bin/ksh
cd /tmp

Passwd="password"

CN="AutoLdap Test"
tmp=$$.ldaptmp
dtmp=$$.ldapdeletes

Domain="cn=manager"

cnt=1
while [ 1 ]
do

	cnt=`expr $cnt + 1`
	
	today=`date +%Y%m%d`
	time=`date +%H%M%S`
	
	# Add a test entry to the primary server
	echo "\n${PServer}: Adding -> ${CN} date: ${today}${time}"
	
	ldapmodify -r -D ${Domain} -w ${Passwd} >/dev/null << _EOF_
dn: cn=${CN}, o=NetDox Ops, c=US
cn: ${CN}
date: ${today}${time}
objectclass: netdoxapp
status: test

_EOF_
	
	# Is our test entry in the primary server?
	x=`ldapsearch "cn=${CN}" date 2>/dev/null | grep
"${today}${time}"`
	if [ "z${x}" = "z" ]
	  then
		echo "WARNING Failed to update primary ldap server"
		echo "Fatal error"
		exit 1;
	fi
	if [ $Verbose -eq 0 ]
	  then
		echo "Add succesful"
	fi
	
	# Now Search for all Auto entries.
	# All hosts should match the primary ldap server.
	echo "Searching for all Auto entries"
	# Get Auto's
	ldapsearch "cn=${CN}" date  > ${dtmp}
	
	echo "Found"
	cat ${dtmp}
	rm -f $$.ldap*
	
	sleep 5
	
	echo $cnt

done