From: Vladimír Čunát Date: Wed, 28 Apr 2021 10:53:26 +0000 (+0200) Subject: cache: clear any stale readers when opening cache X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bfc14a88fd0a494c22365374d88c36ef5725e20a;p=thirdparty%2Fknot-resolver.git cache: clear any stale readers when opening cache (cherry picked from commit 39d373272b1bfb4e438d790d4bbe4162fb927ea7) --- diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c index 5f4db061c..706cd80e7 100644 --- a/lib/cache/cdb_lmdb.c +++ b/lib/cache/cdb_lmdb.c @@ -124,6 +124,18 @@ static int refresh_mapsize(struct lmdb_env *env) return kr_ok(); } +static void clear_stale_readers(struct lmdb_env *env) +{ + int cleared; + int ret = mdb_reader_check(env->env, &cleared); + if (ret != MDB_SUCCESS) { + kr_log_error("[cache] failed to clear stale reader locks: " + "LMDB error %d %s\n", ret, mdb_strerror(ret)); + } else if (cleared != 0) { + kr_log_info("[cache] cleared %d stale reader locks\n", cleared); + } +} + #define FLAG_RENEW (2*MDB_RDONLY) /** mdb_txn_begin or _renew + handle retries in some situations * @@ -154,13 +166,7 @@ retry: if (ret == 0) goto retry; } else if (unlikely(ret == MDB_READERS_FULL)) { - int cleared; - ret = mdb_reader_check(env->env, &cleared); - if (ret == MDB_SUCCESS) - kr_log_info("[cache] cleared %d stale reader locks\n", cleared); - else - kr_log_error("[cache] failed to clear stale reader locks: " - "LMDB error %d %s\n", ret, mdb_strerror(ret)); + clear_stale_readers(env); goto retry; } return ret; @@ -389,6 +395,11 @@ static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t map ret = mdb_txn_commit(txn); if (ret != MDB_SUCCESS) goto error_mdb; + /* Stale RO transactions could have been left behind by a cashing process + * (e.g. one whose termination lead to spawning the current one). + * According to docs they might hold onto some space until we clear them. */ + clear_stale_readers(env); + return kr_ok(); error_mdb: