]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1796. [func] "rndc freeze/thaw" now freezes/thaws all zones.
authorMark Andrews <marka@isc.org>
Fri, 14 Jan 2005 03:28:09 +0000 (03:28 +0000)
committerMark Andrews <marka@isc.org>
Fri, 14 Jan 2005 03:28:09 +0000 (03:28 +0000)
CHANGES
bin/named/server.c
bin/rndc/rndc.c
lib/dns/include/dns/view.h
lib/dns/include/dns/zt.h
lib/dns/view.c
lib/dns/zt.c

diff --git a/CHANGES b/CHANGES
index 8317c0a0e4c3b32d75341187433deac957dddbd0..e419b2afc0285fc77c3d0ec346b627e4ea3b6098 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,7 +3,7 @@
 1797.  [func]          named-checkconf now check acls to verify that they
                        only refer to existing acls. [RT #13101]
 
-1796.  [placeholder]   rt12498
+1796.  [func]          "rndc freeze/thaw" now freezes/thaws all zones.
 
 1795.  [placeholder]   rt13396
 
index 0dc6cdf04933e58fc65533412055047e8e6f6e65..b2a6e4ad6b6482d56bfe93276e04b48051bc1885 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.436 2005/01/12 01:56:07 marka Exp $ */
+/* $Id: server.c,v 1.437 2005/01/14 03:28:07 marka Exp $ */
 
 #include <config.h>
 
@@ -4109,11 +4109,11 @@ ns_server_status(ns_server_t *server, isc_buffer_t *text) {
 }
 
 /*
- * Act on a "freeze" or "unfreeze" command from the command channel.
+ * 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) {
-       isc_result_t result;
+       isc_result_t result, tresult;
        dns_zone_t *zone = NULL;
        dns_zonetype_t type;
        char classstr[DNS_RDATACLASS_FORMATSIZE];
@@ -4126,8 +4126,26 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
        result = zone_from_args(server, args, &zone);
        if (result != ISC_R_SUCCESS)
                return (result);
-       if (zone == NULL)
-               return (ISC_R_UNEXPECTEDEND);
+       if (zone == NULL) {
+               result = isc_task_beginexclusive(server->task);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+               tresult = ISC_R_SUCCESS;
+               for (view = ISC_LIST_HEAD(server->viewlist);
+                    view != NULL;
+                    view = ISC_LIST_NEXT(view, link)) {
+                       result = dns_view_freezezones(view, freeze);
+                       if (result != ISC_R_SUCCESS &&
+                           tresult == ISC_R_SUCCESS)
+                               tresult = result;
+               }
+               isc_task_endexclusive(server->task);
+               isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+                             NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+                             "%s all zones: %s",
+                             freeze ? "freezing" : "thawing",
+                             isc_result_totext(tresult));
+               return (tresult);
+       }
        type = dns_zone_gettype(zone);
        if (type != dns_zone_master) {
                dns_zone_detach(&zone);
@@ -4173,7 +4191,7 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args) {
        isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
                      NS_LOGMODULE_SERVER, ISC_LOG_INFO,
                      "%s zone '%s/%s'%s%s: %s",
-                     freeze ? "freezing" : "unfreezing",
+                     freeze ? "freezing" : "thawing",
                      zonename, classstr, sep, vname,
                      isc_result_totext(result));
        dns_zone_detach(&zone);
index d2f16edc5695c2707ce130ba42b93278c7df6e61..8b0aea473258029bc69eb364786bc99568004b71 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rndc.c,v 1.100 2004/10/11 05:30:20 marka Exp $ */
+/* $Id: rndc.c,v 1.101 2005/01/14 03:28:07 marka Exp $ */
 
 /*
  * Principal Author: DCL
@@ -100,8 +100,10 @@ command is one of the following:\n\
                Schedule immediate maintenance for a zone.\n\
   retransfer zone [class [view]]\n\
                Retransfer a single zone without checking serial number.\n\
+  freeze       Suspend updates to all dynamic zones.\n\
   freeze zone [class [view]]\n\
                Suspend updates to a dynamic zone.\n\
+  thaw         Enable updates to all dynamic zones and reload them.\n\
   thaw zone [class [view]]\n\
                Enable updates to a frozen dynamic zone and reload it.\n\
   notify zone [class [view]]\n\
index 4570cfc70b434b52d88ad9a57f1de4cea194decc..a6f359a66cb165e057ffaa372872e8d5cf17cfe4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: view.h,v 1.92 2004/12/21 10:45:19 jinmei Exp $ */
+/* $Id: view.h,v 1.93 2005/01/14 03:28:08 marka Exp $ */
 
 #ifndef DNS_VIEW_H
 #define DNS_VIEW_H 1
@@ -787,4 +787,12 @@ dns_view_getrootdelonly(dns_view_t *view);
  *     'view' is valid.
  */
 
+isc_result_t
+dns_view_freezezones(dns_view_t *view, isc_boolean_t freeze);
+/*
+ * Freeze/thaw updates to master zones.
+ *
+ * Requires:
+ *     'view' is valid.
+ */
 #endif /* DNS_VIEW_H */
index cfd77a85a338f48690fc3a63db3a329a6a255369..63ab5fa0c7b27089e526b2ebd0d156345e7a875e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zt.h,v 1.30 2004/03/05 05:09:48 marka Exp $ */
+/* $Id: zt.h,v 1.31 2005/01/14 03:28:09 marka Exp $ */
 
 #ifndef DNS_ZT_H
 #define DNS_ZT_H 1
@@ -145,9 +145,21 @@ dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop);
  *     'zt' to be valid
  */
 
