]> git.sur5r.net Git - openldap/commitdiff
syncrepl retry-on-error code
authorJong Hyuk Choi <jongchoi@openldap.org>
Fri, 18 Jun 2004 05:04:03 +0000 (05:04 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Fri, 18 Jun 2004 05:04:03 +0000 (05:04 +0000)
libraries/libldap_r/rq.c
servers/slapd/config.c
servers/slapd/slap.h
servers/slapd/syncrepl.c

index b028054e33a17a75defa29715ef2e21b8c4301f2..194d16db8eda17e77969da03b883bbc064771bde 100644 (file)
@@ -66,12 +66,11 @@ ldap_pvt_runqueue_remove(
                        break;
        }
 
-       assert ( e == entry );
-
-       LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
+       if ( e == entry ) {
+               LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
+       }
 
        LDAP_FREE( entry );
-
 }
 
 struct re_s*
@@ -148,7 +147,7 @@ ldap_pvt_runqueue_resched(
 
        LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext );
 
-       if ( entry->interval.tv_sec && !defer ) {
+       if ( !defer ) {
                entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec;
        } else {
                entry->next_sched.tv_sec = 0;
index 7aceee21eb25fd94d5a8701df5cc7a506ad1bd6e..b91b0979dfa05dec53f6f03c17ae7981c756c0e0 100644 (file)
@@ -3028,6 +3028,9 @@ add_syncrepl(
        si->si_attrs[0] = NULL;
        si->si_type = LDAP_SYNC_REFRESH_ONLY;
        si->si_interval = 86400;
+       si->si_retryinterval = 0;
+       si->si_retrynum_init = 0;
+       si->si_retrynum = 0;
        si->si_syncCookie.ctxcsn = NULL;
        si->si_syncCookie.octet_str = NULL;
        si->si_syncCookie.sid = -1;
@@ -3144,6 +3147,8 @@ add_syncrepl(
 #define SLIMITSTR              "sizelimit"
 #define TLIMITSTR              "timelimit"
 
+#define RETRYSTR               "retry"
+
 #define GOT_ID                 0x0001
 #define GOT_PROVIDER   0x0002
 #define GOT_METHOD             0x0004
@@ -3383,6 +3388,53 @@ parse_syncrepl_line(
                                        (long) si->si_interval);
                                return 1;
                        }
+               } else if ( !strncasecmp( cargv[ i ],
+                       RETRYSTR, sizeof( RETRYSTR ) - 1 ) )
+               {
+                       char *str;
+                       char **retry_list;
+                       int j, k, n;
+
+                       val = cargv[ i ] + sizeof( RETRYSTR );
+                       retry_list = (char **) ch_calloc( 1, sizeof( char * ));
+                       retry_list[0] = NULL;
+
+                       str2clist( &retry_list, val, " ,\t" );
+
+                       for ( k = 0; retry_list && retry_list[k]; k++ ) ;
+                       n = k / 2;
+                       if ( k % 2 ) {
+                               fprintf( stderr,
+                                               "Error: incomplete syncrepl retry list\n" );
+                               for ( k = 0; retry_list && retry_list[k]; k++ ) {
+                                       ch_free( retry_list[k] );
+                               }
+                               ch_free( retry_list );
+                               exit( EXIT_FAILURE );
+                       }
+                       si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
+                       si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
+                       si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
+                       for ( j = 0; j < n; j++ ) {
+                               si->si_retryinterval[j] = atoi( retry_list[j*2] );
+                               if ( *retry_list[j*2+1] == '+' ) {
+                                       si->si_retrynum_init[j] = -1;
+                                       si->si_retrynum[j] = -1;
+                                       j++;
+                                       break;
+                               } else {
+                                       si->si_retrynum_init[j] = atoi( retry_list[j*2+1] );
+                                       si->si_retrynum[j] = atoi( retry_list[j*2+1] );
+                               }
+                       }
+                       si->si_retrynum_init[j] = -2;
+                       si->si_retrynum[j] = -2;
+                       si->si_retryinterval[j] = 0;
+                       
+                       for ( k = 0; retry_list && retry_list[k]; k++ ) {
+                               ch_free( retry_list[k] );
+                       }
+                       ch_free( retry_list );
                } else if ( !strncasecmp( cargv[ i ],
                        MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) )
                {
index 293c3cb79c84836cce6016c0d0c1e71f1b10c8df..e0330c07bbde4bb209657d9e697e2f39bcf2e91e 100644 (file)
@@ -1407,6 +1407,9 @@ typedef struct syncinfo_s {
         char                           **si_attrs;
         int                                    si_type;
         time_t                         si_interval;
+               time_t                          *si_retryinterval;
+               int                                     *si_retrynum_init;
+               int                                     *si_retrynum;
                struct sync_cookie      si_syncCookie;
         int                                    si_manageDSAit;
         int                                    si_slimit;
index 530963696356eae10c37646fb7d36022c35878ca..42a3456b89277a20bc615e3aab015c386778c043 100644 (file)
@@ -823,6 +823,7 @@ do_syncrepl(
        int first = 0;
        int dostop = 0;
        ber_socket_t s;
+       int i, defer = 1;
 
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 );
@@ -885,7 +886,7 @@ do_syncrepl(
                                                arg );
                                } else {
                                        connection_client_enable( s );
-                               }
+                               } 
                        } else if ( !first ) {
                                dostop = 1;
                        }
@@ -901,25 +902,45 @@ do_syncrepl(
         * 4) for Persist and Success, reschedule to defer
         */
        ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+
        if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
                ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
        }
 
-       if ( dostop ) {
-               connection_client_stop( s );
-       }
-
-       if ( rc && rc != LDAP_SERVER_DOWN ) {
-               ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+       if ( rc == LDAP_SUCCESS ) {
+               if ( dostop ) {
+                       connection_client_stop( s );
+               }
+               if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
+                       defer = 0;
+               }
+               rtask->interval.tv_sec = si->si_interval;
+               ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, defer );
+               if ( si->si_retrynum ) {
+                       for ( i = 0; si->si_retrynum_init[i] != -2; i++ ) {
+                               si->si_retrynum[i] = si->si_retrynum_init[i];
+                       }
+                       si->si_retrynum[i] = -2;
+               }
        } else {
-               if ( rc == LDAP_SERVER_DOWN ||
-                       si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
-                       rc = 0;
-               } else {
-                       rc = 1;
+               for ( i = 0; si->si_retrynum && si->si_retrynum[i] <= 0; i++ ) {
+                       if ( si->si_retrynum[i] == -1  || si->si_retrynum[i] == -2 )
+                               break;
+               }
+
+               if ( !si->si_retrynum || si->si_retrynum[i] == -2 ) {
+                       if ( dostop ) {
+                               connection_client_stop( s );
+                       }
+                       ldap_pvt_runqueue_remove( &syncrepl_rq, rtask );
+               } else if ( si->si_retrynum[i] >= -1 ) {
+                       if ( si->si_retrynum[i] > 0 )
+                               si->si_retrynum[i]--;
+                       rtask->interval.tv_sec = si->si_retryinterval[i];
+                       ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
                }
-               ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, rc );
        }
+       
        ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
 
        return NULL;