>From ed10a190a5705b9b2b095afd65758f177356de9d Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 21 Aug 2013 03:37:47 +0200 Subject: [PATCH 05/12] LDAP: Make cleanup synchronous The LDAP cleanup request was asynchronous for no good reason, probably a leftover from the days of async sysdb. This patch makes it sychronous again, removing a lot of uneeded code. --- src/providers/ldap/ldap_common.h | 1 + src/providers/ldap/ldap_id_cleanup.c | 157 ++++++----------------------------- src/providers/ldap/sdap_async_enum.c | 26 ++---- 3 files changed, 34 insertions(+), 150 deletions(-) diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 7ba8e95571854dfbb2e1eb4faf24c992f41b68f4..1dd69f4e253f9bcf1162b8e0212eeac59ec621fe 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -168,6 +168,7 @@ int ldap_get_autofs_options(TALLOC_CTX *memctx, errno_t ldap_setup_enumeration(struct sdap_id_ctx *ctx, struct sdap_id_conn_ctx *conn, struct sdap_domain *sdom); +errno_t ldap_id_cleanup(struct sdap_id_ctx *ctx); int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv); void sdap_mark_offline(struct sdap_id_ctx *ctx); diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c index 534e2ee015d157a26798c5b14fdd3e8d9a156b63..85c0139dbb9ff2d72b4e132b73b3bd4c8d56aab0 100644 --- a/src/providers/ldap/ldap_id_cleanup.c +++ b/src/providers/ldap/ldap_id_cleanup.c @@ -33,23 +33,11 @@ #include "providers/ldap/sdap_async.h" /* ==Cleanup-Task========================================================= */ - -struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx); -static void ldap_id_cleanup_reschedule(struct tevent_req *req); - -static void ldap_id_cleanup_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval tv, void *pvt); - static void ldap_id_cleanup_timer(struct tevent_context *ev, struct tevent_timer *tt, struct timeval tv, void *pvt) { struct sdap_id_ctx *ctx = talloc_get_type(pvt, struct sdap_id_ctx); - struct tevent_timer *timeout; - struct tevent_req *req; int delay; errno_t ret; @@ -62,89 +50,20 @@ static void ldap_id_cleanup_timer(struct tevent_context *ev, return; } - req = ldap_id_cleanup_send(ctx, ev, ctx); - if (!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; - } - tevent_req_set_callback(req, ldap_id_cleanup_reschedule, ctx); - - /* if cleanup takes so long, either we try to cleanup too - * frequently, or something went seriously wrong */ - delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT); - 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; -} - -static void ldap_id_cleanup_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); - struct sdap_id_ctx *ctx = tevent_req_callback_data(req, - struct sdap_id_ctx); - int delay; - - delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT); - DEBUG(1, ("Cleanup timed out! Timeout too small? (%ds)!\n", delay)); - - tv = tevent_timeval_current_ofs(delay, 0); - ldap_id_cleanup_set_timer(ctx, tv); - - talloc_zfree(req); -} - -static void ldap_id_cleanup_reschedule(struct tevent_req *req) -{ - struct sdap_id_ctx *ctx = tevent_req_callback_data(req, - struct sdap_id_ctx); - enum tevent_req_state tstate; - uint64_t err; - struct timeval tv; - int delay; - - if (tevent_req_is_error(req, &tstate, &err)) { + ret = ldap_id_cleanup(ctx); + if (ret != EOK) { /* On error schedule starting from now, not the last run */ tv = tevent_timeval_current(); } else { tv = ctx->last_purge; } - talloc_zfree(req); delay = dp_opt_get_int(ctx->opts->basic, SDAP_CACHE_PURGE_TIMEOUT); tv = tevent_timeval_add(&tv, delay, 0); ldap_id_cleanup_set_timer(ctx, tv); + ctx->last_purge = tevent_timeval_current(); } - - int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv) { struct tevent_timer *cleanup_task; @@ -162,80 +81,58 @@ int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv) return EOK; } - - -struct global_cleanup_state { - struct tevent_context *ev; - struct sdap_id_ctx *ctx; -}; - static int cleanup_users(TALLOC_CTX *memctx, struct sdap_id_ctx *ctx); static int cleanup_groups(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain); -struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx) +errno_t ldap_id_cleanup(struct sdap_id_ctx *ctx) { - struct global_cleanup_state *state; - struct tevent_req *req; - int ret; + int ret, tret; bool in_transaction = false; + TALLOC_CTX *tmp_ctx; - req = tevent_req_create(memctx, &state, struct global_cleanup_state); - if (!req) return NULL; + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } - state->ev = ev; - state->ctx = ctx; - - ctx->last_purge = tevent_timeval_current(); - - ret = sysdb_transaction_start(state->ctx->be->domain->sysdb); + ret = sysdb_transaction_start(ctx->be->domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n")); - goto fail; + goto done; } in_transaction = true; - ret = cleanup_users(state, state->ctx); + ret = cleanup_users(tmp_ctx, ctx); if (ret && ret != ENOENT) { - goto fail; + goto done; } - ret = cleanup_groups(state, - state->ctx->be->domain->sysdb, - state->ctx->be->domain); + ret = cleanup_groups(tmp_ctx, + ctx->be->domain->sysdb, + ctx->be->domain); if (ret) { - goto fail; + goto done; } - ret = sysdb_transaction_commit(state->ctx->be->domain->sysdb); + ret = sysdb_transaction_commit(ctx->be->domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n")); - goto fail; + goto done; } in_transaction = false; - tevent_req_done(req); - tevent_req_post(req, ev); - return req; - -fail: - DEBUG(1, ("Failed to cleanup caches (%d [%s]), retrying later!\n", - (int)ret, strerror(ret))); + ret = EOK; +done: if (in_transaction) { - ret = sysdb_transaction_cancel(state->ctx->be->domain->sysdb); - if (ret != EOK) { - DEBUG(1, ("Could not cancel transaction\n")); - tevent_req_error(req, ret); - tevent_req_post(req, ev); - return req; + tret = sysdb_transaction_cancel(ctx->be->domain->sysdb); + if (tret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n")); } } - tevent_req_done(req); - tevent_req_post(req, ev); - return req; + talloc_free(tmp_ctx); + return ret; } diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c index ab6ae0773141157743977aba36a9115ce02be3cb..b34b801a3a6257ebc6f53d4b1970dba95ec2bb9f 100644 --- a/src/providers/ldap/sdap_async_enum.c +++ b/src/providers/ldap/sdap_async_enum.c @@ -31,10 +31,6 @@ #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_idmap.h" -extern struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx); - static struct tevent_req *enum_users_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, @@ -67,7 +63,6 @@ static void sdap_dom_enum_conn_done(struct tevent_req *subreq); static void sdap_dom_enum_users_done(struct tevent_req *subreq); static void sdap_dom_enum_groups_done(struct tevent_req *subreq); static void sdap_dom_enum_services_done(struct tevent_req *subreq); -static void sdap_dom_enum_cleanup_done(struct tevent_req *subreq); struct tevent_req * sdap_dom_enum_send(TALLOC_CTX *memctx, @@ -316,27 +311,18 @@ static void sdap_dom_enum_services_done(struct tevent_req *subreq) } if (state->purge) { - subreq = ldap_id_cleanup_send(state, state->ev, state->ctx); - if (!subreq) { - tevent_req_error(req, ENOMEM); - return; + ret = ldap_id_cleanup(state->ctx); + if (ret != EOK) { + /* Not fatal, worst case we'll have stale entries that would be + * removed on a subsequent online lookup + */ + DEBUG(SSSDBG_MINOR_FAILURE, ("Cleanup failed: %d\n", ret)); } - - tevent_req_set_callback(subreq, sdap_dom_enum_cleanup_done, req); - return; } tevent_req_done(req); } -static void sdap_dom_enum_cleanup_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - talloc_zfree(subreq); - tevent_req_done(req); -} - errno_t sdap_dom_enum_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); -- 1.8.3.1