]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Convert the load balancer into a backend
authorNadezhda Ivanova <nivanova@symas.com>
Mon, 5 Feb 2018 09:04:02 +0000 (11:04 +0200)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:58:14 +0000 (17:58 +0000)
doc/man/man5/lloadd.conf.5
doc/man/man8/lloadd.8
servers/lloadd/config.c
servers/lloadd/daemon.c
servers/lloadd/init.c
servers/lloadd/module_init.c
servers/lloadd/proto-lload.h
tests/data/lloadd-anon.conf
tests/data/lloadd-backend-issues.conf
tests/data/lloadd.conf
tests/data/slapd-lload.conf

index 24044cf1519f1e3de591bb0b88b6bffcd2517fd1..d8b50d5d7cc8e81cde6a3e9663e0726b09c5e0e8 100644 (file)
@@ -29,18 +29,13 @@ is as follows:
 .nf
     # comment - these options apply to the server as a whole
     <global configuration options>
-    # first backend definition & configuration options
-    backend <backend 1 definition>
-    <configuration options specific to backend 1>
-    # subsequent backend definitions & configuration options
+    # first backend definition
+    backend-server <backend 1 definition>
+    # 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 "<listen URIs>"
+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 <filename>
 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]://<hostname>[:port]
 .B [retry=<retry interval in ms>]
 .B [keepalive=<idle>:<probes>:<interval>]
@@ -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
index cf1c0859a4a56a9a9a096403accc34ffdd758c05..ccf3f3c14427b42f608a150e002442ac92f7599e 100644 (file)
@@ -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"
index b2f26404f816f3b2d9aab450140573e73b296426..aa29ef84eef34883767d27ad37d5d558bab42a0a 100644 (file)
 /*
  * 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=<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 */
index a03c3ea3f9664e75542278f7497e241028adfab2..d6dcb343440271e2e85452138aa541754df4a843 100644 (file)
 
 #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 <sys/stat.h>
 /* this should go in <ldap.h> 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 );
 
index 52b76fadc6465d01f66d36d46933e3b9d1cbf75c..189d6cdcb58fed67cc850ef7ddb97be1e2d7722d 100644 (file)
@@ -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 )
index e38e8888c7e40acc52fbf41fddeba2b66779cc5e..5ff03a86906139f67db8fbcda17f7f19b0e6d9f3 100644 (file)
@@ -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 )
index c6d4be17a43759c243008ba9f7e1e2b6449f459e..d686cc95024ff98ed95f04b127dfc00b51903f4c 100644 (file)
@@ -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 */
index 0a3ec0fe39052d97d222a890b538282e6af7d037..6064335b4065406c8c16cd895f7f7752d4c1bcdb 100644 (file)
 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
index 93ab68bff82ae8bd54853a7bb1224a1e398f693b..b55442699ae49db09b964e20539e13a7a275d9f9 100644 (file)
@@ -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
index 890f420de2ce9968c2cf40f8e17a7ea62f3655fe..e825e0e551694b6cbef0acda1fd5436b7cabcce0 100644 (file)
@@ -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
index 8ac942a96e4d39dc1afb7b4bff87e16ea216bee7..239749ac4e9b9083b142fe6fe40654661f7603a2 100644 (file)
@@ -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