]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
gc: fix integer overflow when computing how much to GC
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 9 Jun 2020 06:09:32 +0000 (08:09 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Mon, 29 Jun 2020 12:25:32 +0000 (14:25 +0200)
On 32-bit systems the insufficient GC could commonly happen:
https://lists.nic.cz/pipermail/knot-resolver-users/2020/000265.html

The meaning of -f parameter got slightly changed, so that the buggy
computation could be greatly simplified.  GC seems to make sense when
most of cache space is used, in which case the difference is small.

NEWS
utils/cache_gc/kr_cache_gc.c
utils/cache_gc/kr_cache_gc.h
utils/cache_gc/main.c

diff --git a/NEWS b/NEWS
index fe2ebe2a8669b08f567c6369381b427785685143..ffa0c5e10e202db46ba715594e8bdfb408f286d9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ Bugfixes
 - tls: send alert to peer if handshake fails (!1007)
 - cache: fix interaction between LMDB locks and preallocation (!1013)
 - cache garbage collector: fix flushing of messages to logs (!1009)
+- cache garbage collector: fix insufficient GC on 32-bit systems (!1009)
 
 
 Knot Resolver 5.1.1 (2020-05-19)
index 6ba8aad684144c026e13c1ff690e29f83cc3e0e8..a4c0495998e392225b55543544300dd1e1e9a411 100644 (file)
@@ -217,8 +217,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
        for (int i = 0; i < CATEGORIES; ++i) {
                cats_sumsize += cats.categories_sizes[i];
        }
-       ssize_t amount_tofree = knot_db_lmdb_get_mapsize(db) * cfg->cache_to_be_freed
-           * cats_sumsize / (100 * knot_db_lmdb_get_usage(db));
+       /* use less precise variant to avoid 32-bit overflow */
+       ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
 
 #ifdef DEBUG
        printf("tofree: %zd\n", amount_tofree);
index 261115d00ea1ea3dcb20ff7273eebb5bd19f0728..839e553d5bdc7f0438765371bc5b762f628ba413 100644 (file)
@@ -25,7 +25,7 @@ typedef struct {
        unsigned long rw_txn_delay;     // waiting time between two RW transactions in usecs
 
        uint8_t cache_max_usage;        // maximum cache usage before triggering GC (percent)
-       uint8_t cache_to_be_freed;      // percent of cache to be freed during GC
+       uint8_t cache_to_be_freed;      // percent of current cache usage to be freed during GC
 
        bool dry_run;
 } kr_cache_gc_cfg_t;
index cd868553fcf393d914a7ebb091ed0da987a55cb2..41654c8438f260d61e26de7d39b69abcae5748e5 100644 (file)
@@ -36,7 +36,7 @@ static void print_help()
        printf(" -l <deletes_per_txn>\n");
        printf(" -m <rw_txn_duration(usecs)>\n");
        printf(" -u <cache_max_usage(percent)>\n");
-       printf(" -f <cache_to_be_freed(percent)>\n");
+       printf(" -f <cache_to_be_freed(percent-of-current-usage)>\n");
        printf(" -w <wait_next_rw_txn(usecs)>\n");
        printf(" -t <temporary_memory(MBytes)>\n");
        printf(" -n (= dry run)\n");