int ret = cache_op(cache, read, &key, &val, 1);
if (ret == 0 && val.len == sizeof(CACHE_VERSION)
&& memcmp(val.data, &CACHE_VERSION, sizeof(CACHE_VERSION)) == 0) {
- ret = kr_error(EEXIST);
+ ret = kr_ok();
} else {
int oldret = ret;
/* Version doesn't match. Recreate cache and write version key. */
/**
* Clear all items from the cache.
* @param cache cache structure
- * @return 0 or an errcode
+ * @return if nonzero is returned, there's a big problem - you probably want to abort(),
+ * perhaps except for kr_error(EAGAIN) which probably indicates transient errors.
*/
KR_EXPORT
int kr_cache_clear(struct kr_cache *cache);
/* Find if we get a lock on lockfile. */
ret = open(lockfile, O_CREAT|O_EXCL|O_RDONLY, S_IRUSR);
if (ret == -1) {
- kr_log_error("[cache] clearing failed to get ./.cachelock; retry later\n");
+ kr_log_error("[cache] clearing failed to get ./.cachelock (%s); retry later\n",
+ strerror(errno));
/* As we're out of space (almost certainly - mdb_drop didn't work),
* we will retry on the next failing write operation. */
- return kr_error(errno);
+ return kr_error(EAGAIN);
}
close(ret);
{
int ret = cache_op(cache, write, key, val, 1);
if (!ret) return kr_ok();
- /* Clear cache if overfull. Using kres-cache-gc service should prevent this. */
- if (ret == kr_error(ENOSPC)) {
- ret = kr_cache_clear(cache);
- const char *msg = "[cache] clearing because overfull, ret = %d\n";
- if (ret) {
- kr_log_error(msg, ret);
- } else {
- kr_log_info(msg, ret);
- ret = kr_error(ENOSPC);
- }
- return ret;
+
+ if (ret != kr_error(ENOSPC)) { /* failing a write isn't too bad */
+ VERBOSE_MSG(qry, "=> failed backend write, ret = %d\n", ret);
+ return kr_error(ret);
+ }
+
+ /* Cache is overfull. Using kres-cache-gc service should prevent this.
+ * As a fallback, try clearing it. */
+ ret = kr_cache_clear(cache);
+ switch (ret) {
+ default:
+ kr_log_error("CRITICAL: clearing cache failed with %s\n",
+ kr_strerror(ret));
+ abort();
+ case 0:
+ kr_log_info("[cache] overfull cache cleared\n");
+ case -EAGAIN: // fall-through; .cachelock race -> retry later
+ return kr_error(ENOSPC);
}
- VERBOSE_MSG(qry, "=> failed backend write, ret = %d\n", ret);
- return kr_error(ret ? ret : ENOSPC);
}