]> git.sur5r.net Git - openldap/commitdiff
Add strictrefresh syncrepl option
authorHoward Chu <hyc@openldap.org>
Fri, 15 Apr 2011 18:13:38 +0000 (11:13 -0700)
committerHoward Chu <hyc@openldap.org>
Fri, 15 Apr 2011 18:13:38 +0000 (11:13 -0700)
Only affects delta-syncrepl - stop listening to clients while
refresh is running.

servers/slapd/connection.c
servers/slapd/daemon.c
servers/slapd/proto-slap.h
servers/slapd/syncrepl.c

index 0d508ee7ef6eca1f66a66a5ad5c598025ff70d53..aea3b39191c1e919637861dd1a1cbacb70e1aa33 100644 (file)
@@ -225,6 +225,7 @@ int connections_timeout_idle(time_t now)
                 */
                if(( c->c_n_ops_executing && !c->c_writewaiter)
                        || c->c_conn_state == SLAP_C_CLIENT ) {
+                       connection_done( c );
                        continue;
                }
 
@@ -243,16 +244,40 @@ int connections_timeout_idle(time_t now)
                                connection_closing( c, "writetimeout" );
                                connection_close( c );
                                i++;
+                               continue;
                        }
                }
+               connection_done( c );
        }
-       connection_done( c );
        if ( old && !writers )
                slapd_clr_writetime( old );
 
        return i;
 }
 
+/* Drop all client connections */
+void connections_drop()
+{
+       Connection* c;
+       int connindex;
+
+       for( c = connection_first( &connindex );
+               c != NULL;
+               c = connection_next( c, &connindex ) )
+       {
+               /* Don't close a slow-running request or a persistent
+                * outbound connection.
+                */
+               if(( c->c_n_ops_executing && !c->c_writewaiter)
+                       || c->c_conn_state == SLAP_C_CLIENT ) {
+                       connection_done( c );
+                       continue;
+               }
+               connection_closing( c, "dropping" );
+               connection_close( c );
+       }
+}
+
 static Connection* connection_get( ber_socket_t s )
 {
        Connection *c;
index 21821aafdd6123be1e524672893c90501d247f21..8e8a69d560661b1c5b14c8bbd9e4a6cfdfbdd126 100644 (file)
@@ -3048,6 +3048,28 @@ slapd_get_listeners( void )
        return slap_listeners;
 }
 
+/* Reject all incoming requests */
+void
+slap_suspend_listeners( void )
+{
+       int i;
+       for (i=0; slap_listeners[i]; i++) {
+               slap_listeners[i]->sl_mute = 1;
+               listen( slap_listeners[i]->sl_sd, 0 );
+       }
+}
+
+/* Resume after a suspend */
+void
+slap_resume_listeners( void )
+{
+       int i;
+       for (i=0; slap_listeners[i]; i++) {
+               slap_listeners[i]->sl_mute = 0;
+               listen( slap_listeners[i]->sl_sd, SLAPD_LISTEN_BACKLOG );
+       }
+}
+
 void
 slap_wake_listener()
 {
index d28bdc23e1cb36702f2f87eee4f922c3c07c430b..d44a03e41f522d89998b3cdaadaf55a2afa0bf74 100644 (file)
@@ -760,6 +760,7 @@ LDAP_SLAPD_F (int) connections_init LDAP_P((void));
 LDAP_SLAPD_F (int) connections_shutdown LDAP_P((void));
 LDAP_SLAPD_F (int) connections_destroy LDAP_P((void));
 LDAP_SLAPD_F (int) connections_timeout_idle LDAP_P((time_t));
+LDAP_SLAPD_F (void) connections_drop LDAP_P((void));
 
 LDAP_SLAPD_F (Connection *) connection_client_setup LDAP_P((
        ber_socket_t s,
@@ -867,6 +868,9 @@ LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
 LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
 LDAP_SLAPD_F (void) slap_wake_listener LDAP_P((void));
 
+LDAP_SLAPD_F (void) slap_suspend_listeners LDAP_P((void));
+LDAP_SLAPD_F (void) slap_resume_listeners LDAP_P((void));
+
 LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
index c1fa865515ef2cc451b3b936674bf02ca1010d54..29efd16cbe05ca7ff290c6931ffb4bff9950cf63 100644 (file)
@@ -111,6 +111,7 @@ typedef struct syncinfo_s {
        int                     si_syncdata;
        int                     si_logstate;
        int                     si_got;
+       int                     si_strict_refresh;      /* stop listening during fallback refresh */
        ber_int_t       si_msgid;
        Avlnode                 *si_presentlist;
        LDAP                    *si_ld;
@@ -961,6 +962,10 @@ do_syncrep2(
                                                bdn.bv_val[bdn.bv_len] = '\0';
                                                Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s delta-sync lost sync on (%s), switching to REFRESH\n",
                                                        si->si_ridtxt, bdn.bv_val, 0 );
+                                               if (si->si_strict_refresh) {
+                                                       slap_suspend_listeners();
+                                                       connections_drop();
+                                               }
                                                break;
                                        default:
                                                break;
@@ -1023,6 +1028,10 @@ do_syncrep2(
                                        si->si_logstate = SYNCLOG_FALLBACK;
                                        Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s delta-sync lost sync, switching to REFRESH\n",
                                                si->si_ridtxt, 0, 0 );
+                                       if (si->si_strict_refresh) {
+                                               slap_suspend_listeners();
+                                               connections_drop();
+                                       }
                                }
                                rc = err;
                                goto done;
@@ -1118,6 +1127,7 @@ do_syncrep2(
                                && si->si_logstate == SYNCLOG_FALLBACK ) {
                                si->si_logstate = SYNCLOG_LOGGING;
                                rc = LDAP_SYNC_REFRESH_REQUIRED;
+                               slap_resume_listeners();
                        } else {
                                rc = -2;
                        }
@@ -4117,6 +4127,7 @@ config_suffixm( ConfigArgs *c, syncinfo_t *si )
 #define LOGBASESTR             "logbase"
 #define LOGFILTERSTR   "logfilter"
 #define SUFFIXMSTR             "suffixmassage"
+#define        STRICT_REFRESH  "strictrefresh"
 
 /* FIXME: undocumented */
 #define EXATTRSSTR             "exattrs"
@@ -4615,6 +4626,10 @@ parse_syncrepl_line(
                        val = c->argv[ i ] + STRLENOF( SYNCDATASTR "=" );
                        si->si_syncdata = verb_to_mask( val, datamodes );
                        si->si_got |= GOT_SYNCDATA;
+               } else if ( !strncasecmp( c->argv[ i ], STRICT_REFRESH,
+                                       STRLENOF( STRICT_REFRESH ) ) )
+               {
+                       si->si_strict_refresh = 1;
                } else if ( bindconf_parse( c->argv[i], &si->si_bindconf ) ) {
                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
                                "Error: parse_syncrepl_line: "