From 678fa100f7d5a935335ea9898901b317dcfbfc88 Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Mon, 5 Feb 2018 11:04:02 +0200 Subject: [PATCH] Convert the load balancer into a backend --- doc/man/man5/lloadd.conf.5 | 38 +++++++--- doc/man/man8/lloadd.8 | 8 +- servers/lloadd/config.c | 102 +++++++++++++++++++++++--- servers/lloadd/daemon.c | 39 ++++------ servers/lloadd/init.c | 5 +- servers/lloadd/module_init.c | 54 +++++++++++--- servers/lloadd/proto-lload.h | 6 +- tests/data/lloadd-anon.conf | 6 +- tests/data/lloadd-backend-issues.conf | 8 +- tests/data/lloadd.conf | 6 +- tests/data/slapd-lload.conf | 6 +- 11 files changed, 202 insertions(+), 76 deletions(-) diff --git a/doc/man/man5/lloadd.conf.5 b/doc/man/man5/lloadd.conf.5 index 24044cf151..d8b50d5d7c 100644 --- a/doc/man/man5/lloadd.conf.5 +++ b/doc/man/man5/lloadd.conf.5 @@ -29,18 +29,13 @@ is as follows: .nf # comment - these options apply to the server as a whole - # first backend definition & configuration options - backend - - # subsequent backend definitions & configuration options + # first backend definition + backend-server + # subsequent backend definitions ... .fi .LP -As many backend-specific sections as desired may be included. Global -options can be overridden in a backend (for options that appear more -than once, the last appearance in the -.B lloadd.conf -file is used). +As many backend servers may be configured as desired. .LP If a line begins with white space, it is considered a continuation of the previous line. No physical line should be over 2000 bytes @@ -61,6 +56,23 @@ Global Configuration Options and General Backend Options. Refer to the "OpenLDAP Administrator's Guide" for more details on the lloadd configuration file. +.SH SLAPD INTEGRATION +Note that when +.B lloadd +is configured as a +.B slapd +module, any option that shares the same name as an option in +.BR slapd.conf (5), +the +.B slapd +interpretation wins. An additional option is available in this case: +.TP +.B listen "" +The URIs the Load Balancer module should listen on. Must not overlap with the +ones that +.B slapd +uses for its own listening sockets. + .SH GLOBAL CONFIGURATION OPTIONS Options described in this section apply to all backends, unless specifically overridden in a backend definition. Arguments that should be replaced by @@ -124,6 +136,7 @@ configured in .\" connections anymore. .PD .RE +.RE .TP .B include Read additional configuration information from the given file before @@ -589,7 +602,7 @@ in effect. .SH BACKEND OPTIONS .TP -.B backend +.B backend-server .B uri=ldap[s]://[:port] .B [retry=] .B [keepalive=::] @@ -720,7 +733,7 @@ bindconf binddn=cn=test credentials=pass -backend +backend-server uri=ldap://ldap1.example.com numconns=3 bindconns=2 @@ -728,7 +741,7 @@ backend max-pending-ops=5 conn-max-pending=3 -backend +backend-server uri=ldap://ldap2.example.com numconns=3 bindconns=2 @@ -749,6 +762,7 @@ default lloadd configuration file .SH SEE ALSO .BR ldap (3), .BR gnutls\-cli (1), +.BR slapd.conf (5), .BR lloadd (8), .BR slapd (8). .LP diff --git a/doc/man/man8/lloadd.8 b/doc/man/man8/lloadd.8 index cf1c0859a4..ccf3f3c144 100644 --- a/doc/man/man8/lloadd.8 +++ b/doc/man/man8/lloadd.8 @@ -224,7 +224,9 @@ loadable module. In that case, it can be loaded as such: .LP .nf .ft tt - moduleload path/to/lloadd.la lloadd.conf "listening URLs" + moduleload path/to/lloadd.la + backend lload + listen "listening URLs" .ft .fi @@ -280,7 +282,9 @@ put the following in your slapd.conf (or its equivalent in cn=config): .LP .nf .ft tt - moduleload lloadd.la /var/tmp/lloadd.conf "ldap://:1389 ldaps://" + moduleload lloadd.la + backend lload + listen "ldap://:1389 ldaps://" .ft .fi .SH "SEE ALSO" diff --git a/servers/lloadd/config.c b/servers/lloadd/config.c index b2f26404f8..aa29ef84ee 100644 --- a/servers/lloadd/config.c +++ b/servers/lloadd/config.c @@ -60,12 +60,19 @@ /* * defaults for various global variables */ +#ifdef BALANCER_MODULE +char *listeners_list = NULL; +#else /* !BALANCER_MODULE */ slap_mask_t global_allows = 0; slap_mask_t global_disallows = 0; int global_gentlehup = 0; int global_idletimeout = 0; char *global_host = NULL; +char *slapd_pid_file = NULL; +char *slapd_args_file = NULL; +#endif /* !BALANCER_MODULE */ + static FILE *logfile; static char *logfileName; @@ -83,9 +90,6 @@ struct timeval *lload_timeout_api = NULL; struct timeval *lload_timeout_net = NULL; struct timeval *lload_write_timeout = &timeout_write_tv; -char *slapd_pid_file = NULL; -char *slapd_args_file = NULL; - static int fp_getline( FILE *fp, ConfigArgs *c ); static void fp_getline_init( ConfigArgs *c ); @@ -131,6 +135,7 @@ enum { CFG_ACL = 1, CFG_BACKEND, CFG_BINDCONF, + CFG_LISTEN, CFG_TLS_RAND, CFG_TLS_CIPHER, CFG_TLS_PROTOCOL_MIN, @@ -147,6 +152,8 @@ enum { CFG_LOGFILE, CFG_MIRRORMODE, CFG_IOTHREADS, + CFG_MAXBUF_CLIENT, + CFG_MAXBUF_UPSTREAM, CFG_THREADQS, CFG_TLS_ECNAME, CFG_TLS_CACERT, @@ -177,15 +184,25 @@ static ConfigTable config_back_cf_table[] = { &config_generic, NULL, NULL, NULL }, - { "backend", "backend options", 2, 0, 0, + { "backend-server", "backend options", 2, 0, 0, ARG_MAGIC|CFG_BACKEND, &config_backend, - NULL, NULL, NULL + "( OLcfgBkAt:13.1 " + "NAME 'olcBkLloadBackend' " + "DESC 'Lload backend configuration options' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL }, { "bindconf", "backend credentials", 2, 0, 0, ARG_MAGIC|CFG_BINDCONF, &config_bindconf, - NULL, NULL, NULL + "( OLcfgBkAt:13.2 " + "NAME 'olcBkLloadBindconf' " + "DESC 'Backend credentials' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL }, { "gentlehup", "on|off", 2, 2, 0, #ifdef SIGHUP @@ -200,7 +217,13 @@ static ConfigTable config_back_cf_table[] = { { "idletimeout", "timeout", 2, 2, 0, ARG_INT, &global_idletimeout, - NULL, NULL, NULL + "( OLcfgBkAt:13.3 " + "NAME 'olcBkLloadIdleTimeout' " + "DESC 'Connection idle timeout' " + "EQUALITY integerMatch " + "SYNTAX OMsInteger " + "SINGLE-VALUE )", + NULL, NULL }, { "include", "file", 2, 2, 0, ARG_MAGIC, @@ -210,8 +233,25 @@ static ConfigTable config_back_cf_table[] = { { "io-threads", "count", 2, 0, 0, ARG_UINT|ARG_MAGIC|CFG_IOTHREADS, &config_generic, - NULL, NULL, NULL + "( OLcfgBkAt:13.4 " + "NAME 'olcBkLloadIOThreads' " + "DESC 'I/O threads' " + "SYNTAX OMsInteger " + "SINGLE-VALUE )", + NULL, NULL }, +#ifdef BALANCER_MODULE + { "listen", "uri list", 2, 2, 0, + ARG_STRING|CFG_LISTEN, + &listeners_list, + "( OLcfgBkAt:13.5 " + "NAME 'olcBkLloadListen' " + "DESC 'A list of listener adresses' " + "SYNTAX OMsDirectoryString " + "SINGLE-VALUE )", + NULL, NULL + }, +#endif /* BALANCER_MODULE */ { "logfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_LOGFILE, &config_generic, @@ -233,14 +273,24 @@ static ConfigTable config_back_cf_table[] = { NULL, NULL, NULL }, { "sockbuf_max_incoming_client", "max", 2, 2, 0, - ARG_BER_LEN_T, + ARG_BER_LEN_T|CFG_MAXBUF_CLIENT, &sockbuf_max_incoming_client, - NULL, NULL, NULL + "( OLcfgBkAt:13.6 " + "NAME 'olcBkLloadSockbufMaxClient' " + "DESC 'The maximum LDAP PDU size accepted coming from clients' " + "SYNTAX OMsInteger " + "SINGLE-VALUE )", + NULL, NULL }, { "sockbuf_max_incoming_upstream", "max", 2, 2, 0, ARG_BER_LEN_T, &sockbuf_max_incoming_upstream, - NULL, NULL, NULL + "( OLcfgBkAt:13.7 " + "NAME 'olcBkLloadSockbufMaxUpstream' " + "DESC 'The maximum LDAP PDU size accepted coming from upstream' " + "SYNTAX OMsInteger " + "SINGLE-VALUE )", + NULL, NULL }, { "tcp-buffer", "[listener=] [{read|write}=]size", 0, 0, 0, #ifdef LDAP_TCP_BUFFER @@ -431,6 +481,25 @@ static ConfigTable config_back_cf_table[] = { { NULL, NULL, 0, 0, 0, ARG_IGNORED, NULL } }; +#ifdef BALANCER_MODULE +static ConfigOCs lloadocs[] = { + { "( OLcfgBkOc:13.1 " + "NAME 'olcLloadConfig' " + "DESC 'Lload backend configuration' " + "SUP olcBackendConfig " + "MAY ( olcBkLloadBackend " + "$ olcBkLloadBindconf " + "$ olcBkLloadIOThreads " + "$ olcBkLloadListen " + "$ olcBkLloadSockbufMaxClient " + "$ olcBkLloadSockbufMaxUpstream " + ") )", + Cft_Backend, config_back_cf_table, + NULL, NULL }, + { NULL, 0, NULL } +}; +#endif /* BALANCER_MODULE */ + static int config_generic( ConfigArgs *c ) { @@ -1886,12 +1955,14 @@ slap_verbmasks_destroy( slap_verbmasks *v ) return 0; } +#ifndef BALANCER_MODULE int config_push_cleanup( ConfigArgs *ca, ConfigDriver *cleanup ) { /* Stub, cleanups only run in online config */ return 0; } +#endif /* !BALANCER_MODULE */ static slap_verbmasks tlskey[] = { { BER_BVC("no"), LLOAD_CLEARTEXT }, @@ -2832,8 +2903,15 @@ lload_config_check_my_url( const char *url, LDAPURLDesc *lud ) return NULL; } +#ifdef BALANCER_MODULE int lload_back_init_cf( BackendInfo *bi ) { - return 0; + /* Make sure we don't exceed the bits reserved for userland */ + config_check_userland( CFG_LAST ); + + bi->bi_cf_ocs = lloadocs; + + return config_register_schema( config_back_cf_table, lloadocs ); } +#endif /* BALANCER_MODULE */ diff --git a/servers/lloadd/daemon.c b/servers/lloadd/daemon.c index a03c3ea3f9..d6dcb34344 100644 --- a/servers/lloadd/daemon.c +++ b/servers/lloadd/daemon.c @@ -45,17 +45,13 @@ #include "ldap_rq.h" -#ifdef HAVE_TCPD -int allow_severity = LOG_INFO; -int deny_severity = LOG_NOTICE; -#endif /* TCP Wrappers */ - #ifdef LDAP_PF_LOCAL #include /* this should go in as soon as it is accepted */ #define LDAPI_MOD_URLEXT "x-mod" #endif /* LDAP_PF_LOCAL */ +#ifndef BALANCER_MODULE #ifdef LDAP_PF_INET6 int slap_inet4or6 = AF_UNSPEC; #else /* ! INETv6 */ @@ -66,17 +62,24 @@ int slap_inet4or6 = AF_INET; time_t starttime; struct runqueue_s slapd_rq; +#ifdef LDAP_TCP_BUFFER +int slapd_tcp_rmem; +int slapd_tcp_wmem; +#endif /* LDAP_TCP_BUFFER */ + +volatile sig_atomic_t slapd_shutdown = 0; +volatile sig_atomic_t slapd_gentle_shutdown = 0; +volatile sig_atomic_t slapd_abrupt_shutdown = 0; +#endif /* !BALANCER_MODULE */ + +static int emfile; + #ifndef SLAPD_MAX_DAEMON_THREADS #define SLAPD_MAX_DAEMON_THREADS 16 #endif int lload_daemon_threads = 1; int lload_daemon_mask; -#ifdef LDAP_TCP_BUFFER -int slapd_tcp_rmem; -int slapd_tcp_wmem; -#endif /* LDAP_TCP_BUFFER */ - struct event_base *listener_base = NULL; LloadListener **lload_listeners = NULL; static ldap_pvt_thread_t listener_tid, *daemon_tid; @@ -97,20 +100,6 @@ lload_global_stats_t lload_stats; #define DAEMON_ID(fd) ( fd & lload_daemon_mask ) -static int emfile; - -static volatile int waking; -#define WAKE_DAEMON( l, w ) \ - do { \ - if ( w ) { \ - event_active( lload_daemon[l].wakeup_event, EV_WRITE, 0 ); \ - } \ - } while (0) - -volatile sig_atomic_t slapd_shutdown = 0; -volatile sig_atomic_t slapd_gentle_shutdown = 0; -volatile sig_atomic_t slapd_abrupt_shutdown = 0; - #ifdef HAVE_WINSOCK ldap_pvt_thread_mutex_t slapd_ws_mutex; SOCKET *slapd_ws_sockets; @@ -1390,7 +1379,7 @@ lload_sig_shutdown( evutil_socket_t sig, short what, void *arg ) } for ( i = 0; i < lload_daemon_threads; i++ ) { - WAKE_DAEMON( i, 1 ); + event_base_loopexit( lload_daemon[i].base, NULL ); } event_base_loopexit( daemon_base, NULL ); diff --git a/servers/lloadd/init.c b/servers/lloadd/init.c index 52b76fadc6..189d6cdcb5 100644 --- a/servers/lloadd/init.c +++ b/servers/lloadd/init.c @@ -37,6 +37,7 @@ #include "ldap_rq.h" +#ifndef BALANCER_MODULE /* * read-only global variables or variables only written by the listener * thread (after they are initialized) - no need to protect them with a mutex. @@ -61,8 +62,10 @@ int connection_pool_max = SLAP_MAX_WORKER_THREADS; int connection_pool_queues = 1; int slap_tool_thread_max = 1; -static const char *lload_name = NULL; int slapMode = SLAP_UNDEFINED_MODE; +#endif /* !BALANCER_MODULE */ + +static const char *lload_name = NULL; int lload_init( int mode, const char *name ) diff --git a/servers/lloadd/module_init.c b/servers/lloadd/module_init.c index e38e8888c7..5ff03a8690 100644 --- a/servers/lloadd/module_init.c +++ b/servers/lloadd/module_init.c @@ -149,14 +149,8 @@ lload_module_start_daemon( void *ctx, void *arg ) } int -init_module( int argc, char *argv[] ) +lload_back_open( BackendInfo *bi ) { - if ( argc != 2 ) { - Debug( LDAP_DEBUG_CONFIG, "lloadd: " - "incorrect number of arguments to module\n" ); - return -1; - } - if ( slapMode & SLAP_TOOL_MODE ) { return 0; } @@ -170,19 +164,55 @@ init_module( int argc, char *argv[] ) } #endif /* HAVE_TLS */ - if ( lloadd_daemon_init( argv[1] ) != 0 ) { + if ( lloadd_daemon_init( listeners_list ) != 0 ) { return -1; } lload_conn_pool_init(); - if ( lload_read_config( argv[0], NULL ) != 0 ) { - return -1; - } - if ( lload_monitor_initialize() != 0 ) { return -1; } return ldap_pvt_thread_pool_submit( &connection_pool, lload_module_start_daemon, NULL ); + + return 0; } + +int +lload_back_initialize( BackendInfo *bi ) +{ + bi->bi_flags = SLAP_BFLAG_STANDALONE; + bi->bi_open = lload_back_open; + bi->bi_config = config_generic_wrapper; + bi->bi_close = 0; + bi->bi_destroy = 0; + + bi->bi_db_init = 0; + bi->bi_db_config = 0; + bi->bi_db_open = 0; + bi->bi_db_close = 0; + bi->bi_db_destroy = 0; + + bi->bi_op_bind = 0; + bi->bi_op_unbind = 0; + bi->bi_op_search = 0; + bi->bi_op_compare = 0; + bi->bi_op_modify = 0; + bi->bi_op_modrdn = 0; + bi->bi_op_add = 0; + bi->bi_op_delete = 0; + bi->bi_op_abandon = 0; + + bi->bi_extended = 0; + + bi->bi_chk_referrals = 0; + + bi->bi_connection_init = 0; + bi->bi_connection_destroy = 0; + + lload_back_init_cf( bi ); + return 0; +} + +SLAP_BACKEND_INIT_MODULE( lload ) diff --git a/servers/lloadd/proto-lload.h b/servers/lloadd/proto-lload.h index c6d4be17a4..d686cc9502 100644 --- a/servers/lloadd/proto-lload.h +++ b/servers/lloadd/proto-lload.h @@ -77,6 +77,9 @@ LDAP_SLAPD_F (int) lload_bindconf_parse( const char *word, slap_bindconf *bc ); LDAP_SLAPD_F (int) lload_bindconf_unparse( slap_bindconf *bc, struct berval *bv ); LDAP_SLAPD_F (int) lload_bindconf_tls_set( slap_bindconf *bc, LDAP *ld ); LDAP_SLAPD_F (void) lload_bindconf_free( slap_bindconf *bc ); +#ifdef BALANCER_MODULE +LDAP_SLAPD_F (int) lload_back_init_cf( BackendInfo *bi ); +#endif /* * connection.c @@ -103,6 +106,7 @@ LDAP_SLAPD_F (void) lload_sig_shutdown( evutil_socket_t sig, short what, void *a LDAP_SLAPD_V (struct evdns_base *) dnsbase; LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown; +LDAP_SLAPD_V (volatile sig_atomic_t) slapd_gentle_shutdown; LDAP_SLAPD_V (int) lloadd_inited; LDAP_SLAPD_V (struct event *) lload_timeout_event; @@ -190,7 +194,7 @@ LDAP_SLAPD_V (int) lber_debug; LDAP_SLAPD_V (int) ldap_syslog; LDAP_SLAPD_V (lload_global_stats_t) lload_stats; - +LDAP_SLAPD_V (char *) listeners_list; LDAP_END_DECL #endif /* PROTO_LLOAD_H */ diff --git a/tests/data/lloadd-anon.conf b/tests/data/lloadd-anon.conf index 0a3ec0fe39..6064335b40 100644 --- a/tests/data/lloadd-anon.conf +++ b/tests/data/lloadd-anon.conf @@ -17,21 +17,21 @@ sockbuf_max_incoming_client 4194303 sockbuf_max_incoming_upstream 4194303 -backend uri=@URI2@ +backend-server uri=@URI2@ numconns=3 bindconns=2 retry=5000 max-pending-ops=5 conn-max-pending=3 -backend uri=@URI3@ +backend-server uri=@URI3@ numconns=3 bindconns=2 retry=5000 max-pending-ops=5 conn-max-pending=3 -backend uri=@URI4@ +backend-server uri=@URI4@ numconns=3 bindconns=2 retry=5000 diff --git a/tests/data/lloadd-backend-issues.conf b/tests/data/lloadd-backend-issues.conf index 93ab68bff8..b55442699a 100644 --- a/tests/data/lloadd-backend-issues.conf +++ b/tests/data/lloadd-backend-issues.conf @@ -23,7 +23,7 @@ bindconf credentials=secret # incorrect password (DB is empty) -backend uri=@URI2@ +backend-server uri=@URI2@ numconns=3 bindconns=2 retry=500 @@ -31,7 +31,7 @@ backend uri=@URI2@ conn-max-pending=3 # backend is often unresponsive -backend uri=@URI3@ +backend-server uri=@URI3@ numconns=3 bindconns=2 retry=500 @@ -39,7 +39,7 @@ backend uri=@URI3@ conn-max-pending=3 # unreachable backend (not running) -backend uri=@URI4@ +backend-server uri=@URI4@ numconns=3 bindconns=2 retry=500 @@ -47,7 +47,7 @@ backend uri=@URI4@ conn-max-pending=3 # backend that fails to resolve -backend uri=ldap://does.not.resolve.example.com +backend-server uri=ldap://does.not.resolve.example.com numconns=3 bindconns=2 retry=500 diff --git a/tests/data/lloadd.conf b/tests/data/lloadd.conf index 890f420de2..e825e0e551 100644 --- a/tests/data/lloadd.conf +++ b/tests/data/lloadd.conf @@ -24,21 +24,21 @@ bindconf binddn="cn=Manager,dc=example,dc=com" credentials=secret -backend uri=@URI2@ +backend-server uri=@URI2@ numconns=3 bindconns=3 retry=5000 max-pending-ops=20 conn-max-pending=3 -backend uri=@URI3@ +backend-server uri=@URI3@ numconns=3 bindconns=3 retry=5000 max-pending-ops=20 conn-max-pending=3 -backend uri=@URI4@ +backend-server uri=@URI4@ numconns=3 bindconns=3 retry=5000 diff --git a/tests/data/slapd-lload.conf b/tests/data/slapd-lload.conf index 8ac942a96e..239749ac4e 100644 --- a/tests/data/slapd-lload.conf +++ b/tests/data/slapd-lload.conf @@ -28,6 +28,10 @@ argsfile @TESTDIR@/slapd.1.args sockbuf_max_incoming 4194303 modulepath ../servers/lloadd/ -moduleload lloadd.la @TESTDIR@/slapd.1.conf.lloadd "@URI1@" +moduleload lloadd.la + +backend lload +listen "@URI1@" +include @TESTDIR@/slapd.1.conf.lloadd database monitor