[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.