From 3fcf293d7098e8373cff0088bcadc23b0b7f020c Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Wed, 9 Jun 2010 10:34:47 -0400 Subject: Properly check that the timeout event was created for cleanup/enum We need to make sure that if we didn't create the timeout, that we cancel the request so there's no chance of ending up with two enumerations/cleanups running simultaneously. We'll attempt to reschedule later, if possible. https://fedorahosted.org/sssd/ticket/524 --- src/providers/ldap/ldap_id_cleanup.c | 24 +++++++++++++++++++++++- src/providers/ldap/ldap_id_enum.c | 24 +++++++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c index 53c9501ff..330094f70 100644 --- a/src/providers/ldap/ldap_id_cleanup.c +++ b/src/providers/ldap/ldap_id_cleanup.c @@ -51,6 +51,7 @@ static void ldap_id_cleanup_timer(struct tevent_context *ev, struct tevent_timer *timeout; struct tevent_req *req; int delay; + errno_t ret; if (be_is_offline(ctx->be)) { DEBUG(4, ("Backend is marked offline, retry later!\n")); @@ -67,7 +68,10 @@ static void ldap_id_cleanup_timer(struct tevent_context *ev, /* schedule starting from now, not the last run */ delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT); tv = tevent_timeval_current_ofs(delay, 0); - ldap_id_cleanup_set_timer(ctx, tv); + ret = ldap_id_cleanup_set_timer(ctx, tv); + if (ret != EOK) { + DEBUG(1, ("Error setting up cleanup timer\n")); + } return; } tevent_req_set_callback(req, ldap_id_cleanup_reschedule, ctx); @@ -78,6 +82,24 @@ static void ldap_id_cleanup_timer(struct tevent_context *ev, tv = tevent_timeval_current_ofs(delay, 0); timeout = tevent_add_timer(ctx->be->ev, req, tv, ldap_id_cleanup_timeout, req); + if (timeout == NULL) { + /* If we can't guarantee a timeout, we + * need to cancel the request, to avoid + * the possibility of starting another + * concurrently + */ + talloc_zfree(req); + + DEBUG(1, ("Failed to schedule cleanup, retrying later!\n")); + /* schedule starting from now, not the last run */ + delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT); + tv = tevent_timeval_current_ofs(delay, 0); + ret = ldap_id_cleanup_set_timer(ctx, tv); + if (ret != EOK) { + DEBUG(1, ("Error setting up cleanup timer\n")); + } + return; + } return; } diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c index 89ca2de7a..95b35e0ca 100644 --- a/src/providers/ldap/ldap_id_enum.c +++ b/src/providers/ldap/ldap_id_enum.c @@ -54,6 +54,7 @@ static void ldap_id_enumerate_timer(struct tevent_context *ev, struct tevent_timer *timeout; struct tevent_req *req; int delay; + errno_t ret; if (be_is_offline(ctx->be)) { DEBUG(4, ("Backend is marked offline, retry later!\n")); @@ -70,7 +71,10 @@ static void ldap_id_enumerate_timer(struct tevent_context *ev, /* schedule starting from now, not the last run */ delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT); tv = tevent_timeval_current_ofs(delay, 0); - ldap_id_enumerate_set_timer(ctx, tv); + ret = ldap_id_enumerate_set_timer(ctx, tv); + if (ret != EOK) { + DEBUG(1, ("Error setting up enumerate timer\n")); + } return; } tevent_req_set_callback(req, ldap_id_enumerate_reschedule, ctx); @@ -81,6 +85,24 @@ static void ldap_id_enumerate_timer(struct tevent_context *ev, tv = tevent_timeval_current_ofs(delay, 0); timeout = tevent_add_timer(ctx->be->ev, req, tv, ldap_id_enumerate_timeout, req); + if (timeout == NULL) { + /* If we can't guarantee a timeout, we + * need to cancel the request, to avoid + * the possibility of starting another + * concurrently + */ + talloc_zfree(req); + + DEBUG(1, ("Failed to schedule enumeration, retrying later!\n")); + /* schedule starting from now, not the last run */ + delay = dp_opt_get_int(ctx->opts->basic, SDAP_ENUM_REFRESH_TIMEOUT); + tv = tevent_timeval_current_ofs(delay, 0); + ret = ldap_id_enumerate_set_timer(ctx, tv); + if (ret != EOK) { + DEBUG(1, ("Error setting up enumerate timer\n")); + } + return; + } return; } -- cgit