]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
prefill: download through a temporary file
authorVladimír Čunát <vladimir.cunat@nic.cz>
Sun, 25 May 2025 08:17:44 +0000 (10:17 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Sun, 25 May 2025 08:17:44 +0000 (10:17 +0200)
File rename is an atomic operation, so that's a plus.
We had a practical issue with the canary process,
as (for me) it exits somewhere during the download; example log:

kresd0[912938]: [prefil] downloading root zone to file root.zone ...
kresd0[912942]: [prefil] root zone file valid for 11 hours 59 minutes, reusing data from disk
kresd0[912942]: [prefil] empty zone file
kresd0[912942]: [prefil] error parsing zone file `root.zone`
kresd0[912942]: [prefil] root zone import failed, retry in 01 seconds
kresd0[912942]: [prefil] downloading root zone to file root.zone ...
kresd0[912942]: [prefil] import started for zone file `root.zone`
kresd0[912942]: [prefil] performance: parsing took 0.832 s, hashing took nan s
kresd0[912942]: [prefil] zone successfully parsed, import started
kresd0[912942]: [prefil] root zone refresh in 11 hours 59 minutes
kresd0[912942]: [prefil] performance: validating and caching took 0.736 s

Also avoid the unnecessary pcall+error.  Why throw and immediately catch?

NEWS
modules/prefill/prefill.lua

diff --git a/NEWS b/NEWS
index 0bd683341dfc950b1c0424ca9b60a129ccf86e0d..7f2e884b14a05f960a31d84ef94e873d29512659 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Bugfixes
 - fix `dnssec: false` (!1687)
 - fix undefined disable_defer (!1685)
 - daemon: fix a memory leak present since v6.0.9 (#927)
+- fix logging `[prefil] empty zone file` (!1688)
 
 Improvements
 ------------
index 29cbc4ce9f4af37dffe60eb0608a8969b92b72ce..58849f5ab6fdaf6faa4a9381dc3fc20827027afc 100644 (file)
@@ -70,19 +70,26 @@ end
 
 local function download(url, fname)
        local kluautil = require('kluautil')
-       local file, rcode, errmsg
-       file, errmsg = io.open(fname, 'w')
+       local fname_tmp = os.tmpname()
+       local file, ok, errmsg
+       file, errmsg = io.open(fname_tmp, 'w')
        if not file then
-               error(string.format("unable to open file %s: %s", fname, errmsg))
+               return false, string.format("unable to open file %s: %s", fname_tmp, errmsg)
        end
 
        log_info(ffi.C.LOG_GRP_PREFILL, "downloading root zone to file %s ...", fname)
-       rcode, errmsg = kluautil.kr_https_fetch(url, file, rz_ca_file)
-       if rcode == nil then
-               error(string.format("fetch of `%s` failed: %s", url, errmsg))
-       end
-
+       ok, errmsg = kluautil.kr_https_fetch(url, file, rz_ca_file)
        file:close()
+       if not ok then
+               os.remove(fname_tmp) -- try to clean up but ignore errors
+               return false, string.format("fetch of `%s` failed: %s", url, errmsg)
+       end
+       ok, errmsg = os.rename(fname_tmp, fname)
+       if ok == nil then
+               os.remove(fname_tmp) -- try to clean up but ignore errors
+               return false, string.format("unable to move to file %s: %s", fname, errmsg);
+       end
+       return true
 end
 
 local function import(fname)
@@ -105,7 +112,7 @@ function forward_references.fill_cache()
                log_info(ffi.C.LOG_GRP_PREFILL, "root zone file valid for %s, reusing data from disk",
                        display_delay(file_ttl))
        else
-               local ok, errmsg = pcall(download, rz_url, rz_local_fname)
+               local ok, errmsg = download(rz_url, rz_local_fname)
                if not ok then
                        rz_cur_interval = rz_https_fail_interval
                                                - math.random(rz_interval_randomizer_limit)
@@ -113,7 +120,6 @@ function forward_references.fill_cache()
                                .. "will retry root zone download in %s",
                                errmsg, display_delay(rz_cur_interval))
                        restart_timer(rz_cur_interval)
-                       os.remove(rz_local_fname)
                        return
                end
                file_ttl = rz_default_interval