]> 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:23:54 +0000 (04:23 +0000)
committerMark Andrews <marka@isc.org>
Sat, 11 Jul 2009 04:23:54 +0000 (04:23 +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 f2e254c61265278d250eb9486d8faaa551acd311..bb3f1c83a636f40c90f2873ab7ca1d228eb63475 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 8bd8f6ce361fd1ab07f82068b585ed51085782d6..b6b7c73be4e43e667062a5219a5376096a8120c7 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.33.266.1 2009/07/11 04:23:52 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 43eccc4a63d4f8d91d8660cb687bb7555d0cdd98..1a3f746f3fb45a62a99b96b9113df609174a56ef 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.h,v 1.93.120.2 2009/01/29 23:47:44 tbox Exp $ */
+/* $Id: server.h,v 1.93.120.3 2009/07/11 04:23:53 marka Exp $ */
 
 #ifndef NAMED_SERVER_H
 #define NAMED_SERVER_H 1
@@ -276,7 +276,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 e685e18dc336fb07a90aa31547ca8db75be95706..026bcbeb42b3f314bc49868157247b28e224bfd1 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.520.12.7 2009/01/30 03:53:38 marka Exp $ */
+/* $Id: server.c,v 1.520.12.8 2009/07/11 04:23:52 marka Exp $ */
 
 /*! \file */
 
@@ -5401,7 +5401,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;
@@ -5411,6 +5413,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)
@@ -5443,25 +5446,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 e2859ae5bbb53246404d7d4ccc908b019951678f..a7919fab7cc74337c77dc4537f2ebffd57683aee 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.160.50.4 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: zone.h,v 1.160.50.5 2009/07/11 04:23:53 marka Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -256,6 +256,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
@@ -264,6 +267,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 55228120ba2c28c9d63aa0aebbc7bbd09a828d18..b697c8ff314ecf34d299960918a519512d69991b 100644 (file)
@@ -717,6 +717,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 5a4fab3654c1d9c1947be6489a42ce715fabbf0f..712ee8a4dfae72635bb3fe6654441587531324c2 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.483.36.7 2009/06/17 04:53:57 marka Exp $ */
+/* $Id: zone.c,v 1.483.36.8 2009/07/11 04:23:53 marka Exp $ */
 
 /*! \file */
 
@@ -351,11 +351,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. */
 
 #define UNREACH_CHACHE_SIZE    10U
 #define UNREACH_HOLD_TIME      600     /* 10 minutes */
@@ -1314,7 +1318,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;
        }
 
@@ -1448,6 +1454,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;
        }
 
@@ -1470,6 +1478,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;
@@ -9875,6 +9907,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;