]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2920. [bug] Delay thawing the zone until the reload of it has
authorMark Andrews <marka@isc.org>
Thu, 2 Jul 2009 07:39:03 +0000 (07:39 +0000)
committerMark Andrews <marka@isc.org>
Thu, 2 Jul 2009 07:39:03 +0000 (07:39 +0000)
                        completed successfully.  [RT #19750]

CHANGES
bin/named/control.c
bin/named/include/named/server.h
bin/named/server.c
lib/dns/include/dns/zone.h
lib/dns/win32/libdns.def
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index d1b23919940beb7ec37574c420f5745505677653..d66efd15c9f44f904b824021dd1ab7345e60ddf3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2920.  [bug]           Delay thawing the zone until the reload of it has
+                       completed successfully.  [RT #19750]
+
 2619.  [func]          Add support for RFC 5011, automatic trust anchor
                        maintenance.  The new "managed-keys" statement can
                        be used in place of "trusted-keys" for zones which
index 8bd8f6ce361fd1ab07f82068b585ed51085782d6..63f0979bbc80afd63abd80fbf4a652f0286034eb 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: control.c,v 1.33 2007/09/13 04:45:18 each Exp $ */
+/* $Id: control.c,v 1.34 2009/07/02 07:39:02 marka Exp $ */
 
 /*! \file */
 
@@ -170,10 +170,12 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
        } else if (command_compare(command, NS_COMMAND_TSIGDELETE)) {
                result = ns_server_tsigdelete(ns_g_server, command, text);
        } else if (command_compare(command, NS_COMMAND_FREEZE)) {
-               result = ns_server_freeze(ns_g_server, ISC_TRUE, command);
+               result = ns_server_freeze(ns_g_server, ISC_TRUE, command,
+                                         text);
        } else if (command_compare(command, NS_COMMAND_UNFREEZE) ||
                   command_compare(command, NS_COMMAND_THAW)) {
-               result = ns_server_freeze(ns_g_server, ISC_FALSE, command);
+               result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
+                                         text);
        } else if (command_compare(command, NS_COMMAND_RECURSING)) {
                result = ns_server_dumprecursing(ns_g_server);
        } else if (command_compare(command, NS_COMMAND_TIMERPOKE)) {
index b076cbaa3f1f48d0719fa9e5bb764db97d9c449c..4ade41a00850bf88795aaca98d1515cd906e727b 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.h,v 1.99 2009/06/30 02:52:32 each Exp $ */
+/* $Id: server.h,v 1.100 2009/07/02 07:39:02 marka Exp $ */
 
 #ifndef NAMED_SERVER_H
 #define NAMED_SERVER_H 1
@@ -286,7 +286,8 @@ ns_server_tsigdelete(ns_server_t *server, char *command, isc_buffer_t *text);
  * Enable or disable updates for a zone.
  */
 isc_result_t
-ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args);
+ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
+                isc_buffer_t *text);
 
 /*%
  * Dump the current recursive queries.
index 890f5b464085704bcf66da6a6120b863253fa3bb..f14337c6f7ee566920321ad10b024c1e142061f0 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.536 2009/06/30 23:48:01 tbox Exp $ */
+/* $Id: server.c,v 1.537 2009/07/02 07:39:02 marka Exp $ */
 
 /*! \file */
 
