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

Re: (ITS#5133) Synchronous replication on slave doesn't notice lost network connection



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 );
 }