]> git.sur5r.net Git - openldap/commitdiff
Gentile HUP shutdown from Hallvard
authorKurt Zeilenga <kurt@openldap.org>
Mon, 3 Jun 2002 16:47:43 +0000 (16:47 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 3 Jun 2002 16:47:43 +0000 (16:47 +0000)
doc/man/man5/slapd.conf.5
servers/slapd/config.c
servers/slapd/daemon.c
servers/slapd/proto-slap.h

index 3c9ed2bc52eb6192b694abd87c5d3eedfde80700..9a22026da77d5778075ade89b820cb4fceac56e0 100644 (file)
@@ -204,6 +204,22 @@ disables Start TLS from forcing session to anonymous status (see also
 disables StartTLS if authenticated (see also
 .BR tls_2_anon ).
 .TP
+.B gentlehup { on | off }
+A SIGHUP signal will only cause a 'gentle' shutdown-attempt:
+.B Slapd
+will stop listening for new connections, but will not close the
+connections to the current clients.  It terminates when all clients
+have closed their connections (if they ever do), or \- as before \-
+if it receives a SIGTERM signal.  This can be useful if you wish to
+terminate the server and start a new
+.B slapd
+server
+.B with another database,
+without disrupting the currently active clients.
+The default is off.  You may wish to use
+.B idletimeout
+along with this option.
+.TP
 .B idletimeout <integer>
 Specify the number of seconds to wait before forcibly closing
 an idle client connection.  A idletimeout of 0 disables this
index e5dcdbe1c76014fbd7a3ef4ac74f16e87dfc9abc..d89f9cb21b395cc0b5b23678346ec0156a04ab83 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <ac/string.h>
 #include <ac/ctype.h>
+#include <ac/signal.h>
 #include <ac/socket.h>
 #include <ac/errno.h>
 
@@ -40,6 +41,7 @@ slap_mask_t           global_disallows = 0;
 slap_mask_t            global_requires = 0;
 slap_ssf_set_t global_ssf_set;
 char           *replogfile;
+int            global_gentlehup = 0;
 int            global_idletimeout = 0;
 char   *global_host = NULL;
 char   *global_realm = NULL;
@@ -2038,6 +2040,22 @@ read_config( const char *fname )
                                }
                        }
 
+#ifdef SIGHUP
+               /* turn on/off gentle SIGHUP handling */
+               } else if ( strcasecmp( cargv[0], "gentlehup" ) == 0 ) {
+                       if ( cargc < 2 ) {
+                               Debug( LDAP_DEBUG_ANY,
+    "%s: line %d: missing on|off in \"gentlehup <on|off>\" line\n",
+                                   fname, lineno, 0 );
+                               return( 1 );
+                       }
+                       if ( strcasecmp( cargv[1], "off" ) == 0 ) {
+                               global_gentlehup = 0;
+                       } else {
+                               global_gentlehup = 1;
+                       }
+#endif
+
                /* set idle timeout value */
                } else if ( strcasecmp( cargv[0], "idletimeout" ) == 0 ) {
                        int i;
index 2ab0fa769ff440d01a274ad3dab7c4eb701dc4e1..3dc4cdbcf1baff1e096801430229fbf0868d2233 100644 (file)
@@ -55,12 +55,12 @@ do { if (w) tcp_write( wake_sds[1], "0", 1 ); } while(0)
 #ifndef HAVE_WINSOCK
 static
 #endif
-volatile sig_atomic_t slapd_shutdown = 0;
+volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
 
 static struct slap_daemon {
        ldap_pvt_thread_mutex_t sd_mutex;
 
-       int sd_nactives;
+       ber_socket_t sd_nactives;
 
 #ifndef HAVE_WINSOCK
        /* In winsock, accept() returns values higher than dtblsize
@@ -192,6 +192,8 @@ static void slapd_add(ber_socket_t s) {
        }
 #endif
 
+       slap_daemon.sd_nactives++;
+
        FD_SET( s, &slap_daemon.sd_actives );
        FD_SET( s, &slap_daemon.sd_readers );
 
@@ -216,6 +218,8 @@ static void slapd_add(ber_socket_t s) {
 void slapd_remove(ber_socket_t s, int wake) {
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
+       slap_daemon.sd_nactives--;
+
 #ifdef NEW_LOGGING
        LDAP_LOG(( "connection", LDAP_LEVEL_DETAIL1,
                   "slapd_remove: removing %ld%s%s\n",
@@ -233,7 +237,7 @@ void slapd_remove(ber_socket_t s, int wake) {
        FD_CLR( s, &slap_daemon.sd_writers );
 
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-       WAKE_LISTENER(wake);
+       WAKE_LISTENER(wake || slapd_gentle_shutdown < 0);
 }
 
 void slapd_clr_write(ber_socket_t s, int wake) {
@@ -980,6 +984,34 @@ slapd_daemon_destroy(void)
 }
 
 
+static void
+close_listeners(
+       int remove
+)
+{
+       int l;
+
+       for ( l = 0; slap_listeners[l] != NULL; l++ ) {
+               if ( remove )
+                       slapd_remove( slap_listeners[l]->sl_sd, 0 );
+               if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
+#ifdef LDAP_PF_LOCAL
+                       if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
+                               unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
+                       }
+#endif /* LDAP_PF_LOCAL */
+                       slapd_close( slap_listeners[l]->sl_sd );
+               }
+               if ( slap_listeners[l]->sl_url )
+                       free ( slap_listeners[l]->sl_url );
+               if ( slap_listeners[l]->sl_name )
+                       free ( slap_listeners[l]->sl_name );
+               free ( slap_listeners[l] );
+               slap_listeners[l] = NULL;
+       }
+}
+
+
 static void *
 slapd_daemon_task(
        void *ptr
@@ -1066,6 +1098,26 @@ slapd_daemon_task(
                        }
                }
 
+#ifdef SIGHUP
+               if( slapd_gentle_shutdown ) {
+                       ber_socket_t active;
+
+                       if( slapd_gentle_shutdown > 0 ) {
+                               Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
+                               close_listeners( 1 );
+                               slapd_gentle_shutdown = -1;
+                       }
+
+                       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+                       active = slap_daemon.sd_nactives;
+                       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+                       if( active == 0 ) {
+                               slapd_shutdown = -1;
+                               break;
+                       }
+               }
+#endif
+
                FD_ZERO( &writefds );
                FD_ZERO( &readfds );
 
@@ -1716,21 +1768,8 @@ slapd_daemon_task(
 #endif
        }
 
-       for ( l = 0; slap_listeners[l] != NULL; l++ ) {
-               if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) {
-#ifdef LDAP_PF_LOCAL
-                       if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
-                               unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path );
-                       }
-#endif /* LDAP_PF_LOCAL */
-                       slapd_close( slap_listeners[l]->sl_sd );
-               }
-               if ( slap_listeners[l]->sl_url )
-                       free ( slap_listeners[l]->sl_url );
-               if ( slap_listeners[l]->sl_name )
-                       free ( slap_listeners[l]->sl_name );
-               free ( slap_listeners[l] );
-       }
+       if( slapd_gentle_shutdown >= 0 )
+               close_listeners ( 0 );
        free ( slap_listeners );
        slap_listeners = NULL;
 
@@ -1862,6 +1901,11 @@ slap_sig_shutdown( int sig )
                  0, 0, 0);
 #endif
        else
+#endif
+#ifdef SIGHUP
+       if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0)
+               slapd_gentle_shutdown = 1;
+       else
 #endif
        slapd_shutdown = 1;
 
index 92bd607b880b63b9d9bd812a3dd6045e48783623..f80e53969a21dd3834cff7738131e54a3ca21bb5 100644 (file)
@@ -1017,6 +1017,7 @@ LDAP_SLAPD_V (const char)         Versionstr[];
 LDAP_SLAPD_V (struct slap_limits_set)          deflimit;
 
 LDAP_SLAPD_V (slap_access_t)   global_default_access;
+LDAP_SLAPD_V (int)             global_gentlehup;
 LDAP_SLAPD_V (int)             global_idletimeout;
 LDAP_SLAPD_V (int)             global_schemacheck;
 LDAP_SLAPD_V (char *)  global_host;