X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=e6b5e157cb15da24fc61717b9c864d0980152b31;hb=543c588772b22a029b60e72e45e68032935ecd54;hp=b0f2d6bd0952c3dbcf7ad73acb5dd17a22c02a7c;hpb=9bc19c523240b1a7c44cf8362fb28368bf17f672;p=openldap diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index b0f2d6bd09..e6b5e157cb 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -81,10 +81,9 @@ Listener **slap_listeners = NULL; static ber_socket_t wake_sds[2]; static int emfile; -static int waking; +static volatile int waking; #define WAKE_LISTENER(w) do { \ - if ((w) && waking < 5) { \ - waking++; \ + if ((w) && ++waking < 5) { \ tcp_write( wake_sds[1], "0", 1 ); \ } \ } while(0) @@ -95,6 +94,9 @@ volatile sig_atomic_t slapd_abrupt_shutdown = 0; static struct slap_daemon { ldap_pvt_thread_mutex_t sd_mutex; +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_t tcpd_mutex; +#endif ber_socket_t sd_nactives; int sd_nwriters; @@ -180,8 +182,8 @@ static struct slap_daemon { slap_daemon.sd_nfds++; \ } else { \ Debug( LDAP_DEBUG_ANY, \ - "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \ - errno, 0, 0 ); \ + "daemon: epoll_ctl(ADD,fd=%d) failed, errno=%d, shutting down\n", \ + s, errno, 0 ); \ slapd_shutdown = 2; \ } \ } while (0) @@ -194,6 +196,7 @@ static struct slap_daemon { # define SLAP_DEL_SOCK(s) do { \ int fd, rc, index = SLAP_SOCK_IX((s)); \ + if ( index < 0 ) break; \ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, \ (s), &SLAP_SOCK_EP((s))); \ slap_daemon.sd_epolls[index] = \ @@ -212,7 +215,7 @@ static struct slap_daemon { # define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT((i), EPOLLIN) # define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT((i), EPOLLOUT) # define SLAP_EVENT_IS_LISTENER(i) SLAP_EV_LISTENER(revents[(i)].data.ptr) -# define SLAP_EVENT_LISTENER(i) (revents[(i)].data.ptr) +# define SLAP_EVENT_LISTENER(i) ((Listener *)(revents[(i)].data.ptr)) # define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[(i)].data.ptr) @@ -279,7 +282,7 @@ static struct slap_daemon { if (!SLAP_SOCK_IS_WRITE(fd)) { FD_SET((fd), &slap_daemon.sd_writers); } \ } while(0) -# define SLAP_ADDTEST(s) do { } while 0 +# define SLAP_ADDTEST(s) # define SLAP_EVENT_MAX dtblsize # else # define SLAP_SOCK_SET_READ(fd) FD_SET((fd), &slap_daemon.sd_readers) @@ -451,18 +454,32 @@ static void slapd_add(ber_socket_t s, int isactive, Listener *sl) { #endif } +void slapd_sd_lock() +{ + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); +} + +void slapd_sd_unlock() +{ + ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); +} + /* * Remove the descriptor from daemon control */ void slapd_remove( ber_socket_t s, int wasactive, - int wake ) + int wake, + int locked ) { int waswriter; int wasreader; - ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + if ( !locked ) + ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); + + assert( SLAP_SOCK_IS_ACTIVE( s )); if ( wasactive ) slap_daemon.sd_nactives--; @@ -532,14 +549,18 @@ void slapd_set_write(ber_socket_t s, int wake) { WAKE_LISTENER(wake); } -void slapd_clr_read(ber_socket_t s, int wake) { +int slapd_clr_read(ber_socket_t s, int wake) { + int rc = 1; ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - assert( SLAP_SOCK_IS_ACTIVE( s )); - SLAP_SOCK_CLR_READ( s ); - + if ( SLAP_SOCK_IS_ACTIVE( s )) { + SLAP_SOCK_CLR_READ( s ); + rc = 0; + } ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - WAKE_LISTENER(wake); + if ( !rc ) + WAKE_LISTENER(wake); + return rc; } void slapd_set_read(ber_socket_t s, int wake) { @@ -690,7 +711,7 @@ static int slap_get_listener_addresses( snprintf(serv, sizeof serv, "%d", port); if ( (err = getaddrinfo(host, serv, &hints, &res)) ) { - Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n", + Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo() failed: %s\n", AC_GAI_STRERROR(err), 0, 0); return -1; } @@ -1077,21 +1098,6 @@ static int slap_open_listener( return -1; } -#ifdef LDAP_CONNECTIONLESS - if( l.sl_is_udp ) { - long id = connection_init( l.sl_sd, &l, "", "", CONN_IS_UDP, - (slap_ssf_t) 0, NULL ); - - if( id < 0 ) { - Debug( LDAP_DEBUG_TRACE, - "slap_open_listener: connectionless init failed on %s (%d)\n", - url, l.sl_sd, 0 ); - return -1; - } - l.sl_is_udp++; - } -#endif - Debug( LDAP_DEBUG_TRACE, "daemon: listener initialized %s\n", l.sl_url.bv_val, 0, 0 ); return 0; @@ -1178,6 +1184,10 @@ int slapd_daemon_init( const char *urls ) ldap_charray_free( u ); ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex ); +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_init( &slap_daemon.tcpd_mutex ); +#endif + return !i; } @@ -1197,6 +1207,11 @@ slapd_daemon_destroy(void) } #endif +#ifdef HAVE_TCPD + ldap_pvt_thread_mutex_destroy( &slap_daemon.tcpd_mutex ); +#endif + + ldap_pvt_thread_mutex_destroy( &slap_daemon.sd_mutex ); return 0; } @@ -1211,7 +1226,7 @@ close_listeners( Listener *lr = slap_listeners[l]; if ( lr->sl_sd != AC_SOCKET_INVALID ) { - if ( remove ) slapd_remove( lr->sl_sd, 0, 0 ); + if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 ); #ifdef LDAP_PF_LOCAL if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) { @@ -1453,20 +1468,25 @@ slap_listener( #endif /* SLAPD_RLOOKUPS */ #ifdef HAVE_TCPD - if ( !hosts_ctl("slapd", - dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, - peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, - SLAP_STRING_UNKNOWN )) { - /* DENY ACCESS */ - Statslog( LDAP_DEBUG_STATS, - "fd=%ld DENIED from %s (%s)\n", - (long) s, + int rc; + ldap_pvt_thread_mutex_lock( &slap_daemon.tcpd_mutex ); + rc = hosts_ctl("slapd", dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, - 0, 0 ); - slapd_close(s); - return 0; + SLAP_STRING_UNKNOWN ); + ldap_pvt_thread_mutex_unlock( &slap_daemon.tcpd_mutex ); + if ( !rc ) { + /* DENY ACCESS */ + Statslog( LDAP_DEBUG_STATS, + "fd=%ld DENIED from %s (%s)\n", + (long) s, + dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, + peeraddr != NULL ? peeraddr : SLAP_STRING_UNKNOWN, + 0, 0 ); + slapd_close(s); + return 0; + } } #endif /* HAVE_TCPD */ } @@ -1497,7 +1517,6 @@ slap_listener( id, (long) s, peername, sl->sl_name.bv_val, 0 ); - slapd_add( s, 1, NULL ); return 0; } @@ -1578,10 +1597,8 @@ slapd_daemon_task( * listening port. The listen() and accept() calls * are unnecessary. */ - if ( slap_listeners[l]->sl_is_udp ) { - slapd_add( slap_listeners[l]->sl_sd, 1, slap_listeners[l] ); + if ( slap_listeners[l]->sl_is_udp ) continue; - } #endif if ( listen( slap_listeners[l]->sl_sd, SLAPD_LISTEN_BACKLOG ) == -1 ) { @@ -1644,7 +1661,7 @@ slapd_daemon_task( } #ifdef HAVE_NT_SERVICE_MANAGER - if ( started_event != NULL ) } + if ( started_event != NULL ) { ldap_pvt_thread_cond_signal( &started_event ); } #endif @@ -1695,9 +1712,13 @@ slapd_daemon_task( ber_socket_t active; if( slapd_gentle_shutdown == 1 ) { + BackendDB *be; Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 ); close_listeners( 1 ); frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES; + LDAP_STAILQ_FOREACH(be, &backendDB, be_next) { + be->be_restrictops |= SLAP_RESTRICT_OP_WRITES; + } slapd_gentle_shutdown = 2; } @@ -1705,31 +1726,36 @@ slapd_daemon_task( active = slap_daemon.sd_nactives; ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); if( active == 0 ) { - slapd_shutdown = 2; + slapd_shutdown = 1; break; } } #endif - at = 0; ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); nwriters = slap_daemon.sd_nwriters; - SLAP_EVENT_INIT; for ( l = 0; slap_listeners[l] != NULL; l++ ) { Listener *lr = slap_listeners[l]; if ( lr->sl_sd == AC_SOCKET_INVALID ) continue; - if ( lr->sl_mute || lr->sl_busy ) { +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER + if ( lr->sl_mute || lr->sl_busy ) +#else + if ( lr->sl_mute ) +#endif + { SLAP_SOCK_CLR_READ( lr->sl_sd ); } else { SLAP_SOCK_SET_READ( lr->sl_sd ); } } + SLAP_EVENT_INIT; + nfds = SLAP_EVENT_MAX; if ( global_idletimeout && slap_daemon.sd_nactives ) at = 1; @@ -1788,12 +1814,14 @@ slapd_daemon_task( continue; } +#ifdef SLAP_LIGHTWEIGHT_DISPATCHER if ( lr->sl_busy ) { Debug( LDAP_DEBUG_CONNS, "daemon: select: listen=%d busy\n", lr->sl_sd, 0, 0 ); continue; } +#endif Debug( LDAP_DEBUG_CONNS, "daemon: select: listen=%d active_threads=%d tvp=%s\n", @@ -1845,14 +1873,11 @@ slapd_daemon_task( #if SLAP_EVENTS_ARE_INDEXED if ( SLAP_EVENT_IS_READ( wake_sds[0] )) { + char c[BUFSIZ]; SLAP_EVENT_CLR_READ( wake_sds[0] ); - ns--; - { - char c[BUFSIZ]; - tcp_read( wake_sds[0], c, sizeof(c) ); - } - Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 ); waking = 0; + tcp_read( wake_sds[0], c, sizeof(c) ); + Debug( LDAP_DEBUG_CONNS, "daemon: waked\n", 0, 0, 0 ); continue; } @@ -1953,7 +1978,7 @@ slapd_daemon_task( /* * NOTE: it is possible that the connection was closed * and that the stream is now inactive. - * connection_write() must validitate the stream is still + * connection_write() must validate the stream is still * active. */ if ( connection_write( wd ) < 0 ) { @@ -2007,18 +2032,10 @@ slapd_daemon_task( * 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. + * + * We now handle wake events when we see them; they are not given + * higher priority. */ - /* 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 ); @@ -2045,6 +2062,7 @@ slapd_daemon_task( r ? "r" : "", w ? "w" : "" ); } } + Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 ); #endif for (i=0; isl_is_udp ) { + continue; + } + + id = connection_init( lr->sl_sd, lr, "", "", CONN_IS_UDP, (slap_ssf_t) 0, NULL ); + + if( id < 0 ) { + Debug( LDAP_DEBUG_TRACE, + "connectionless_init: failed on %s (%d)\n", lr->sl_url, lr->sl_sd, 0 ); + return -1; + } + lr->sl_is_udp++; + } + + return 0; +} +#endif /* LDAP_CONNECTIONLESS */ + int slapd_daemon( void ) { int rc; connections_init(); +#ifdef LDAP_CONNECTIONLESS + connectionless_init(); +#endif #define SLAPD_LISTENER_THREAD 1 #if defined( SLAPD_LISTENER_THREAD )