]> 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>
Sat, 11 Jul 2009 04:30:50 +0000 (04:30 +0000)
committerMark Andrews <marka@isc.org>
Sat, 11 Jul 2009 04:30:50 +0000 (04:30 +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 9f3fdc7dc084eeab163b145a8868d882a6591988..bfba5539cb00f68fb65d2e2e938fc84c0f826f01 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 2621.  [doc]           Made copyright boilterplate consistent.  [RT #19833]
 
+2920.  [bug]           Delay thawing the zone until the reload of it has
+                       completed successfully.  [RT #19750]
+
 2618.  [bug]           The sdb and sdlz db_interator_seek() methods could
                        loop infinitely. [RT #19847]
 
index 3f2d52e946bedd4e7b3e5f52da1510d7e9ae4318..4cee768d0800fdbc56d4a21c97a1ad5694417009 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: control.c,v 1.20.10.10 2007/09/13 23:46:26 tbox Exp $ */
+/* $Id: control.c,v 1.20.10.11 2009/07/11 04:30:49 marka Exp $ */
 
 /*! \file */
 
@@ -159,10 +159,12 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
        } else if (command_compare(command, NS_COMMAND_STATUS)) {
                result = ns_server_status(ns_g_server, 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 54d1dae17167404bfd20b6b9e93f98636660a21f..8eb50c95ce874008ba94d2af886379f00e73566b 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.h,v 1.73.18.8 2006/03/09 23:46:20 marka Exp $ */
+/* $Id: server.h,v 1.73.18.9 2009/07/11 04:30:49 marka Exp $ */
 
 #ifndef NAMED_SERVER_H
 #define NAMED_SERVER_H 1
@@ -207,7 +207,8 @@ ns_server_status(ns_server_t *server, 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 83467db42d0b064bc91afd2309b7edad45da670d..7bb2a6e0e2985e44f1b5d29be7c01a80d5393583 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.419.18.74 2009/01/30 04:24:29 marka Exp $ */
+/* $Id: server.c,v 1.419.18.75 2009/07/11 04:30:49 marka Exp $ */
 
 /*! \file */
 
@@ -4941,7 +4941,9 @@ ns_server_status(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;
@@ -4951,6 +4953,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)
@@ -4983,25 +4986,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, "_bind") == 0 ||
index 93e69df0c84331ffc6bd960dfb1822e4760f22d4..96f5d1266862499a8a0c4b7a7934ea513123c5dc 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.126.18.23 2009/01/19 00:36:28 marka Exp $ */
+/* $Id: zone.h,v 1.126.18.24 2009/07/11 04:30:50 marka Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -243,6 +243,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
@@ -251,6 +254,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 975c359496c961cb725a360f3fb6eadbc8ea6d8a..84cf7085b5bcd6c2cfdadba68b585135c599b86c 100644 (file)
@@ -674,6 +674,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 683d1a4b5c1de76bb291f15d597f165a0f132c17..d7859e7c02f4fdf4a361fcbef7a0c32515eb6ba7 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.410.18.59 2009/03/26 23:00:22 marka Exp $ */
+/* $Id: zone.c,v 1.410.18.60 2009/07/11 04:30:49 marka Exp $ */
 
 /*! \file */
 
@@ -306,11 +306,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_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. */
 
 struct dns_zonemgr {
        unsigned int            magic;
@@ -1089,7 +1093,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;
        }
 
@@ -1223,6 +1229,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;
        }
 
@@ -1245,6 +1253,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 void
 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
        dns_load_t *load = event->ev_arg;
@@ -6724,6 +6756,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;