From 94190b07a92e2bdcd1d6e83588afc70bebf41494 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 9 Jan 2012 15:03:12 +0100 Subject: [PATCH 08/10] Split the logic to check cache expiration into separate function --- src/responder/common/responder.h | 5 +++ src/responder/common/responder_cmd.c | 51 ++++++++++++++++++++++++++++ src/responder/nss/nsssrv_cmd.c | 60 +++++++++------------------------ 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 0eabe647d40249355078334c8724f9f81f46370a..4a205c85bac635ee59e5855e896ae81122811101 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -169,6 +169,11 @@ errno_t setent_add_ref(TALLOC_CTX *memctx, void setent_notify(struct setent_req_list *list, errno_t err); void setent_notify_done(struct setent_req_list *list); +errno_t +sss_cmd_check_cache(struct ldb_message *msg, + int cache_refresh_percent, + uint64_t cache_expire); + typedef void (*sss_dp_callback_t)(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); diff --git a/src/responder/common/responder_cmd.c b/src/responder/common/responder_cmd.c index 28315e0605c9eda133ed663caee34c39c75dbc8b..f36ea14aff972237b954a3e8f0b26d97c8d17877 100644 --- a/src/responder/common/responder_cmd.c +++ b/src/responder/common/responder_cmd.c @@ -19,6 +19,7 @@ along with this program. If not, see . */ #include +#include "db/sysdb.h" #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" @@ -234,3 +235,53 @@ void setent_notify_done(struct setent_req_list *list) { return setent_notify(list, EOK); } + +/* + * Return values: + * EOK - cache hit + * EAGAIN - cache hit, but schedule off band update + * ENOENT - cache miss + */ +errno_t +sss_cmd_check_cache(struct ldb_message *msg, + int cache_refresh_percent, + uint64_t cache_expire) +{ + uint64_t lastUpdate; + uint64_t midpoint_refresh = 0; + time_t now; + + now = time(NULL); + lastUpdate = ldb_msg_find_attr_as_uint64(msg, SYSDB_LAST_UPDATE, 0); + midpoint_refresh = 0; + + if(cache_refresh_percent) { + midpoint_refresh = lastUpdate + + (cache_expire - lastUpdate)*cache_refresh_percent/100; + if (midpoint_refresh - lastUpdate < 10) { + /* If the percentage results in an expiration + * less than ten seconds after the lastUpdate time, + * that's too often we will simply set it to 10s + */ + midpoint_refresh = lastUpdate+10; + } + } + + if (cache_expire > now) { + /* cache still valid */ + + if (midpoint_refresh && midpoint_refresh < now) { + /* We're past the the cache refresh timeout + * We'll return the value from the cache, but we'll also + * queue the cache entry for update out-of-band. + */ + return EAGAIN; + } else { + /* Cache is still valid. */ + return EOK; + } + } + + /* Cache needs to be updated */ + return ENOENT; +} diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 43ae947c54ec9d9b39f0c7a4da26717ed6090296..e368e3ac6a7d4ad45ab1bcc4daaaefb849b58047 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -510,15 +510,11 @@ errno_t check_cache(struct nss_dom_ctx *dctx, void *pvt) { errno_t ret; - time_t now; - uint64_t lastUpdate; - uint64_t cacheExpire = 0; - uint64_t midpoint_refresh; struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; - bool off_band_update = false; struct tevent_req *req = NULL; struct dp_callback_ctx *cb_ctx = NULL; + uint64_t cacheExpire = 0; /* when searching for a user or netgroup, more than one reply is a * db error @@ -537,59 +533,37 @@ errno_t check_cache(struct nss_dom_ctx *dctx, /* if we have any reply let's check cache validity */ if (res->count > 0) { - - now = time(NULL); - - lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0], - SYSDB_LAST_UPDATE, 0); if (req_type == SSS_DP_INITGROUPS) { cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0], - SYSDB_INITGR_EXPIRE, 1); + SYSDB_INITGR_EXPIRE, 1); } if (cacheExpire == 0) { cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0], - SYSDB_CACHE_EXPIRE, 0); + SYSDB_CACHE_EXPIRE, 0); } - midpoint_refresh = 0; - if(nctx->cache_refresh_percent) { - midpoint_refresh = lastUpdate + - (cacheExpire - lastUpdate)*nctx->cache_refresh_percent/100; - if (midpoint_refresh - lastUpdate < 10) { - /* If the percentage results in an expiration - * less than ten seconds after the lastUpdate time, - * that's too often we will simply set it to 10s - */ - midpoint_refresh = lastUpdate+10; - } - } - - if (cacheExpire > now) { - /* cache still valid */ - - if (midpoint_refresh && midpoint_refresh < now) { - /* We're past the the cache refresh timeout - * We'll return the value from the cache, but we'll also - * queue the cache entry for update out-of-band. - */ - DEBUG(6, ("Performing midpoint cache update on [%s]\n", - opt_name)); - off_band_update = true; - } - else { - - /* Cache is still valid. Just return it. */ - return EOK; - } + /* if we have any reply let's check cache validity */ + ret = sss_cmd_check_cache(res->msgs[0], nctx->cache_refresh_percent, + cacheExpire); + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_FUNC, ("Cached entry is valid, returning..\n")); + return EOK; + } else if (ret != EAGAIN && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Error checking cache: %d\n", ret)); + goto error; } } - if (off_band_update) { + /* EAGAIN (off band) or ENOENT (cache miss) -> check cache */ + if (ret == EAGAIN) { /* No callback required * This was an out-of-band update. We'll return EOK * so the calling function can return the cached entry * immediately. */ + DEBUG(SSSDBG_TRACE_FUNC, + ("Performing midpoint cache update on [%s]\n", opt_name)); + req = sss_dp_get_account_send(cctx, cctx->rctx, dctx->domain, true, req_type, opt_name, opt_id, NULL); if (!req) { -- 1.7.7.6