+isc_result_t
+dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze);
+/*
+ * Freeze/thaw updates to master zones.
+ * Any pending updates will be flushed.
+ * Zones will be reloaded on thaw.
+ */
+
 isc_result_t
 dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
             isc_result_t (*action)(dns_zone_t *, void *), void *uap);
+
+isc_result_t
+dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
+             isc_result_t (*action)(dns_zone_t *, void *), void *uap);
 /*
  * Apply a given 'action' to all zone zones in the table.
  * If 'stop' is 'ISC_TRUE' then walking the zone tree will stop if
@@ -158,7 +170,9 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
  *     'action' to be non NULL.
  *
  * Returns:
- *     ISC_R_SUCCESS if action was applied to all nodes.
+ *     ISC_R_SUCCESS if action was applied to all nodes.  If 'stop' is
+ *     ISC_FALSE and 'sub' is non NULL then the first error (if any)
+ *     reported by 'action' is returned in '*sub';
  *     any error code from 'action'.
  */
 
index 6a3fa54e66f4df8b25973ead51dc5ae9d7546de7..61b208ced1042462f4589d64e3a69eca36922179 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: view.c,v 1.128 2004/12/29 23:01:13 marka Exp $ */
+/* $Id: view.c,v 1.129 2005/01/14 03:28:07 marka Exp $ */
 
 #include <config.h>
 
@@ -1348,3 +1348,9 @@ dns_view_getrootdelonly(dns_view_t *view) {
        REQUIRE(DNS_VIEW_VALID(view));
        return (view->rootdelonly);
 }
+
+isc_result_t
+dns_view_freezezones(dns_view_t *view, isc_boolean_t value) {
+       REQUIRE(DNS_VIEW_VALID(view));
+       return (dns_zt_freezezones(view->zonetable, value));
+}
index 4b942f6dbb9e5a37cb26a335aeba46b8fc30b8e7..6fbd260d6428d11859abcde44dda93385b1f92e0 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zt.c,v 1.38 2004/03/05 05:09:27 marka Exp $ */
+/* $Id: zt.c,v 1.39 2005/01/14 03:28:07 marka Exp $ */
 
 #include <config.h>
 
+#include <isc/file.h>
 #include <isc/magic.h>
 #include <isc/mem.h>
+#include <isc/string.h>
 #include <isc/util.h>
 
+#include <dns/log.h>
+#include <dns/name.h>
 #include <dns/rbt.h>
+#include <dns/rdataclass.h>
 #include <dns/result.h>
+#include <dns/view.h>
 #include <dns/zone.h>
 #include <dns/zt.h>
 
@@ -51,6 +57,9 @@ load(dns_zone_t *zone, void *uap);
 static isc_result_t
 loadnew(dns_zone_t *zone, void *uap);
 
+static isc_result_t
+freezezones(dns_zone_t *zone, void *uap);
+
 isc_result_t
 dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
        dns_zt_t *zt;
