diff options
author | Jan Zeleny <jzeleny@redhat.com> | 2012-06-20 13:42:06 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2012-08-01 16:19:41 +0200 |
commit | 10922e0293f3ebf056708acacce35e93fe07747e (patch) | |
tree | cefb07a15c1166acbc3c16911cd2bfc551aae975 /src/providers/ldap | |
parent | bbd33e46aa6194c1086939f7cf8538c067186455 (diff) | |
download | sssd-10922e0293f3ebf056708acacce35e93fe07747e.tar.gz sssd-10922e0293f3ebf056708acacce35e93fe07747e.tar.bz2 sssd-10922e0293f3ebf056708acacce35e93fe07747e.zip |
Primary server support: support for "disconnecting" connections in LDAP
This patch adds support for marking existing connections as being
disconnected. Each such connection can't be used for new queries and a
new one has to be created instead if necessary. This will ensure that
pending operations will end gracefully during reconnection. Also all new
queries to the server we are reconnecting to will use another (probably
newly created) connection.
Diffstat (limited to 'src/providers/ldap')
-rw-r--r-- | src/providers/ldap/sdap_id_op.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c index d4f6fe34..3036d0cc 100644 --- a/src/providers/ldap/sdap_id_op.c +++ b/src/providers/ldap/sdap_id_op.c @@ -72,9 +72,14 @@ struct sdap_id_conn_data { int notify_lock; /* list of operations using connect */ struct sdap_id_op *ops; + /* A flag which is signalizing that this + * connection will be disconnected and should + * not be used any more */ + bool disconnecting; }; static void sdap_id_conn_cache_be_offline_cb(void *pvt); +static void sdap_id_conn_cache_fo_reconnect_cb(void *pvt); static void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data); static int sdap_id_conn_data_destroy(struct sdap_id_conn_data *conn_data); @@ -118,6 +123,14 @@ int sdap_id_conn_cache_create(TALLOC_CTX *memctx, goto fail; } + ret = be_add_reconnect_cb(conn_cache, id_ctx->be, + sdap_id_conn_cache_fo_reconnect_cb, conn_cache, + NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("be_add_reconnect_cb failed.\n")); + goto fail; + } + *conn_cache_out = conn_cache; return EOK; @@ -139,6 +152,18 @@ static void sdap_id_conn_cache_be_offline_cb(void *pvt) } } +/* Callback for attempt to reconnect to primary server */ +static void sdap_id_conn_cache_fo_reconnect_cb(void *pvt) +{ + struct sdap_id_conn_cache *conn_cache = talloc_get_type(pvt, struct sdap_id_conn_cache); + struct sdap_id_conn_data *cached_connection = conn_cache->cached_connection; + + /* Release any cached connection on going offline */ + if (cached_connection != NULL) { + cached_connection->disconnecting = true; + } +} + /* Release sdap_id_conn_data and destroy it if no longer needed */ static void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data) { @@ -194,7 +219,8 @@ static bool sdap_can_reuse_connection(struct sdap_id_conn_data *conn_data) { int timeout; - if (!conn_data || !conn_data->sh || !conn_data->sh->connected) { + if (!conn_data || !conn_data->sh || + !conn_data->sh->connected || conn_data->disconnecting) { return false; } @@ -721,6 +747,7 @@ int sdap_id_op_connect_recv(struct tevent_req *req, int *dp_error) int sdap_id_op_done(struct sdap_id_op *op, int retval, int *dp_err_out) { bool communication_error; + struct sdap_id_conn_data *current_conn = op->conn_data; switch (retval) { case EIO: case ETIMEDOUT: @@ -733,8 +760,8 @@ int sdap_id_op_done(struct sdap_id_op *op, int retval, int *dp_err_out) break; } - if (communication_error && op->conn_data != 0 - && op->conn_data == op->conn_cache->cached_connection) { + if (communication_error && current_conn != 0 + && current_conn == op->conn_cache->cached_connection) { /* do not reuse failed connection */ op->conn_cache->cached_connection = NULL; @@ -774,9 +801,15 @@ int sdap_id_op_done(struct sdap_id_op *op, int retval, int *dp_err_out) op->reconnect_retry_count = 0; } - if (op->conn_data) { + if (current_conn) { DEBUG(9, ("releasing operation connection\n")); sdap_id_op_hook_conn_data(op, NULL); + + if (current_conn->ops == NULL || current_conn->disconnecting) { + DEBUG(SSSDBG_TRACE_FUNC, ("Connection is marked for " + "disconnection, executing ...\n")); + sdap_id_release_conn_data(current_conn); + } } *dp_err_out = dp_err; |