From a7caededb70b86f9bcd8503ea2099215504423a7 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: May 01 2015 15:00:54 +0000 Subject: Ticket #48178 add config param to enable nunc-stans https://fedorahosted.org/389/ticket/48178 Reviewed by: ??? Branch: master Fix Description: If nsslapd-enable-nunc-stans: on, the server will use nunc-stans as the event framework. NOTE: You still have to build the server with configure --enable-nunc-stans in order to be able to set nsslapd-enable-nunc-stans: on. By default, the value is off. Platforms tested: Fedora 20 Flag Day: no Doc impact: no --- diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index 58668f0..6d719fd 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -282,6 +282,7 @@ connection_cleanup(Connection *conn) ns_enable_listeners(); } #ifdef ENABLE_NUNC_STANS + /* even if !config_get_enable_nunc_stans, it is ok to set to 0 here */ conn->c_ns_close_jobs = 0; #endif } @@ -2357,9 +2358,8 @@ connection_threadmain() int replication_connection = 0; /* If this connection is from a replication supplier, we want to ensure that operation processing is serialized */ int doshutdown = 0; int maxthreads = 0; -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 + int enable_nunc_stans = config_get_enable_nunc_stans(); long bypasspollcnt = 0; -#endif #if defined( OSF1 ) || defined( hpux ) /* Arrange to ignore SIGPIPE signals. */ @@ -2552,8 +2552,7 @@ connection_threadmain() * when using nunc-stans - it is supposed to be an optimization but turns out * to not be the opposite with nunc-stans */ -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 - } else { /* more data in conn - just put back on work_q - bypass poll */ + } else if (!enable_nunc_stans) { /* more data in conn - just put back on work_q - bypass poll */ bypasspollcnt++; PR_Lock(conn->c_mutex); /* don't do this if it would put us over the max threads per conn */ @@ -2571,7 +2570,6 @@ connection_threadmain() conn->c_maxthreadsblocked++; } PR_Unlock(conn->c_mutex); -#endif } } diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c index dc2e265..e7ce5e5 100644 --- a/ldap/servers/slapd/conntable.c +++ b/ldap/servers/slapd/conntable.c @@ -212,6 +212,7 @@ connection_table_get_connection(Connection_Table *ct, int sd) */ connection_cleanup(c); #ifdef ENABLE_NUNC_STANS + /* NOTE - ok to do this here even if enable_nunc_stans is off */ c->c_ct = ct; /* pointer to connection table that owns this connection */ #endif } diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index 29f0580..af378f5 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -119,12 +119,10 @@ short slapd_housekeeping_timer = 10; /* Do we support timeout on socket send() ? */ int have_send_timeouts = 0; -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 PRFileDesc* signalpipe[2]; static int writesignalpipe = SLAPD_INVALID_SOCKET; static int readsignalpipe = SLAPD_INVALID_SOCKET; #define FDS_SIGNAL_PIPE 0 -#endif static PRThread *disk_thread_p = NULL; static PRCondVar *diskmon_cvar = NULL; @@ -148,6 +146,8 @@ typedef struct listener_info { static int listeners = 0; /* number of listener sockets */ static listener_info *listener_idxs = NULL; /* array of indexes of listener sockets in the ct->fd array */ +static int enable_nunc_stans = 0; /* if nunc-stans is set to enabled, set to 1 in slapd_daemon */ + #define SLAPD_POLL_LISTEN_READY(xxflagsxx) (xxflagsxx & PR_POLL_READ) static int get_configured_connection_table_size(); @@ -177,9 +177,7 @@ static void* catch_signals(); HANDLE hServDoneEvent = NULL; #endif -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 static int createsignalpipe( void ); -#endif #if defined( _WIN32 ) /* Set an event to hook the NT Service termination */ @@ -395,14 +393,13 @@ static void set_timeval_ms(struct timeval *t, int ms); static int handle_new_connection(Connection_Table *ct, int tcps, PRFileDesc *pr_acceptfd, int secure, int local, Connection **newconn ); #ifdef ENABLE_NUNC_STANS static void ns_handle_new_connection(struct ns_job_t *job); -#else +#endif static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll); #ifdef _WIN32 static int clear_signal(fd_set *readfdset); #else static int clear_signal(struct POLL_STRUCT *fds); #endif -#endif #ifdef _WIN32 static void unfurl_banners(Connection_Table *ct,daemon_ports_t *ports, int n_tcps, PRFileDesc *s_tcps); #else @@ -934,7 +931,6 @@ disk_monitoring_thread(void *nothing) } } -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 static void handle_listeners(Connection_Table *ct) { @@ -958,7 +954,6 @@ handle_listeners(Connection_Table *ct) } return; } -#endif /* !ENABLE_NUNC_STANS */ /* * Convert any pre-existing DES passwords to AES. @@ -1224,6 +1219,9 @@ void ns_enable_listeners() { #ifdef ENABLE_NUNC_STANS + if (!enable_nunc_stans) { + return; + } int num_enabled = 0; listener_info *listener; while ((listener = (listener_info *)PR_StackPop(ns_disabled_listeners))) { @@ -1282,7 +1280,7 @@ nunc_stans_free(void *ptr) { slapi_ch_free((void **)&ptr); } -#endif +#endif /* ENABLE_NUNC_STANS */ void slapd_daemon( daemon_ports_t *ports ) { @@ -1306,9 +1304,7 @@ void slapd_daemon( daemon_ports_t *ports ) PRFileDesc **fdesp = NULL; #endif PRIntn num_poll = 0; -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 PRIntervalTime pr_timeout = PR_MillisecondsToInterval(slapd_wakeup_timer); -#endif PRThread *time_thread_p; int threads; int in_referral_mode = config_check_referral_mode(); @@ -1319,6 +1315,10 @@ void slapd_daemon( daemon_ports_t *ports ) int connection_table_size = get_configured_connection_table_size(); the_connection_table= connection_table_new(connection_table_size); +#ifdef ENABLE_NUNC_STANS + enable_nunc_stans = config_get_enable_nunc_stans(); +#endif + #ifdef RESOLVER_NEEDS_LOW_FILE_DESCRIPTORS /* * Some DNS resolver implementations, such as the one built into @@ -1342,10 +1342,10 @@ void slapd_daemon( daemon_ports_t *ports ) i_unix = ports->i_socket; #endif /* ENABLE_LDAPI */ #endif - -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 - createsignalpipe(); -#endif + + if (!enable_nunc_stans) { + createsignalpipe(); + } init_shutdown_detect(); @@ -1494,7 +1494,9 @@ void slapd_daemon( daemon_ports_t *ports ) #endif listener_idxs = (listener_info *)slapi_ch_calloc(listeners, sizeof(*listener_idxs)); #ifdef ENABLE_NUNC_STANS - ns_disabled_listeners = PR_CreateStack("disabled_listeners"); + if (enable_nunc_stans) { + ns_disabled_listeners = PR_CreateStack("disabled_listeners"); + } #endif /* * Convert old DES encoded passwords to AES @@ -1502,7 +1504,7 @@ void slapd_daemon( daemon_ports_t *ports ) convert_pbe_des_to_aes(); #ifdef ENABLE_NUNC_STANS - if (!g_get_shutdown()) { + if (enable_nunc_stans && !g_get_shutdown()) { int ii; PRInt32 maxthreads = 3; if (getenv("MAX_THREADS")) { @@ -1536,7 +1538,7 @@ void slapd_daemon( daemon_ports_t *ports ) } } -#endif +#endif /* ENABLE_NUNC_STANS */ /* Now we write the pid file, indicating that the server is finally and listening for connections */ write_pid_file(); @@ -1544,14 +1546,14 @@ void slapd_daemon( daemon_ports_t *ports ) unfurl_banners(the_connection_table,ports,n_tcps,s_tcps,i_unix); #ifdef ENABLE_NUNC_STANS - if (ns_thrpool_wait(tp)) { + if (enable_nunc_stans && ns_thrpool_wait(tp)) { LDAPDebug( LDAP_DEBUG_ANY, "ns_thrpool_wait failed errno %d (%s)\n", errno, slapd_system_strerror(errno), 0 ); } - -#else /* The meat of the operation is in a loop on a call to select */ - while(!g_get_shutdown()) +#endif + /* The meat of the operation is in a loop on a call to select */ + while(!enable_nunc_stans && !g_get_shutdown()) { #ifdef _WIN32 fd_set readfds; @@ -1614,7 +1616,6 @@ void slapd_daemon( daemon_ports_t *ports ) break; } } -#endif /* ENABLE_NUNC_STANS */ /* We get here when the server is shutting down */ /* Do what we have to do before death */ @@ -1688,36 +1689,36 @@ void slapd_daemon( daemon_ports_t *ports ) threads = g_get_active_threadcnt(); while ( threads > 0 ) { -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 - PRPollDesc xpd; - char x; - int spe = 0; - - /* try to read from the signal pipe, in case threads are - * blocked on it. */ - xpd.fd = signalpipe[0]; - xpd.in_flags = PR_POLL_READ; - xpd.out_flags = 0; - spe = PR_Poll(&xpd, 1, PR_INTERVAL_NO_WAIT); - if (spe > 0) { - spe = PR_Read(signalpipe[0], &x, 1); - if (spe < 0) { - PRErrorCode prerr = PR_GetError(); - LDAPDebug( LDAP_DEBUG_ANY, "listener could not clear signal pipe, " + if (!enable_nunc_stans) { + PRPollDesc xpd; + char x; + int spe = 0; + + /* try to read from the signal pipe, in case threads are + * blocked on it. */ + xpd.fd = signalpipe[0]; + xpd.in_flags = PR_POLL_READ; + xpd.out_flags = 0; + spe = PR_Poll(&xpd, 1, PR_INTERVAL_NO_WAIT); + if (spe > 0) { + spe = PR_Read(signalpipe[0], &x, 1); + if (spe < 0) { + PRErrorCode prerr = PR_GetError(); + LDAPDebug( LDAP_DEBUG_ANY, "listener could not clear signal pipe, " + SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", + prerr, slapd_system_strerror(prerr), 0 ); + break; + } + } else if (spe == -1) { + PRErrorCode prerr = PR_GetError(); + LDAPDebug( LDAP_DEBUG_ANY, "PR_Poll() failed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", prerr, slapd_system_strerror(prerr), 0 ); - break; - } - } else if (spe == -1) { - PRErrorCode prerr = PR_GetError(); - LDAPDebug( LDAP_DEBUG_ANY, "PR_Poll() failed, " - SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", - prerr, slapd_system_strerror(prerr), 0 ); - break; - } else { - /* no data */ + break; + } else { + /* no data */ + } } -#endif DS_Sleep(PR_INTERVAL_NO_WAIT); if ( threads != g_get_active_threadcnt() ) { LDAPDebug( LDAP_DEBUG_TRACE, @@ -1762,7 +1763,9 @@ void slapd_daemon( daemon_ports_t *ports ) connection_table_free(the_connection_table); the_connection_table= NULL; #ifdef ENABLE_NUNC_STANS - ns_thrpool_destroy(tp); + if (enable_nunc_stans) { + ns_thrpool_destroy(tp); + } #endif be_cleanupall (); connection_post_shutdown_cleanup(); @@ -1789,7 +1792,9 @@ void slapd_daemon( daemon_ports_t *ports ) int signal_listner() { -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 + if (enable_nunc_stans) { + return( 0 ); + } /* Replaces previous macro---called to bump the thread out of select */ #if defined( _WIN32 ) if ( PR_Write( signalpipe[1], "", 1) != 1 ) { @@ -1811,17 +1816,18 @@ int signal_listner() errno, 0, 0 ); } #endif -#endif return( 0 ); } -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 #ifdef _WIN32 static int clear_signal(fd_set *readfdset) #else static int clear_signal(struct POLL_STRUCT *fds) #endif { + if (enable_nunc_stans) { + return 0; + } #ifdef _WIN32 if ( FD_ISSET(readsignalpipe, readfdset)) { #else @@ -1844,7 +1850,6 @@ static int clear_signal(struct POLL_STRUCT *fds) } return 0; } -#endif /* !ENABLE_NUNC_STANS */ #ifdef _WIN32 static void set_timeval_ms(struct timeval *t, int ms) @@ -1989,18 +1994,18 @@ setup_pr_read_pds(Connection_Table *ct, PRFileDesc **n_tcps, PRFileDesc **s_tcps ct->c[i].c_fdi = SLAPD_INVALID_SOCKET_INDEX; } -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 - /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE (== 0) */ - count = FDS_SIGNAL_PIPE; + if (!enable_nunc_stans) { + /* The fds entry for the signalpipe is always FDS_SIGNAL_PIPE (== 0) */ + count = FDS_SIGNAL_PIPE; #if !defined(_WIN32) - ct->fd[count].fd = signalpipe[0]; - ct->fd[count].in_flags = SLAPD_POLL_FLAGS; - ct->fd[count].out_flags = 0; + ct->fd[count].fd = signalpipe[0]; + ct->fd[count].in_flags = SLAPD_POLL_FLAGS; + ct->fd[count].out_flags = 0; #else - ct->fd[count].fd = NULL; -#endif - count++; + ct->fd[count].fd = NULL; #endif + count++; + } /* The fds entry for n_tcps starts with n_tcps and less than n_tcpe */ ct->n_tcps = count; if (n_tcps != NULL && accept_new_connections) @@ -2262,7 +2267,6 @@ handle_read_ready(Connection_Table *ct, fd_set *readfds) #endif /* _WIN32 */ -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 static void handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll) { @@ -2418,7 +2422,6 @@ handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll) } #endif } -#endif /* !ENABLE_NUNC_STANS */ #ifdef ENABLE_NUNC_STANS #define CONN_NEEDS_CLOSING(c) (c->c_flags & CONN_FLAG_CLOSING) || (c->c_sd == SLAPD_INVALID_SOCKET) @@ -2478,6 +2481,10 @@ ns_connection_post_io_or_closing(Connection *conn) #ifdef ENABLE_NUNC_STANS struct timeval tv; + if (!enable_nunc_stans) { + return; + } + if (CONN_NEEDS_CLOSING(conn)) { /* there should only ever be 0 or 1 active closure jobs */ PR_ASSERT((conn->c_ns_close_jobs == 0) || (conn->c_ns_close_jobs == 1)); @@ -3386,10 +3393,10 @@ static int init_shutdown_detect() (void) SIGNAL( SIGUSR1, slapd_do_nothing ); (void) SIGNAL( SIGUSR2, set_shutdown ); #endif -#ifndef ENABLE_NUNC_STANS - (void) SIGNAL( SIGTERM, set_shutdown ); - (void) SIGNAL( SIGHUP, set_shutdown ); -#endif + if (!enable_nunc_stans) { + (void) SIGNAL( SIGTERM, set_shutdown ); + (void) SIGNAL( SIGHUP, set_shutdown ); + } #endif /* _WIN32 */ return 0; } @@ -3984,10 +3991,12 @@ netaddr2string(const PRNetAddr *addr, char *addrbuf, size_t addrbuflen) } -#if !defined(ENABLE_NUNC_STANS) || ENABLE_NUNC_STANS == 0 static int createsignalpipe( void ) { + if (enable_nunc_stans) { + return( 0 ); + } #if defined( _WIN32 ) if ( PR_NewTCPSocketPair(&signalpipe[0])) { PRErrorCode prerr = PR_GetError(); @@ -4019,7 +4028,6 @@ createsignalpipe( void ) #endif return( 0 ); } -#endif #ifdef HPUX10 diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c index d03d39b..5aee1c4 100644 --- a/ldap/servers/slapd/libglobs.c +++ b/ldap/servers/slapd/libglobs.c @@ -274,6 +274,9 @@ slapi_onoff_t init_ignore_time_skew; slapi_onoff_t init_dynamic_plugins; slapi_onoff_t init_cn_uses_dn_syntax_in_dns; slapi_onoff_t init_global_backend_local; +#ifdef ENABLE_NUNC_STANS +slapi_onoff_t init_enable_nunc_stans; +#endif #if defined (LINUX) slapi_int_t init_malloc_mxfast; slapi_int_t init_malloc_trim_threshold; @@ -1127,7 +1130,13 @@ static struct config_get_and_set { {CONFIG_GLOBAL_BACKEND_LOCK, config_set_global_backend_lock, NULL, 0, (void**)&global_slapdFrontendConfig.global_backend_lock, - CONFIG_ON_OFF, (ConfigGetFunc)config_get_global_backend_lock, &init_global_backend_local} + CONFIG_ON_OFF, (ConfigGetFunc)config_get_global_backend_lock, &init_global_backend_local} +#ifdef ENABLE_NUNC_STANS + ,{CONFIG_ENABLE_NUNC_STANS, config_set_enable_nunc_stans, + NULL, 0, + (void**)&global_slapdFrontendConfig.enable_nunc_stans, + CONFIG_ON_OFF, (ConfigGetFunc)config_get_enable_nunc_stans, &init_enable_nunc_stans} +#endif #ifdef MEMPOOL_EXPERIMENTAL ,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch, NULL, 0, @@ -1576,6 +1585,9 @@ FrontendConfig_init () { init_dynamic_plugins = cfg->dynamic_plugins = LDAP_OFF; init_cn_uses_dn_syntax_in_dns = cfg->cn_uses_dn_syntax_in_dns = LDAP_OFF; init_global_backend_local = LDAP_OFF; +#ifdef ENABLE_NUNC_STANS + init_enable_nunc_stans = cfg->enable_nunc_stans = LDAP_OFF; +#endif #if defined(LINUX) init_malloc_mxfast = cfg->malloc_mxfast = DEFAULT_MALLOC_UNSET; init_malloc_trim_threshold = cfg->malloc_trim_threshold = DEFAULT_MALLOC_UNSET; @@ -7400,6 +7412,33 @@ config_get_listen_backlog_size() return retVal; } +#ifdef ENABLE_NUNC_STANS +int +config_get_enable_nunc_stans() +{ + int retVal; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + CFG_LOCK_READ(slapdFrontendConfig); + retVal = slapdFrontendConfig->enable_nunc_stans; + CFG_UNLOCK_READ(slapdFrontendConfig); + + return retVal; +} + +int +config_set_enable_nunc_stans( const char *attrname, char *value, + char *errorbuf, int apply ) +{ + int retVal = LDAP_SUCCESS; + slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig(); + + retVal = config_set_onoff(attrname, value, + &(slapdFrontendConfig->enable_nunc_stans), + errorbuf, apply); + return retVal; +} +#endif + static char * config_initvalue_to_onoff(struct config_get_and_set *cgas, char *initvalbuf, size_t initvalbufsize) { diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 353024d..408543e 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -597,6 +597,10 @@ int config_set_dynamic_plugins(const char *attrname, char *value, char *errorbuf int config_get_dynamic_plugins(); int config_set_cn_uses_dn_syntax_in_dns(const char *attrname, char *value, char *errorbuf, int apply); int config_get_cn_uses_dn_syntax_in_dns(); +#ifdef ENABLE_NUNC_STANS +int config_get_enable_nunc_stans(void); +int config_set_enable_nunc_stans(const char *attrname, char *value, char *errorbuf, int apply); +#endif PLHashNumber hashNocaseString(const void *key); PRIntn hashNocaseCompare(const void *v1, const void *v2); diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 6447ee5..b7c6e80 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -2126,7 +2126,9 @@ typedef struct _slapdEntryPoints { #define CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE "nsslapd-plugin-binddn-tracking" #define CONFIG_MODDN_ACI_ATTRIBUTE "nsslapd-moddn-aci" #define CONFIG_GLOBAL_BACKEND_LOCK "nsslapd-global-backend-lock" - +#ifdef ENABLE_NUNC_STANS +#define CONFIG_ENABLE_NUNC_STANS "nsslapd-enable-nunc-stans" +#endif #define CONFIG_CONFIG_ATTRIBUTE "nsslapd-config" #define CONFIG_INSTDIR_ATTRIBUTE "nsslapd-instancedir" #define CONFIG_SCHEMADIR_ATTRIBUTE "nsslapd-schemadir" @@ -2433,6 +2435,9 @@ typedef struct _slapdFrontendConfig { slapi_onoff_t dynamic_plugins; /* allow plugins to be dynamically enabled/disabled */ slapi_onoff_t cn_uses_dn_syntax_in_dns; /* indicates the cn value in dns has dn syntax */ slapi_onoff_t global_backend_lock; +#ifdef ENABLE_NUNC_STANS + slapi_onoff_t enable_nunc_stans; +#endif #if defined(LINUX) int malloc_mxfast; /* mallopt M_MXFAST */ int malloc_trim_threshold; /* mallopt M_TRIM_THRESHOLD */