@@ -265,13 +274,91 @@ loadnew(dns_zone_t *zone, void *uap) {
        return (result);
 }
 
+isc_result_t
+dns_zt_freezezones(dns_zt_t *zt, isc_boolean_t freeze) {
+       isc_result_t result, tresult;
+
+       REQUIRE(VALID_ZT(zt));
+
+       RWLOCK(&zt->rwlock, isc_rwlocktype_read);
+       result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze);
+       RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
+       return ((result == ISC_R_SUCCESS) ? tresult : result);
+}
+
+static isc_result_t
+freezezones(dns_zone_t *zone, void *uap) {
+       isc_boolean_t freeze = *(isc_boolean_t *)uap;
+       isc_boolean_t frozen;
+       isc_result_t result = ISC_R_SUCCESS;
+       char classstr[DNS_RDATACLASS_FORMATSIZE];
+       char zonename[DNS_NAME_FORMATSIZE];
+       dns_view_t *view;
+       char *journal;
+       const char *vname;
+       const char *sep;
+       int level;
+
+       if (dns_zone_gettype(zone) != dns_zone_master)
+               return (ISC_R_SUCCESS);
+
+       frozen = dns_zone_getupdatedisabled(zone);
+       if (freeze) {
+               if (frozen)
+                       result = DNS_R_FROZEN;
+               if (result == ISC_R_SUCCESS)
+                       result = dns_zone_flush(zone);
+               if (result == ISC_R_SUCCESS) {
+                       journal = dns_zone_getjournal(zone);
+                       if (journal != NULL)
+                               (void)isc_file_remove(journal);
+               }
+       } else {
+               if (frozen) {
+                       result = dns_zone_load(zone);
+                       if (result == DNS_R_CONTINUE ||
+                           result == DNS_R_UPTODATE)
+                               result = ISC_R_SUCCESS;
+               }
+       }
+       if (result == ISC_R_SUCCESS)
+               dns_zone_setupdatedisabled(zone, freeze);
+       view = dns_zone_getview(zone);
+       if (strcmp(view->name, "_bind") == 0 ||
+           strcmp(view->name, "_default") == 0)
+       {
+               vname = "";
+               sep = "";
+       } else {
+               vname = view->name;
+               sep = " ";
+       }
+       dns_rdataclass_format(dns_zone_getclass(zone), classstr,
+                             sizeof(classstr));
+       dns_name_format(dns_zone_getorigin(zone), zonename, sizeof(zonename));
+       level = (result != ISC_R_SUCCESS) ? ISC_LOG_ERROR : ISC_LOG_DEBUG(1);
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
+                     level, "%s zone '%s/%s'%s%s: %s",
+                     freeze ? "freezing" : "thawing",
+                     zonename, classstr, sep, vname,
+                     isc_result_totext(result));
+       return (result);
+}
+
 isc_result_t
 dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
             isc_result_t (*action)(dns_zone_t *, void *), void *uap)
+{
+       return (dns_zt_apply2(zt, stop, NULL, action, uap));
+}
+
+isc_result_t
+dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
+             isc_result_t (*action)(dns_zone_t *, void *), void *uap)
 {
        dns_rbtnode_t *node;
        dns_rbtnodechain_t chain;
-       isc_result_t result;
+       isc_result_t result, tresult = ISC_R_SUCCESS;
        dns_zone_t *zone;
 
        REQUIRE(VALID_ZT(zt));
@@ -292,8 +379,13 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
                        zone = node->data;
                        if (zone != NULL)
                                result = (action)(zone, uap);
-                       if (result != ISC_R_SUCCESS && stop)
+                       if (result != ISC_R_SUCCESS && stop) {
+                               tresult = result;
                                goto cleanup;   /* don't break */
+                       } else if (result != ISC_R_SUCCESS &&
+                                tresult != ISC_R_SUCCESS)
+                               tresult = result;
+                               
                }
                result = dns_rbtnodechain_next(&chain, NULL, NULL);
        }
@@ -302,6 +394,8 @@ dns_zt_apply(dns_zt_t *zt, isc_boolean_t stop,
 
  cleanup:
        dns_rbtnodechain_invalidate(&chain);
+       if (sub != NULL)
+               *sub = tresult;
 
        return (result);
 }