/* Cached part of struct stat for data.mdb. */
dev_t st_dev;
ino_t st_ino;
+ off_t st_size;
const char *mdb_data_path; /**< path to data.mdb, for convenience */
};
}
env->st_dev = st.st_dev;
env->st_ino = st.st_ino;
+ env->st_size = st.st_size;
+ if (env->st_size != env->mapsize)
+ kr_log_verbose("[cache] suspicious size of cache file: %zu != %zu\n",
+ (size_t)env->st_size, env->mapsize);
/* Open the database. */
MDB_txn *txn = NULL;
// FIXME: if the file doesn't exist?
}
if (st.st_dev == env->st_dev && st.st_ino == env->st_ino) {
- return kr_ok();
+ if (st.st_size == env->st_size)
+ return kr_ok();
+ kr_log_info("[cache] detected size change by another process: %zu -> %zu\n",
+ (size_t)env->st_size, (size_t)st.st_size);
+ int ret = cdb_commit(db, stats);
+ if (!ret) ret = lmdb_error(mdb_env_set_mapsize(env->env, st.st_size));
+ if (!ret) env->mapsize = st.st_size;
+ env->st_size = st.st_size; // avoid retrying in cycle even if it failed
+ return kr_error(ret);
}
kr_log_verbose("[cache] cache file has been replaced, reopening\n");
int ret = reopen_env(env, stats);
int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
knot_db_t ** libknot_db);
+/** A wrapper around kr_cdb_api::check_health that keeps libknot_db up to date.
+ * \return zero or negative error code. */
int kr_gc_cache_check_health(struct kr_cache *kres_db, knot_db_t ** libknot_db);
void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db);
#include "lib/defines.h"
#include "lib/utils.h"
#include <libknot/libknot.h>
+#include <lmdb.h>
#include "kresconfig.h"
#include "kr_cache_gc.h"
}
// ENOENT: kresd may not be started yet or cleared the cache now
- if (ret && ret != KNOT_ENOENT) {
+ // MDB_MAP_RESIZED: GC bailed out but on next iteration it should be OK
+ if (ret && ret != KNOT_ENOENT && ret != kr_error(MDB_MAP_RESIZED)) {
printf("Error (%s)\n", knot_strerror(ret));
exit_code = 10;
break;