From 03e5c754568b3ea06aa7ccf7538a04a54612f82c Mon Sep 17 00:00:00 2001 From: Marek Vavrusa <marek.vavrusa@nic.cz> Date: Wed, 18 Jul 2012 19:02:35 +0200 Subject: [PATCH] Implemented ixfr-from-differences in config. refs #1949 --- samples/knot.full.conf | 10 ++++++++++ src/knot/conf/cf-lex.l | 1 + src/knot/conf/cf-parse.y | 4 ++++ src/knot/conf/conf.c | 6 ++++++ src/knot/conf/conf.h | 2 ++ src/knot/server/zones.c | 22 ++++++++++++++++++++++ src/libknot/updates/changesets.c | 2 +- src/libknot/zone/zone-diff.c | 2 +- 8 files changed, 47 insertions(+), 2 deletions(-) diff --git a/samples/knot.full.conf b/samples/knot.full.conf index d9d9de79fe..a0ec438593 100644 --- a/samples/knot.full.conf +++ b/samples/knot.full.conf @@ -119,6 +119,11 @@ zones { # Shared options for all listed zones # + # Build differences from zone file changes + # Possible values: on|off + # Default value: off + ixfr-from-differences off; + # Enable semantic checks for all zones (if 'on') # Possible values: on|off # Default value: off @@ -161,6 +166,11 @@ zones { # it is considered relative to the current directory from which the server # was started. file "samples/example.com.zone"; + + # Build differences from zone file changes + # Possible values: on|off + # Default value: off + ixfr-from-differences off; # Disable ANY type queries for authoritative answers (if 'on') # Possible values: on|off diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l index 16b0343860..58d1f4b961 100644 --- a/src/knot/conf/cf-lex.l +++ b/src/knot/conf/cf-lex.l @@ -90,6 +90,7 @@ notify-out { lval.t = yytext; return NOTIFY_OUT; } workers { lval.t = yytext; return WORKERS; } user { lval.t = yytext; return USER; } pidfile { lval.t = yytext; return PIDFILE; } +ixfr-from-differences { lval.t = yytext; return BUILD_DIFFS; } interfaces { lval.t = yytext; return INTERFACES; } address { lval.t = yytext; return ADDRESS; } diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y index fb6502674f..69a5415350 100644 --- a/src/knot/conf/cf-parse.y +++ b/src/knot/conf/cf-parse.y @@ -172,6 +172,7 @@ static void conf_zone_start(void *scanner, char *name) { this_zone->ixfr_fslimit = -1; // Default policy applies this_zone->dbsync_timeout = -1; // Default policy applies this_zone->disable_any = -1; // Default policy applies + this_zone->build_diffs = -1; // Default policy applies // Append mising dot to ensure FQDN size_t nlen = strlen(name); @@ -266,6 +267,7 @@ static int conf_mask(void* scanner, int nval, int prefixlen) { %token <tok> XFR_OUT %token <tok> NOTIFY_IN %token <tok> NOTIFY_OUT +%token <tok> BUILD_DIFFS %token <tok> INTERFACES ADDRESS PORT %token <tok> IPA @@ -662,6 +664,7 @@ zone: | zone zone_acl '}' | zone zone_acl_list | zone FILENAME TEXT ';' { this_zone->file = $3.t; } + | zone BUILD_DIFFS BOOL ';' { this_zone->build_diffs = $3.i; } | zone SEMANTIC_CHECKS BOOL ';' { this_zone->enable_checks = $3.i; } | zone DISABLE_ANY BOOL ';' { this_zone->disable_any = $3.i; } | zone DBSYNC_TIMEOUT NUM ';' { this_zone->dbsync_timeout = $3.i; } @@ -688,6 +691,7 @@ zones: ZONES '{' | zones zone '}' | zones DISABLE_ANY BOOL ';' { new_config->disable_any = $3.i; } + | zones BUILD_DIFFS BOOL ';' { new_config->build_diffs = $3.i; } | zones SEMANTIC_CHECKS BOOL ';' { new_config->zone_checks = $3.i; } | zones IXFR_FSLIMIT SIZE ';' { new_config->ixfr_fslimit = $3.l; } | zones IXFR_FSLIMIT NUM ';' { new_config->ixfr_fslimit = $3.i; } diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index edc2f1ad23..447f59a8aa 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -214,6 +214,11 @@ static int conf_process(conf_t *conf) if (zone->dbsync_timeout < 0) { zone->dbsync_timeout = conf->dbsync_timeout; } + + // Default policy for ixfr-from-differences + if (zone->build_diffs < 0) { + zone->build_diffs = conf->build_diffs; + } // Default policy for semantic checks if (zone->enable_checks < 0) { @@ -490,6 +495,7 @@ conf_t *conf_new(const char* path) c->ixfr_fslimit = -1; c->uid = -1; c->gid = -1; + c->build_diffs = 0; /* Disable by default. */ return c; } diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index 7e1b61ff8e..7921335cd8 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -96,6 +96,7 @@ typedef struct conf_zone_t { int disable_any; /*!< Disable ANY type queries for AA.*/ int notify_retries; /*!< NOTIFY query retries. */ int notify_timeout; /*!< Timeout for NOTIFY response (s). */ + int build_diffs; /*!< Calculate differences from changes. */ struct { list xfr_in; /*!< Remotes accepted for for xfr-in.*/ list xfr_out; /*!< Remotes accepted for xfr-out.*/ @@ -197,6 +198,7 @@ typedef struct conf_t { int notify_timeout; /*!< Timeout for NOTIFY response in seconds. */ int dbsync_timeout; /*!< Default interval between syncing to zonefile.*/ size_t ixfr_fslimit; /*!< File size limit for IXFR journal. */ + int build_diffs; /*!< Calculate differences from changes. */ /* * Implementation specifics diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 81e1bf43c0..919c3fa5cb 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -1537,6 +1537,28 @@ static int zones_insert_zone(conf_zone_t *z, knot_zone_t **dst, rcu_read_unlock(); } + + /* Calculate differences. */ + rcu_read_lock(); + knot_zone_t *z_old = knot_zonedb_find_zone(ns->zone_db, + dname); + /* Ensure both new and old have zone contents. */ + knot_zone_contents_t *zc = knot_zone_get_contents(zone); + knot_zone_contents_t *zc_old = knot_zone_get_contents(z_old); + if (z->build_diffs && zc != NULL && zc_old != NULL && zone_changed) { + int bd = zones_create_and_save_changesets(z_old, zone); + if (bd == KNOTD_ENODIFF) { + log_zone_warning("Zone file for '%s' changed, " + "but serial didn't - " + "won't create changesets.\n", + z->name); + } else if (bd != KNOTD_EOK) { + log_zone_warning("Failed to calculate differences" + " from the zone file update: " + "%s\n", knotd_strerror(bd)); + } + } + rcu_read_unlock(); } /* CLEANUP */ diff --git a/src/libknot/updates/changesets.c b/src/libknot/updates/changesets.c index 457ba93b2a..bd167897fc 100644 --- a/src/libknot/updates/changesets.c +++ b/src/libknot/updates/changesets.c @@ -206,7 +206,7 @@ int knot_changeset_add_soa(knot_changeset_t *changeset, knot_rrset_t *soa, int knot_changesets_check_size(knot_changesets_t *changesets) { /* Check if allocated is sufficient. */ - if (changesets->count <= changesets->allocated) { + if (changesets->count < changesets->allocated) { return KNOT_EOK; } diff --git a/src/libknot/zone/zone-diff.c b/src/libknot/zone/zone-diff.c index 07817d4eb9..400f24f2a9 100644 --- a/src/libknot/zone/zone-diff.c +++ b/src/libknot/zone/zone-diff.c @@ -857,7 +857,7 @@ int knot_zone_diff_create_changesets(const knot_zone_contents_t *z1, return ret; } - ret = knot_zone_contents_diff(z1, z2, &((*changesets)->sets[0])); + ret = knot_zone_contents_diff(z1, z2, (*changesets)->sets); if (ret != KNOT_EOK) { dbg_zonediff("zone_diff: create_changesets: " "Could not diff zones. " -- GitLab