From f4a2fdd400ab3f7ddeaf63e01bbf62546a76404c Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Wed, 18 Apr 2018 17:55:30 +0300 Subject: [PATCH] Fix a new backend not being operational if added via cn=config --- servers/lloadd/config.c | 75 +++++++++++++++++--------------- servers/lloadd/daemon.c | 95 ++++++++++++++++++----------------------- servers/lloadd/lload.h | 17 +++++--- 3 files changed, 93 insertions(+), 94 deletions(-) diff --git a/servers/lloadd/config.c b/servers/lloadd/config.c index 9eb63910a4..701eddc328 100644 --- a/servers/lloadd/config.c +++ b/servers/lloadd/config.c @@ -751,9 +751,6 @@ config_generic( ConfigArgs *c ) enum lcf_daemon flag = 0; int rc = LDAP_SUCCESS; - lload_change.type = c->op; - lload_change.object = LLOAD_DAEMON; - if ( c->op == SLAP_CONFIG_EMIT ) { switch ( c->type ) { case CFG_IOTHREADS: @@ -800,6 +797,9 @@ config_generic( ConfigArgs *c ) return rc; } + lload_change.type = LLOAD_CHANGE_MODIFY; + lload_change.object = LLOAD_DAEMON; + switch ( c->type ) { case CFG_CONCUR: ldap_pvt_thread_set_concurrency( c->value_uint ); @@ -1136,9 +1136,6 @@ config_bindconf( ConfigArgs *c ) { int i; - lload_change.type = c->op; - lload_change.object = LLOAD_DAEMON; - if ( c->op == SLAP_CONFIG_EMIT ) { struct berval bv; @@ -1161,6 +1158,10 @@ config_bindconf( ConfigArgs *c ) return LDAP_SUCCESS; } + lload_change.type = LLOAD_CHANGE_MODIFY; + lload_change.object = LLOAD_DAEMON; + lload_change.flags.daemon |= LLOAD_DAEMON_MOD_BINDCONF; + for ( i = 1; i < c->argc; i++ ) { if ( lload_bindconf_parse( c->argv[i], &bindconf ) ) { Debug( LDAP_DEBUG_ANY, "config_bindconf: " @@ -1821,16 +1822,18 @@ config_feature( ConfigArgs *c ) slap_mask_t mask = 0; int i; - lload_change.type = c->op; + if ( c->op == SLAP_CONFIG_EMIT ) { + return mask_to_verbs( features, lload_features, &c->rvalue_vals ); + } + + lload_change.type = LLOAD_CHANGE_MODIFY; lload_change.object = LLOAD_DAEMON; lload_change.flags.daemon |= LLOAD_DAEMON_MOD_FEATURES; if ( !lload_change.target ) { lload_change.target = (void *)(uintptr_t)~lload_features; } - if ( c->op == SLAP_CONFIG_EMIT ) { - return mask_to_verbs( features, lload_features, &c->rvalue_vals ); - } else if ( c->op == LDAP_MOD_DELETE ) { + if ( c->op == LDAP_MOD_DELETE ) { if ( !c->line ) { /* Last value has been deleted */ lload_features = 0; @@ -1883,14 +1886,10 @@ config_tls_cleanup( ConfigArgs *c ) static int config_tls_option( ConfigArgs *c ) { - int flag, rc; + int flag; int berval = 0; LDAP *ld = lload_tls_ld; - lload_change.type = c->op; - lload_change.object = LLOAD_DAEMON; - lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS; - switch ( c->type ) { case CFG_TLS_RAND: flag = LDAP_OPT_X_TLS_RANDOM_FILE; @@ -1943,16 +1942,19 @@ config_tls_option( ConfigArgs *c ) if ( c->op == SLAP_CONFIG_EMIT ) { return ldap_pvt_tls_get_option( ld, flag, berval ? (void *)&c->value_bv : (void *)&c->value_string ); - } else if ( c->op == LDAP_MOD_DELETE ) { - config_push_cleanup( c, config_tls_cleanup ); + } + + lload_change.type = LLOAD_CHANGE_MODIFY; + lload_change.object = LLOAD_DAEMON; + lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS; + + config_push_cleanup( c, config_tls_cleanup ); + if ( c->op == LDAP_MOD_DELETE ) { return ldap_pvt_tls_set_option( ld, flag, NULL ); } if ( !berval ) ch_free( c->value_string ); - config_push_cleanup( c, config_tls_cleanup ); - rc = ldap_pvt_tls_set_option( + return ldap_pvt_tls_set_option( ld, flag, berval ? (void *)&c->value_bv : (void *)c->argv[1] ); - if ( berval ) ch_free( c->value_bv.bv_val ); - return rc; } /* FIXME: this ought to be provided by libldap */ @@ -1961,10 +1963,6 @@ config_tls_config( ConfigArgs *c ) { int i, flag; - lload_change.type = c->op; - lload_change.object = LLOAD_DAEMON; - lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS; - switch ( c->type ) { case CFG_TLS_CRLCHECK: flag = LDAP_OPT_X_TLS_CRLCHECK; @@ -1983,13 +1981,18 @@ config_tls_config( ConfigArgs *c ) } if ( c->op == SLAP_CONFIG_EMIT ) { return lload_tls_get_config( lload_tls_ld, flag, &c->value_string ); - } else if ( c->op == LDAP_MOD_DELETE ) { + } + + lload_change.type = LLOAD_CHANGE_MODIFY; + lload_change.object = LLOAD_DAEMON; + lload_change.flags.daemon |= LLOAD_DAEMON_MOD_TLS; + + config_push_cleanup( c, config_tls_cleanup ); + if ( c->op == LDAP_MOD_DELETE ) { int i = 0; - config_push_cleanup( c, config_tls_cleanup ); return ldap_pvt_tls_set_option( lload_tls_ld, flag, &i ); } ch_free( c->value_string ); - config_push_cleanup( c, config_tls_cleanup ); if ( isdigit( (unsigned char)c->argv[1][0] ) && c->type != CFG_TLS_PROTOCOL_MIN ) { if ( lutil_atoi( &i, c->argv[1] ) != 0 ) { @@ -3500,10 +3503,6 @@ backend_cf_gen( ConfigArgs *c ) assert( b != NULL ); - lload_change.type = c->op; - lload_change.object = LLOAD_BACKEND; - lload_change.target = b; - if ( c->op == SLAP_CONFIG_EMIT ) { switch ( c->type ) { case CFG_URI: @@ -3602,6 +3601,14 @@ backend_cf_gen( ConfigArgs *c ) rc = 1; break; } + + /* do not set this if it has already been set by another callback, e.g. + * lload_backend_ldadd */ + if ( lload_change.type == LLOAD_CHANGE_UNDEFINED ) { + lload_change.type = LLOAD_CHANGE_MODIFY; + } + lload_change.object = LLOAD_BACKEND; + lload_change.target = b; lload_change.flags.backend |= flag; config_push_cleanup( c, lload_backend_finish ); @@ -3665,7 +3672,7 @@ lload_backend_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ) * save the new config when done with the entry */ ca->lineno = 0; - lload_change.type = LDAP_REQ_ADD; + lload_change.type = LLOAD_CHANGE_ADD; lload_change.object = LLOAD_BACKEND; lload_change.target = b; @@ -3678,7 +3685,7 @@ lload_backend_lddel( CfEntryInfo *ce, Operation *op ) { LloadBackend *b = ce->ce_private; - lload_change.type = op->o_tag; + lload_change.type = LLOAD_CHANGE_DEL; lload_change.object = LLOAD_BACKEND; lload_change.target = b; diff --git a/servers/lloadd/daemon.c b/servers/lloadd/daemon.c index 841d423e64..f0616c911d 100644 --- a/servers/lloadd/daemon.c +++ b/servers/lloadd/daemon.c @@ -1439,7 +1439,7 @@ daemon_wakeup_cb( evutil_socket_t sig, short what, void *arg ) event_del( lload_daemon[tid].wakeup_event ); } -LloadChange lload_change = { .type = LLOAD_UNDEFINED }; +LloadChange lload_change = { .type = LLOAD_CHANGE_UNDEFINED }; #ifdef BALANCER_MODULE int @@ -1475,7 +1475,7 @@ lload_handle_backend_invalidation( LloadChange *change ) assert( change->object == LLOAD_BACKEND ); - if ( change->type == LDAP_REQ_ADD ) { + if ( change->type == LLOAD_CHANGE_ADD ) { BackendInfo *mi = backend_info( "monitor" ); if ( mi ) { @@ -1490,7 +1490,7 @@ lload_handle_backend_invalidation( LloadChange *change ) } backend_retry( b ); return; - } else if ( change->type == LDAP_REQ_DELETE ) { + } else if ( change->type == LLOAD_CHANGE_DEL ) { ldap_pvt_thread_pool_walk( &connection_pool, handle_pdus, backend_conn_cb, b ); ldap_pvt_thread_pool_walk( @@ -1504,8 +1504,7 @@ lload_handle_backend_invalidation( LloadChange *change ) lload_backend_destroy( b ); return; } - assert( change->type == LDAP_REQ_MODIFY ); - assert( change->flags.generic != 0 ); + assert( change->type == LLOAD_CHANGE_MODIFY ); /* * A change that can't be handled gracefully, terminate all connections and @@ -1628,52 +1627,10 @@ lload_handle_backend_invalidation( LloadChange *change ) } } -void -lload_handle_bindconf_invalidation( LloadChange *change ) -{ - LloadBackend *b; - LloadConnection *c; - - assert( change->type == LDAP_REQ_MODIFY ); - assert( change->object == LLOAD_BINDCONF ); - - change->flags.bindconf &= ~LLOAD_BINDCONF_MOD_TIMEOUTS; - - if ( !change->flags.bindconf ) { - /* Nothing needs doing, things will generally fall into place */ - return; - } - - /* - * Only timeout changes can be handled gracefully, terminate all - * connections and start over. - */ - ldap_pvt_thread_pool_walk( - &connection_pool, handle_pdus, backend_conn_cb, NULL ); - ldap_pvt_thread_pool_walk( - &connection_pool, upstream_bind, backend_conn_cb, NULL ); - - LDAP_CIRCLEQ_FOREACH ( b, &backend, b_next ) { - backend_reset( b ); - backend_retry( b ); - } - - /* Reconsider the PRIVILEGED flag on all clients */ - LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) { - int privileged = ber_bvstrcasecmp( &c->c_auth, &lloadd_identity ); - - /* We have just terminated all pending operations (even pins), there - * should be no connections still binding/closing */ - assert( c->c_state == LLOAD_C_READY ); - - c->c_type = privileged ? LLOAD_C_PRIVILEGED : LLOAD_C_OPEN; - } -} - void lload_handle_global_invalidation( LloadChange *change ) { - assert( change->type == LDAP_REQ_MODIFY ); + assert( change->type == LLOAD_CHANGE_MODIFY ); assert( change->object == LLOAD_DAEMON ); if ( change->flags.daemon & LLOAD_DAEMON_MOD_THREADS ) { @@ -1747,12 +1704,45 @@ lload_handle_global_invalidation( LloadChange *change ) } } } + + if ( change->flags.daemon & LLOAD_DAEMON_MOD_BINDCONF ) { + LloadBackend *b; + LloadConnection *c; + + /* + * Only timeout changes can be handled gracefully, terminate all + * connections and start over. + */ + ldap_pvt_thread_pool_walk( + &connection_pool, handle_pdus, backend_conn_cb, NULL ); + ldap_pvt_thread_pool_walk( + &connection_pool, upstream_bind, backend_conn_cb, NULL ); + + LDAP_CIRCLEQ_FOREACH ( b, &backend, b_next ) { + ldap_pvt_thread_mutex_lock( &b->b_mutex ); + backend_reset( b ); + backend_retry( b ); + ldap_pvt_thread_mutex_unlock( &b->b_mutex ); + } + + /* Reconsider the PRIVILEGED flag on all clients */ + LDAP_CIRCLEQ_FOREACH ( c, &clients, c_next ) { + int privileged = ber_bvstrcasecmp( &c->c_auth, &lloadd_identity ); + + /* We have just terminated all pending operations (even pins), there + * should be no connections still binding/closing */ + assert( c->c_state == LLOAD_C_READY ); + + c->c_type = privileged ? LLOAD_C_PRIVILEGED : LLOAD_C_OPEN; + } + } } int lload_handle_invalidation( LloadChange *change ) { - if ( change->type == LDAP_REQ_MODIFY && change->flags.generic == 0 ) { + if ( (change->type == LLOAD_CHANGE_MODIFY) && + change->flags.generic == 0 ) { Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: " "a modify where apparently nothing changed\n" ); } @@ -1764,9 +1754,6 @@ lload_handle_invalidation( LloadChange *change ) case LLOAD_DAEMON: lload_handle_global_invalidation( change ); break; - case LLOAD_BINDCONF: - lload_handle_bindconf_invalidation( change ); - break; default: Debug( LDAP_DEBUG_ANY, "lload_handle_invalidation: " "unrecognised change\n" ); @@ -1796,7 +1783,7 @@ lload_pause_base( struct event_base *base ) void lload_pause_server( void ) { - LloadChange ch = { .type = LLOAD_UNDEFINED }; + LloadChange ch = { .type = LLOAD_CHANGE_UNDEFINED }; int i; lload_pause_base( listener_base ); @@ -1812,7 +1799,7 @@ lload_pause_server( void ) void lload_unpause_server( void ) { - if ( lload_change.type != LLOAD_UNDEFINED ) { + if ( lload_change.type != LLOAD_CHANGE_UNDEFINED ) { lload_handle_invalidation( &lload_change ); } diff --git a/servers/lloadd/lload.h b/servers/lloadd/lload.h index ee2a5f4cc4..02e18b702e 100644 --- a/servers/lloadd/lload.h +++ b/servers/lloadd/lload.h @@ -106,10 +106,19 @@ typedef int lload_cf_aux_table_parse_x( struct berval *val, typedef struct LloadListener LloadListener; +enum lc_type { + LLOAD_CHANGE_UNDEFINED = 0, + LLOAD_CHANGE_MODIFY, + LLOAD_CHANGE_ADD, + LLOAD_CHANGE_DEL, +}; + enum lc_object { LLOAD_UNDEFINED = 0, LLOAD_DAEMON, + /* LLOAD_BINDCONF, + */ LLOAD_BACKEND, }; @@ -119,10 +128,7 @@ enum lcf_daemon { LLOAD_DAEMON_MOD_TLS = 1 << 2, LLOAD_DAEMON_MOD_LISTENER_ADD = 1 << 3, LLOAD_DAEMON_MOD_LISTENER_REPLACE = 1 << 4, -}; - -enum lcf_bindconf { - LLOAD_BINDCONF_MOD_TIMEOUTS = 1 << 0, + LLOAD_DAEMON_MOD_BINDCONF = 1 << 5, }; enum lcf_backend { @@ -131,12 +137,11 @@ enum lcf_backend { }; struct LloadChange { - ber_tag_t type; + enum lc_type type; enum lc_object object; union { int generic; enum lcf_daemon daemon; - enum lcf_bindconf bindconf; enum lcf_backend backend; } flags; void *target;