diff options
Diffstat (limited to 'debian/patches/0002-zonefile-Verify-mtime-against-full-precision-timesta.patch')
-rw-r--r-- | debian/patches/0002-zonefile-Verify-mtime-against-full-precision-timesta.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/debian/patches/0002-zonefile-Verify-mtime-against-full-precision-timesta.patch b/debian/patches/0002-zonefile-Verify-mtime-against-full-precision-timesta.patch new file mode 100644 index 0000000..fa79f5d --- /dev/null +++ b/debian/patches/0002-zonefile-Verify-mtime-against-full-precision-timesta.patch @@ -0,0 +1,129 @@ +From: Daniel Kahn Gillmor <dkg@fifthhorseman.net> +Date: Fri, 22 Feb 2019 16:05:38 -0500 +Subject: zonefile: Verify mtime against full-precision timestamp + +We've just used 1-second granularity mtime to check if a file has +changed. + +But if two updates happen within a calendar second, and knotd notices +the first one and reloads the file, it might never notice the second +change and continue serving the old file. We can see this happening +in intermittent test suite failures in the debian continuous +integration servers: + + https://ci.debian.net/packages/k/knot/unstable/amd64 + +Using nanosecond-granularity timestamps should make these problems go +away. + +Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net> +--- + src/knot/events/handlers/load.c | 6 ++++-- + src/knot/zone/zone.c | 2 +- + src/knot/zone/zone.h | 2 +- + src/knot/zone/zonedb-load.c | 6 ++++-- + src/knot/zone/zonefile.c | 4 ++-- + src/knot/zone/zonefile.h | 2 +- + 6 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/src/knot/events/handlers/load.c b/src/knot/events/handlers/load.c +index 7410d30..1f8f368 100644 +--- a/src/knot/events/handlers/load.c ++++ b/src/knot/events/handlers/load.c +@@ -73,10 +73,12 @@ int event_load(conf_t *conf, zone_t *zone) + + // If configured, attempt to load zonefile. + if (zf_from != ZONEFILE_LOAD_NONE) { +- time_t mtime; ++ struct timespec mtime; + char *filename = conf_zonefile(conf, zone->name); + ret = zonefile_exists(filename, &mtime); +- bool zonefile_unchanged = (zone->zonefile.exists && zone->zonefile.mtime == mtime); ++ bool zonefile_unchanged = (zone->zonefile.exists && ++ zone->zonefile.mtime.tv_sec == mtime.tv_sec && ++ zone->zonefile.mtime.tv_nsec == mtime.tv_nsec); + free(filename); + if (ret == KNOT_EOK) { + ret = zone_load_contents(conf, zone->name, &zf_conts); +diff --git a/src/knot/zone/zone.c b/src/knot/zone/zone.c +index efc0caa..0ec29f1 100644 +--- a/src/knot/zone/zone.c ++++ b/src/knot/zone/zone.c +@@ -145,7 +145,7 @@ static int flush_journal(conf_t *conf, zone_t *zone, bool allow_empty_zone) + + /* Update zone file attributes. */ + zone->zonefile.exists = true; +- zone->zonefile.mtime = st.st_mtime; ++ zone->zonefile.mtime = st.st_mtim; + zone->zonefile.serial = serial_to; + zone->zonefile.resigned = false; + +diff --git a/src/knot/zone/zone.h b/src/knot/zone/zone.h +index 360e222..09c92cc 100644 +--- a/src/knot/zone/zone.h ++++ b/src/knot/zone/zone.h +@@ -50,7 +50,7 @@ typedef struct zone + + /*! \brief Zonefile parameters. */ + struct { +- time_t mtime; ++ struct timespec mtime; + uint32_t serial; + bool exists; + bool resigned; +diff --git a/src/knot/zone/zonedb-load.c b/src/knot/zone/zonedb-load.c +index a6e9834..f23b4b1 100644 +--- a/src/knot/zone/zonedb-load.c ++++ b/src/knot/zone/zonedb-load.c +@@ -35,12 +35,14 @@ static bool zone_file_updated(conf_t *conf, const zone_t *old_zone, + assert(zone_name); + + char *zonefile = conf_zonefile(conf, zone_name); +- time_t mtime; ++ struct timespec mtime; + int ret = zonefile_exists(zonefile, &mtime); + free(zonefile); + + return (ret == KNOT_EOK && old_zone != NULL && +- !(old_zone->zonefile.exists && old_zone->zonefile.mtime == mtime)); ++ !(old_zone->zonefile.exists && ++ old_zone->zonefile.mtime.tv_sec == mtime.tv_sec && ++ old_zone->zonefile.mtime.tv_nsec == mtime.tv_nsec)); + } + + static zone_t *create_zone_from(const knot_dname_t *name, server_t *server) +diff --git a/src/knot/zone/zonefile.c b/src/knot/zone/zonefile.c +index 37fc90b..0e02d21 100644 +--- a/src/knot/zone/zonefile.c ++++ b/src/knot/zone/zonefile.c +@@ -248,7 +248,7 @@ fail: + return NULL; + } + +-int zonefile_exists(const char *path, time_t *mtime) ++int zonefile_exists(const char *path, struct timespec *mtime) + { + if (path == NULL) { + return KNOT_EINVAL; +@@ -260,7 +260,7 @@ int zonefile_exists(const char *path, time_t *mtime) + } + + if (mtime != NULL) { +- *mtime = zonefile_st.st_mtime; ++ *mtime = zonefile_st.st_mtim; + } + + return KNOT_EOK; +diff --git a/src/knot/zone/zonefile.h b/src/knot/zone/zonefile.h +index 90283ee..9d0542e 100644 +--- a/src/knot/zone/zonefile.h ++++ b/src/knot/zone/zonefile.h +@@ -79,7 +79,7 @@ zone_contents_t *zonefile_load(zloader_t *loader); + * + * \return KNOT_E* + */ +-int zonefile_exists(const char *path, time_t *mtime); ++int zonefile_exists(const char *path, struct timespec *mtime); + + /*! + * \brief Write zone contents to zone file. |