summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/responder/common/responder.h5
-rw-r--r--src/responder/common/responder_cmd.c51
-rw-r--r--src/responder/nss/nsssrv_cmd.c60
3 files changed, 73 insertions, 43 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 0eabe647..4a205c85 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 28315e06..f36ea14a 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 <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
+#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 43ae947c..e368e3ac 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);
- }
-
- 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;
- }
+ SYSDB_CACHE_EXPIRE, 0);
}
- 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) {