@@ -6218,7 +6218,9 @@ ns_server_tsiglist(ns_server_t *server, isc_buffer_t *text) {
  * Act on a "freeze" or "thaw" command from the command channel.
  */
 isc_result_t
-ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
+ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
+                isc_buffer_t *text)
+{
        isc_result_t result, tresult;
        dns_zone_t *zone = NULL;
        dns_zonetype_t type;
@@ -6228,6 +6230,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
        char *journal;
        const char *vname, *sep;
        isc_boolean_t frozen;
+       const char *msg = NULL;
 
        result = zone_from_args(server, args, &zone);
        if (result != ISC_R_SUCCESS)
@@ -6260,25 +6263,47 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
 
        frozen = dns_zone_getupdatedisabled(zone);
        if (freeze) {
-               if (frozen)
+               if (frozen) {
+                       msg = "WARNING: The zone was already frozen.\n"
+                             "Someone else may be editing it or "
+                             "it may still be re-loading.";
                        result = DNS_R_FROZEN;
-               if (result == ISC_R_SUCCESS)
+               }
+               if (result == ISC_R_SUCCESS) {
                        result = dns_zone_flush(zone);
+                       if (result != ISC_R_SUCCESS)
+                               msg = "Flushing the zone updates to "
+                                     "disk failed.";
+               }
                if (result == ISC_R_SUCCESS) {
                        journal = dns_zone_getjournal(zone);
                        if (journal != NULL)
                                (void)isc_file_remove(journal);
                }
+               if (result == ISC_R_SUCCESS)
+                       dns_zone_setupdatedisabled(zone, freeze);
        } else {
                if (frozen) {
-                       result = dns_zone_load(zone);
-                       if (result == DNS_R_CONTINUE ||
-                           result == DNS_R_UPTODATE)
+                       result = dns_zone_loadandthaw(zone);
+                       switch (result) {
+                       case ISC_R_SUCCESS:
+                       case DNS_R_UPTODATE:
+                               msg = "The zone reload and thaw was "
+                                     "successful.";
+                               result = ISC_R_SUCCESS;
+                               break;
+                       case DNS_R_CONTINUE:
+                               msg = "A zone reload and thaw was started.\n"
+                                     "Check the logs to see the result.";
                                result = ISC_R_SUCCESS;
+                               break;
+                       }
                }
        }
-       if (result == ISC_R_SUCCESS)
-               dns_zone_setupdatedisabled(zone, freeze);
+
+       if (msg != NULL && strlen(msg) < isc_buffer_availablelength(text))
+               isc_buffer_putmem(text, (const unsigned char *)msg,
+                                 strlen(msg) + 1);
 
        view = dns_zone_getview(zone);
        if (strcmp(view->name, "_default") == 0 ||
index 0f5c0023007fa93182f6a83fff25c9e9138a96b9..5b781d5e33c4823eca46e53eadd3c99fd25f7dbf 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.165 2009/06/30 02:52:32 each Exp $ */
+/* $Id: zone.h,v 1.166 2009/07/02 07:39:03 marka Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -257,6 +257,9 @@ dns_zone_load(dns_zone_t *zone);
 
 isc_result_t
 dns_zone_loadnew(dns_zone_t *zone);
+
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone);
 /*%<
  *     Cause the database to be loaded from its backing store.
  *     Confirm that the minimum requirements for the zone type are
@@ -265,6 +268,8 @@ dns_zone_loadnew(dns_zone_t *zone);
  *     dns_zone_loadnew() only loads zones that are not yet loaded.
  *     dns_zone_load() also loads zones that are already loaded and
  *     and whose master file has changed since the last load.
+ *     dns_zone_loadandthaw() is similar to dns_zone_load() but will
+ *     also re-enable DNS UPDATEs when the load completes.
  *
  * Require:
  *\li  'zone' to be a valid zone.
index ff1575b4a395013e116fafd2ea4e011d4ea406d7..77c489832eca2f18bca4fca627320df4ccd3b86f 100644 (file)
@@ -743,6 +743,7 @@ dns_zone_iattach
 dns_zone_idetach
 dns_zone_isforced
 dns_zone_load
+dns_zone_loadandthaw
 dns_zone_log
 dns_zone_maintenance
 dns_zone_markdirty
index 484318d05a35ae5fd6db38803f20cc27b84a4776..7d785d17d0e934ade0b78bfb9f7a99acf6d8528e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.495 2009/06/30 23:48:01 tbox Exp $ */
+/* $Id: zone.c,v 1.496 2009/07/02 07:39:02 marka Exp $ */
 
 /*! \file */
 
@@ -358,12 +358,15 @@ struct dns_zone {
 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
-#define DNS_ZONEFLG_REFRESHING 0x04000000U     /*%< Refreshing keydata */
+#define DNS_ZONEFLG_REFRESHING 0x04000000U     /*%< Refreshing keydata */
+#define DNS_ZONEFLG_THAW       0x08000000U
 
 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
 
 /* Flags for zone_load() */
 #define DNS_ZONELOADFLAG_NOSTAT        0x00000001U     /* Do not stat() master files */
+#define DNS_ZONELOADFLAG_THAW  0x00000002U     /* Thaw the zone on successful
+                                                  load. */
 
 #define UNREACH_CHACHE_SIZE    10U
 #define UNREACH_HOLD_TIME      600     /* 10 minutes */
@@ -1342,7 +1345,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
        INSIST(zone->type != dns_zone_none);
 
        if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
-               result = ISC_R_SUCCESS;
+               if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+                       DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
+               result = DNS_R_CONTINUE;
                goto cleanup;
        }
 
@@ -1476,6 +1481,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
 
        if (result == DNS_R_CONTINUE) {
                DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
+               if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+                       DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
                goto cleanup;
        }
 
@@ -1498,6 +1505,30 @@ dns_zone_loadnew(dns_zone_t *zone) {
        return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
 }
 
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone) {
+       isc_result_t result;
+               
+       result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
+       switch (result) {
+       case DNS_R_CONTINUE:
+               /* Deferred thaw. */
+               break;
+       case ISC_R_SUCCESS:
+       case DNS_R_UPTODATE:
+       case DNS_R_SEENINCLUDE:
+               zone->update_disabled = ISC_FALSE;
+               break;
+       case DNS_R_NOMASTERFILE:
+               zone->update_disabled = ISC_FALSE;
+               break;
+       default:
+               /* Error, remain in disabled state. */
+               break;
+       }
+       return (result);
+}
+
 static unsigned int
 get_master_options(dns_zone_t *zone) {
        unsigned int options;
@@ -11172,6 +11203,13 @@ zone_loaddone(void *arg, isc_result_t result) {
        (void)zone_postload(load->zone, load->db, load->loadtime, result);
        zonemgr_putio(&load->zone->readio);
        DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
+       /*
+        * Leave the zone frozen if the reload fails.
+        */
+       if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
+            DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
+               zone->update_disabled = ISC_FALSE;
+       DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
        UNLOCK_ZONE(load->zone);
 
        load->magic = 0;