From 9e00b6cc6ce2857490b33218bdaf1339319c5f60 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 15 Apr 2011 11:13:38 -0700 Subject: [PATCH] Add strictrefresh syncrepl option Only affects delta-syncrepl - stop listening to clients while refresh is running. --- servers/slapd/connection.c | 27 ++++++++++++++++++++++++++- servers/slapd/daemon.c | 22 ++++++++++++++++++++++ servers/slapd/proto-slap.h | 4 ++++ servers/slapd/syncrepl.c | 15 +++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 0d508ee7ef..aea3b39191 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -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; diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 21821aafdd..8e8a69d560 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -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() { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index d28bdc23e1..d44a03e41f 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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)); diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index c1fa865515..29efd16cbe 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -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: " -- 2.39.5