[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
(ITS#3596) PATCH for openldap-2.3.1alpha: fix slapd hangs problem under syncrepl
Full_Name: wayne zhao
Version: 2.3.1alpha
OS: Linux 2.6.8-1-386
URL: ftp://ftp.openldap.org/incoming/wayne-050312.patch
Submission from: (NULL) (220.249.10.10)
I am not familiar with openldap source, and I hope I describle the problem &
my patch clearly, ;)
Problem:
I use openldap-2.3.1alpha on two machines, one as master provider and the
other as syncrepl consumer. The syncrepl type is refreshAndPersist. The provider
slapd runs at ldap://192.168.0.218:9014/. The db backend is bdb.
When the connection between the consumer and provider was established, I tried
to use ldappasswd to modify one user's password. But ldappasswd hungs with no
response. And the slapd process on the provider used 100% CPU.
Cause:
I read through the code and found that one thread of slapd looped at
servers/slapd/overlays/syncprov.c:line 1467-1471, in function syncprov_op_mod(),
which made the slapd service unavailible.
mt = avl_find( si->si_mods, &mtdummy, sp_avl_cmp );
if ( mt ) {
ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
ldap_pvt_thread_mutex_unlock( &si->si_mods_mutex );
mt->mt_tail->mi_next = mi;
mt->mt_tail = mi;
/* wait for this op to get to head of list */
line 1467: while ( mt->mt_mods != mi ) {
ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
ldap_pvt_thread_yield();
ldap_pvt_thread_mutex_lock( &mt->mt_mutex );
line 1471: }
ldap_pvt_thread_mutex_unlock( &mt->mt_mutex );
} else {
The problem exists in over_op_func() in servers/slapd/backover.c, called from
passwd_extop() in servers/slapd/passwd.c:line 163. When the operation is
ldappassword, backend extensions were given a chance to handle the operation
themself. But bdb backend doesn't handle passwd modification, so passwd_extop()
will finally do it. In this procedure, syncprov_op_mod() was called twice, one
by over_op_func(), and one by passwd_extop():line 221, the following line:
rs->sr_err = op2.o_bd->be_modify( &op2, rs );
So, in two calls of syncprov_op_mod(), two 'mi' were appended to si->si_mods,
which caused the second time to loop at line 1467-1471 in
servers/slapd/overlays/syncprov.c.
The 'mi' added the first time should be cleanup because the callback function
-- syncprov_op_cleanup() -- were never called. The reason is in over_op_func()
in servers/slapd/backover.c.
cb.sc_next = op->o_callback;
cb.sc_private = oi;
op->o_callback = &cb;
for (; on; on=on->on_next ) {
func = &on->on_bi.bi_op_bind;
if ( func[which] ) {
op->o_bd->bd_info = (BackendInfo *)on;
rc = func[which]( op, rs );
if ( rc != SLAP_CB_CONTINUE ) break;
}
}
NOTICE: at this point, op->o_callback = syncprov_op_cleanup.
func = &oi->oi_orig->bi_op_bind;
if ( func[which] && rc == SLAP_CB_CONTINUE ) {
op->o_bd->bd_info = oi->oi_orig;
rc = func[which]( op, rs );
}
/* should not fall thru this far without anything happening... */
if ( rc == SLAP_CB_CONTINUE ) {
rc = op_rc[ which ];
}
op->o_bd = be;
op->o_callback = cb.sc_next;
NOTICE: syncprov_op_cleanup was gone here!!!!!
----------------------------------------------------------------
slapd.conf on the provider side:
include /usr/local/etc/openldap/schema/core.schema
loglevel 261
pidfile ./var/slapd.pid
argsfile ./var/slapd.args
database bdb
suffix "dc=example,dc=com"
rootdn "cn=admin,dc=example,dc=com"
rootpw secret
directory ./db
index objectClass eq
overlay syncprov
----------------------------------------------------------------
slapd.conf on the provider side:
include /usr/local/etc/openldap/schema/core.schema
pidfile /var/slapd-agent.pid
argsfile /var/slapd-agent.args
database bdb
suffix "dc=example,dc=com"
rootdn "cn=replica,dc=example,dc=com"
rootpw secret
directory /var/ldap
syncrepl rid=1
provider=ldap://192.168.0.218:9014
bindmethod=simple
binddn="cn=admin,dc=example,dc=com"
credentials=secret
searchbase="dc=example,dc=com"
filter="(objectClass=*)"
attrs="*"
schemachecking=off
scope=sub
type=refreshAndPersist
retry=10,+
updateref "ldap://192.168.0.218:9014/"
overlay syncprov
----------------------------------------------------------------
ldappasswd command line:
# ldappasswd -x -w secret -H ldap://192.168.0.218:9014/ -D
'cn=admin,dc=example,dc=com' 'uid=test,dc=example,dc=com' -s 123456
----------------------------------------------------------------
openldap-2.3.1alpha build command:
./configure
make depend
make
make install
----------------------------------------------------------------
The bdb I am using is db-4.3.27.