summaryrefslogtreecommitdiffstats
path: root/src/providers/fail_over.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2011-12-20 16:30:02 +0100
committerStephen Gallagher <sgallagh@redhat.com>2011-12-20 13:37:28 -0500
commitb8ecc581cdd8c7d097bf9db67a4cb220fbbcff6d (patch)
tree113391828a6066980c3156ec936958efd272f3bd /src/providers/fail_over.c
parentf76cb01f05f7c1764028084b166f65c3ff4e670f (diff)
downloadsssd-b8ecc581cdd8c7d097bf9db67a4cb220fbbcff6d.tar.gz
sssd-b8ecc581cdd8c7d097bf9db67a4cb220fbbcff6d.tar.xz
sssd-b8ecc581cdd8c7d097bf9db67a4cb220fbbcff6d.zip
Failover: Introduce a per-service timeout
https://fedorahosted.org/sssd/ticket/976
Diffstat (limited to 'src/providers/fail_over.c')
-rw-r--r--src/providers/fail_over.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 5cfc1a41c..637b5b4d3 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -141,6 +141,7 @@ fo_context_init(TALLOC_CTX *mem_ctx, struct fo_options *opts)
ctx->opts->srv_retry_timeout = opts->srv_retry_timeout;
ctx->opts->retry_timeout = opts->retry_timeout;
ctx->opts->family_order = opts->family_order;
+ ctx->opts->service_resolv_timeout = opts->service_resolv_timeout;
DEBUG(3, ("Created new fail over context, retry timeout is %d\n",
ctx->opts->retry_timeout));
@@ -735,10 +736,13 @@ struct resolve_service_state {
struct resolv_ctx *resolv;
struct tevent_context *ev;
+ struct tevent_timer *timeout_handler;
struct fo_ctx *fo_ctx;
};
+static errno_t fo_resolve_service_activate_timeout(struct tevent_req *req,
+ struct tevent_context *ev, const unsigned long timeout_seconds);
static void fo_resolve_service_cont(struct tevent_req *subreq);
static void fo_resolve_service_done(struct tevent_req *subreq);
static bool fo_resolve_service_server(struct tevent_req *req);
@@ -777,6 +781,14 @@ fo_resolve_service_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
goto done;
}
+ /* Activate per-service timeout handler */
+ ret = fo_resolve_service_activate_timeout(req, ev,
+ ctx->opts->service_resolv_timeout);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not set service timeout\n"));
+ goto done;
+ }
+
if (fo_is_srv_lookup(server)) {
/* Don't know the server yet, must do a SRV lookup */
subreq = resolve_srv_send(state, ev, resolv,
@@ -810,6 +822,40 @@ done:
static void set_server_common_status(struct server_common *common,
enum server_status status);
+static void
+fo_resolve_service_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval tv, void *pvt)
+{
+ struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
+
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Service resolving timeout reached\n"));
+ tevent_req_error(req, ETIMEDOUT);
+}
+
+static errno_t
+fo_resolve_service_activate_timeout(struct tevent_req *req,
+ struct tevent_context *ev,
+ const unsigned long timeout_seconds)
+{
+ struct timeval tv;
+ struct resolve_service_state *state = tevent_req_data(req,
+ struct resolve_service_state);
+
+ tv = tevent_timeval_current();
+ tv = tevent_timeval_add(&tv, timeout_seconds, 0);
+ state->timeout_handler = tevent_add_timer(ev, state, tv,
+ fo_resolve_service_timeout, req);
+ if (state->timeout_handler == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_add_timer failed.\n"));
+ return ENOMEM;
+ }
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Resolve timeout set to %lu seconds\n",
+ timeout_seconds));
+ return EOK;
+}
+
/* SRV resolving finished, see if we got server to work with */
static void
fo_resolve_service_cont(struct tevent_req *subreq)