/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "ldap_rq.h"
-#ifdef HAVE_SYS_EPOLL_H
+#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL)
#include <sys/epoll.h>
#endif
time_t starttime;
ber_socket_t dtblsize;
slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
+struct runqueue_s slapd_rq;
Listener **slap_listeners = NULL;
-#define SLAPD_LISTEN 10
+#ifndef SLAPD_LISTEN_BACKLOG
+#define SLAPD_LISTEN_BACKLOG 1024
+#endif
static ber_socket_t wake_sds[2];
static int emfile;
static int waking;
-#define WAKE_LISTENER(w) \
-do { if (w && waking < 5) { waking++; tcp_write( wake_sds[1], "0", 1 ); } } while(0)
+#define WAKE_LISTENER(w) do { \
+ if ((w) && waking < 5) { waking++; tcp_write( wake_sds[1], "0", 1 ); } \
+ } while(0)
volatile sig_atomic_t slapd_shutdown = 0, slapd_gentle_shutdown = 0;
volatile sig_atomic_t slapd_abrupt_shutdown = 0;
#define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[i].data.ptr)
#define SLAP_SOCK_SET_MUTE(s) SLAP_SOCK_CLR_READ(s)
#define SLAP_SOCK_CLR_MUTE(s) SLAP_SOCK_SET_READ(s)
-#define SLAP_SOCK_IS_MUTE(s) !SLAP_SOCK_IS_READ(s)
+#define SLAP_SOCK_IS_MUTE(s) (!SLAP_SOCK_IS_READ(s))
#define SLAP_SOCK_SET_INIT \
slap_daemon.sd_epolls = ch_malloc(sizeof(struct epoll_event) * dtblsize * 2); \
#define SLAP_SOCK_SET_MUTE(s) FD_CLR(s, &readfds)
#define SLAP_SOCK_CLR_MUTE(s) FD_SET(s, &readfds)
-#define SLAP_SOCK_IS_MUTE(s) FD_ISSET(s, &readfds)
+#define SLAP_SOCK_IS_MUTE(s) (!FD_ISSET(s, &readfds))
#endif
{
int i;
- assert( exts );
- assert( perms );
- assert( crit );
+ assert( exts != NULL );
+ assert( perms != NULL );
+ assert( crit != NULL );
*crit = 0;
for ( i = 0; exts[ i ]; i++ ) {
#endif
#ifdef LDAP_PF_LOCAL
case AF_LOCAL:
- addrlen = sizeof(struct sockaddr_un);
- break;
+#ifdef LOCAL_CREDS
+ {
+ int one = 1;
+ setsockopt(l.sl_sd, 0, LOCAL_CREDS, &one, sizeof one);
+ }
+#endif
+ addrlen = sizeof(struct sockaddr_un);
+ break;
#endif
}
#ifdef LDAP_PF_LOCAL
case AF_LOCAL: {
char *addr = ((struct sockaddr_un *)*sal)->sun_path;
-#if 0 /* don't muck with socket perms */
- if ( chmod( addr, l.sl_perms ) < 0 && crit ) {
- int err = sock_errno();
- Debug( LDAP_DEBUG_ANY, "daemon: fchmod(%ld) failed errno=%d (%s)",
- (long) l.sl_sd, err, sock_errstr(err) );
- tcp_close( l.sl_sd );
- slap_free_listener_addresses(psal);
- return -1;
- }
-#endif
l.sl_name.bv_len = strlen(addr) + sizeof("PATH=") - 1;
l.sl_name.bv_val = ber_memalloc( l.sl_name.bv_len + 1 );
snprintf( l.sl_name.bv_val, l.sl_name.bv_len + 1,
if( getpeereid( s, &uid, &gid ) == 0 ) {
authid.bv_val = ch_malloc(
- sizeof("uidnumber=4294967295+gidnumber=4294967295,"
- "cn=peercred,cn=external,cn=auth"));
+ STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
+ "cn=peercred,cn=external,cn=auth" ) + 1 );
authid.bv_len = sprintf( authid.bv_val,
- "uidnumber=%d+gidnumber=%d,"
+ "gidNumber=%d+uidNumber=%d,"
"cn=peercred,cn=external,cn=auth",
- (int) uid, (int) gid);
+ (int) gid, (int) uid );
+ assert( authid.bv_len <=
+ STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
+ "cn=peercred,cn=external,cn=auth" ) );
}
}
dnsname = "local";
int l;
time_t last_idle_check = 0;
struct timeval idle;
+ int ebadf = 0;
#define SLAPD_IDLE_CHECK_LIMIT 4
}
#endif
- if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN ) == -1 ) {
+ if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN_BACKLOG ) == -1 ) {
int err = sock_errno();
#ifdef LDAP_PF_INET6
ber_socket_t i;
int ns, nwriters;
int at;
- ber_socket_t nfds, nrfds, nwfds;
+ ber_socket_t nfds;
+#if SLAP_EVENTS_ARE_INDEXED
+ ber_socket_t nrfds, nwfds;
+#endif
#define SLAPD_EBADF_LIMIT 16
- int ebadf = 0;
time_t now;
else
tvp = NULL;
- ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
- rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat );
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+ rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
while ( cat && cat->tv_sec && cat->tv_sec <= now ) {
- if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
+ if ( ldap_pvt_runqueue_isrunning( &slapd_rq, rtask )) {
+ ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
} else {
- ldap_pvt_runqueue_runtask( &syncrepl_rq, rtask );
- ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 );
- ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_runqueue_runtask( &slapd_rq, rtask );
+ ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
ldap_pvt_thread_pool_submit( &connection_pool,
rtask->routine, (void *) rtask );
- ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
}
- rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat );
+ rtask = ldap_pvt_runqueue_next_sched( &slapd_rq, &cat );
}
- ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
- if ( cat != NULL ) {
+ if ( cat && cat->tv_sec ) {
time_t diff = difftime( cat->tv_sec, now );
if ( diff == 0 )
diff = tdelta;
case 0: /* timeout - let threads run */
ebadf = 0;
+#ifndef HAVE_YIELDING_SELECT
Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
0, 0, 0 );
ldap_pvt_thread_yield();
+#endif
continue;
default: /* something happened - deal with it */
/* FALL THRU */
}
- /* We don't need to examine the event status for wake_sds;
- * if waking is set and we woke up, we'll read whatever
- * we can.
- */
- if ( waking ) {
+#if SLAP_EVENTS_ARE_INDEXED
+ if ( SLAP_EVENT_IS_READ( wake_sds[0] )) {
char c[BUFSIZ];
tcp_read( wake_sds[0], c, sizeof(c) );
waking = 0;
ns--;
+ SLAP_EVENT_CLR_READ( wake_sds[0] );
continue;
}
-#if SLAP_EVENTS_ARE_INDEXED
/* The event slot equals the descriptor number - this is
* true for Unix select and poll. We treat Windows select
* like this too, even though it's a kludge.
if ( !SLAP_EVENT_IS_READ( slap_listeners[l]->sl_sd ))
continue;
- ns--;
-
rc = slapd_handle_listener(slap_listeners[l]);
#ifdef LDAP_CONNECTIONLESS
if ( rc ) continue;
#endif
+ ns--;
+
/* Don't need to look at this in the data loops */
SLAP_EVENT_CLR_READ( slap_listeners[l]->sl_sd );
SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
/* bypass the following tests if no descriptors left */
if ( ns <= 0 ) {
+#ifndef HAVE_YIELDING_SELECT
ldap_pvt_thread_yield();
+#endif
continue;
}
int r, w;
r = SLAP_EVENT_IS_READ( i );
- w = SLAP_EVENT_IS_WRITE( i );
+ /* writefds was not initialized if nwriters was zero */
+ w = nwriters ? SLAP_EVENT_IS_WRITE( i ) : 0;
if ( r || w ) {
Debug( LDAP_DEBUG_CONNS, " %d%s%s", i,
r ? "r" : "", w ? "w" : "" );
}
slapd_close( wd );
}
+ SLAP_EVENT_CLR_WRITE( wd );
}
for ( i = 0; nrfds > 0; i++ )
* all other connections last (as we do for select), we would need
* to use multiple event handles and cascade them.
*
- * That seems like a bit of hassle. So the wake_sds check has moved
- * above. For epoll and kqueue we can associate arbitrary data with
+ * That seems like a bit of hassle. So the wake_sds check has been
+ * skipped. For epoll and kqueue we can associate arbitrary data with
* an event, so we could use pointers to the listener structure
* instead of just the file descriptor. For /dev/poll we have to
* search the listeners array for a matching descriptor.
*/
+ /* if waking is set and we woke up, we'll read whatever
+ * we can.
+ */
+ if ( waking ) {
+ char c[BUFSIZ];
+ tcp_read( wake_sds[0], c, sizeof(c) );
+ waking = 0;
+ ns--;
+ continue;
+ }
+
#ifdef LDAP_DEBUG
Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
#endif
) continue;
+ /* Don't log internal wake events */
+ if ( SLAP_EVENT_FD( i ) == wake_sds[0] )
+ continue;
+
r = SLAP_EVENT_IS_READ( i );
w = SLAP_EVENT_IS_WRITE( i );
if ( r || w ) {
if ( rc ) {
fd = SLAP_EVENT_FD( i );
+ /* Ignore wake events, they were handled above */
+ if ( fd == wake_sds[0] )
+ continue;
+
if( SLAP_EVENT_IS_WRITE( i ) ) {
Debug( LDAP_DEBUG_CONNS,
"daemon: write active on %d\n",
}
#endif /* SLAP_EVENTS_ARE_INDEXED */
+#ifndef HAVE_YIELDING_SELECT
ldap_pvt_thread_yield();
+#endif
}
if( slapd_shutdown == 1 ) {
- Debug( LDAP_DEBUG_TRACE,
+ Debug( LDAP_DEBUG_ANY,
"daemon: shutdown requested and initiated.\n",
0, 0, 0 );
} else if ( slapd_shutdown == 2 ) {
#ifdef HAVE_NT_SERVICE_MANAGER
- Debug( LDAP_DEBUG_TRACE,
+ Debug( LDAP_DEBUG_ANY,
"daemon: shutdown initiated by Service Manager.\n",
0, 0, 0);
#else /* !HAVE_NT_SERVICE_MANAGER */
- Debug( LDAP_DEBUG_TRACE,
+ Debug( LDAP_DEBUG_ANY,
"daemon: abnormal condition, shutdown initiated.\n",
0, 0, 0 );
#endif /* !HAVE_NT_SERVICE_MANAGER */
} else {
- Debug( LDAP_DEBUG_TRACE,
+ Debug( LDAP_DEBUG_ANY,
"daemon: no active streams, shutdown initiated.\n",
0, 0, 0 );
}
close_listeners ( 0 );
}
- free ( slap_listeners );
- slap_listeners = NULL;
-
if( !slapd_gentle_shutdown ) {
slapd_abrupt_shutdown = 1;
connections_shutdown();
ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
ldap_pvt_thread_pool_destroy(&connection_pool, 1);
+ free ( slap_listeners );
+ slap_listeners = NULL;
+
return NULL;
}
}
-int sockinit(void)
+static int sockinit(void)
{
#if defined( HAVE_WINSOCK2 )
WORD wVersionRequested;
return 0;
}
-int sockdestroy(void)
+static int sockdestroy(void)
{
#if defined( HAVE_WINSOCK2 ) || defined( HAVE_WINSOCK )
WSACleanup();