Commit f4a2fdd4 authored by Nadezhda Ivanova's avatar Nadezhda Ivanova Committed by Ondřej Kuzník
Browse files

Fix a new backend not being operational if added via cn=config

parent 00806dd3
......@@ -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;
......
......@@ -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 );
}
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment