summaryrefslogtreecommitdiffstats
path: root/usr.sbin/nscd/cachelib.c
diff options
context:
space:
mode:
authorse <se@FreeBSD.org>2012-07-04 09:02:12 +0000
committerse <se@FreeBSD.org>2012-07-04 09:02:12 +0000
commit8b8c2303a1367a15ab7a322db29473fd4b7f5e89 (patch)
tree1159be7852686e97260b128780be12bec0efb726 /usr.sbin/nscd/cachelib.c
parente5f970ed4ae0b5e770b2a67c389d8eb77ec82993 (diff)
downloadFreeBSD-src-8b8c2303a1367a15ab7a322db29473fd4b7f5e89.zip
FreeBSD-src-8b8c2303a1367a15ab7a322db29473fd4b7f5e89.tar.gz
Add the possibility to specify a threshold for the number of negative cache
results required to have the cache return lookup failure. A new configuration parameter is introduced, which must be set to a value greater than 1 to activate this feature. The default behavior is unchanged. The purpose of this change is to allow probes for the existence of an entry (which are expected to fail), before that entry is added to one of the queried databases, without the cache returning the stale information from the probe query until that cache entry expires. If, for example, a new user account is created after checking that the new account name is available, the negative cache entry would prevent immediate access to the account. For that example, the new configuration option negative-confidence-threshold passwd 2 will require a second negative query result to consider the negative cache entry for a passwd entry valid, but if the user account has been created between the queries, then the positive query result from the second query will be cached and returned.
Diffstat (limited to 'usr.sbin/nscd/cachelib.c')
-rw-r--r--usr.sbin/nscd/cachelib.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/usr.sbin/nscd/cachelib.c b/usr.sbin/nscd/cachelib.c
index afdbc0a..ab95b29 100644
--- a/usr.sbin/nscd/cachelib.c
+++ b/usr.sbin/nscd/cachelib.c
@@ -726,6 +726,12 @@ cache_read(struct cache_entry_ *entry, const char *key, size_t key_size,
TRACE_OUT(cache_read);
return (-1);
}
+ /* pretend that entry was not found if confidence is below threshold*/
+ if (find_res->confidence <
+ common_entry->common_params.confidence_threshold) {
+ TRACE_OUT(cache_read);
+ return (-1);
+ }
if ((common_entry->common_params.max_lifetime.tv_sec != 0) ||
(common_entry->common_params.max_lifetime.tv_usec != 0)) {
@@ -826,6 +832,24 @@ cache_write(struct cache_entry_ *entry, const char *key, size_t key_size,
item = HASHTABLE_GET_ENTRY(&(common_entry->items), hash);
find_res = HASHTABLE_ENTRY_FIND(cache_ht_, item, &item_data);
if (find_res != NULL) {
+ if (find_res->confidence < common_entry->common_params.confidence_threshold) {
+ /* duplicate entry is no error, if confidence is low */
+ if ((find_res->value_size == value_size) &&
+ (memcmp(find_res->value, value, value_size) == 0)) {
+ /* increase confidence on exact match (key and values) */
+ find_res->confidence++;
+ } else {
+ /* create new entry with low confidence, if value changed */
+ free(item_data.value);
+ item_data.value = malloc(value_size);
+ assert(item_data.value != NULL);
+ memcpy(item_data.value, value, value_size);
+ item_data.value_size = value_size;
+ find_res->confidence = 1;
+ }
+ TRACE_OUT(cache_write);
+ return (0);
+ }
TRACE_OUT(cache_write);
return (-1);
}
@@ -839,6 +863,8 @@ cache_write(struct cache_entry_ *entry, const char *key, size_t key_size,
memcpy(item_data.value, value, value_size);
item_data.value_size = value_size;
+ item_data.confidence = 1;
+
policy_item = common_entry->policies[0]->create_item_func();
policy_item->key = item_data.key;
policy_item->key_size = item_data.key_size;
OpenPOWER on IntegriCloud