We also have a patch for the stable version should anybody be interested in it.
-----
# This patch file is derived from OpenLDAP Software. All of the modifications to OpenLDAP Software # represented in the following patch(es) were developed by Stelios Grigoriadis stelios.xx.grigoriadis@ericsson.com. # These modifications are not subject to any license of Ericsson AB.
# I, Stelios Grigoriadis, hereby place the following modifications to OpenLDAP Software (and only these modifications) # into the public domain. Hence, these modifications may be freely used and/or redistributed for any purpose with or # without attribution and/or other notice.
# Bug Fix - This patch fixes the bug ITS#5133. # The fix works as follows. A periodic check in the runqueue (called do_mastercheck). The intervall is determined by # a slapd.conf parameter (mastercheckint) in the syncrepl section and is optional. If it's not specified, it's not # inserted in the runqueue.
--- servers/slapd/syncrepl.c 2007-10-05 10:36:13.000000000 +0200 +++ syncrepl.c 2008-05-13 14:27:09.000000000 +0200 @@ -78,6 +78,7 @@ int si_manageDSAit; int si_slimit; int si_tlimit; + int si_mastercheck_int; int si_refreshDelete; int si_refreshPresent; int si_syncdata; @@ -89,6 +90,9 @@ ldap_pvt_thread_mutex_t si_mutex; } syncinfo_t;
+/* Necessary in order to use asynchronous searches in mastercheck */ +static ber_int_t ps_msgid; + static int syncuuid_cmp( const void *, const void * ); static void avl_ber_bvfree( void * ); static void syncrepl_del_nonpresent( Operation *, syncinfo_t *, BerVarray, struct berval * ); @@ -314,7 +318,6 @@ BerElement *ber = (BerElement *)&berbuf; LDAPControl c[2], *ctrls[3]; struct timeval timeout; - ber_int_t msgid; int rc; int rhint; char *base; @@ -402,7 +405,7 @@
rc = ldap_search_ext( si->si_ld, base, scope, filter, attrs, attrsonly, ctrls, NULL, si->si_tlimit > 0 ? &timeout : NULL, - si->si_slimit, &msgid ); + si->si_slimit, &ps_msgid ); ber_free_buf( ber ); return rc; } @@ -667,7 +670,7 @@ tout_p = NULL; }
- while (( rc = ldap_result( si->si_ld, LDAP_RES_ANY, LDAP_MSG_ONE, + while (( rc = ldap_result( si->si_ld, ps_msgid, LDAP_MSG_ONE, tout_p, &res )) > 0 ) { if ( slapd_shutdown ) { @@ -2769,6 +2772,7 @@ #define OLDAUTHCSTR "bindprincipal" #define EXATTRSSTR "exattrs" #define MANAGEDSAITSTR "manageDSAit" +#define MASTERCHECKINTSTR "mastercheckint"
/* FIXME: unused */ #define LASTMODSTR "lastmod" @@ -3198,6 +3202,17 @@ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 ); return 1; } + } else if ( !strncasecmp( c->argv[ i ], MASTERCHECKINTSTR "=", + STRLENOF( MASTERCHECKINTSTR "=" ) ) ) + { + val = c->argv[ i ] + STRLENOF( MASTERCHECKINTSTR "=" ); + if ( lutil_atoi( &si->si_mastercheck_int, val ) != 0 || si->si_mastercheck_int < 0 ) { + snprintf( c->msg, sizeof( c->msg ), + "invalid master check interval value "%s".\n", + val ); + Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 ); + return 1; + } } else if ( !strncasecmp( c->argv[ i ], SYNCDATASTR "=", STRLENOF( SYNCDATASTR "=" ) ) ) { @@ -3273,6 +3288,7 @@ si->si_tlimit = 0; si->si_slimit = 0; si->si_conn_setup = 0; + si->si_mastercheck_int = 0;
si->si_presentlist = NULL; LDAP_LIST_INIT( &si->si_nonpresentlist ); @@ -3435,6 +3451,68 @@ ber_dupbv( bv, &bc ); }
+static void * +do_mastercheck( + void *ctx, + void *arg ) +{ + struct re_s* rtask = arg; + syncinfo_t *si = ( syncinfo_t * ) rtask->arg; + int rc; + char *search_attrs[] = { NULL }; + LDAPMessage *res = 0; + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + static int mc_msg=-1; + + ldap_pvt_thread_mutex_lock( &si->si_mutex ); + if (si->si_ld) { + if (mc_msg != -1) { + res=0; + ldap_result(si->si_ld, mc_msg, 1, &timeout, &res); + if (res) { ldap_msgfree(res);} + if (rc != LDAP_SUCCESS) { + ldap_abandon_ext(si->si_ld, mc_msg, NULL, NULL); + } + } + mc_msg=-1; + rc=ldap_search_ext(si->si_ld, "", LDAP_SCOPE_BASE, "(objectClass=*)", search_attrs, + 0, NULL, NULL, NULL, 0, &mc_msg); + if (rc != LDAP_SUCCESS) { + Debug(LDAP_DEBUG_ANY,"Failed to send\n",0,0,0); + } + } + + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); + + if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) { + ldap_pvt_runqueue_stoptask( &slapd_rq, rtask ); + } + + rtask->interval.tv_sec = si->si_mastercheck_int; + ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 ); + + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + + ldap_pvt_thread_mutex_unlock( &si->si_mutex ); +} + +static int add_mastercheck( ConfigArgs *c ) { + int rc; + syncinfo_t *si = c->be->be_syncinfo; + + if ( si->si_mastercheck_int == 0 ) + return 0; + + rc = ldap_pvt_runqueue_insert( &slapd_rq, si->si_mastercheck_int * 60, + do_mastercheck, si, "do_mastercheck", c->be->be_suffix[0].bv_val ); + if (rc < 0) + Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 ); + + return rc; +} + int syncrepl_config( ConfigArgs *c ) { @@ -3470,5 +3548,6 @@ } else if ( add_syncrepl( c ) ) { return(1); } + add_mastercheck( c ); return config_sync_shadow( c ); }