]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3084. [func] A new command "rndc sync" dumps pending changes in
authorEvan Hunt <each@isc.org>
Mon, 21 Mar 2011 07:22:14 +0000 (07:22 +0000)
committerEvan Hunt <each@isc.org>
Mon, 21 Mar 2011 07:22:14 +0000 (07:22 +0000)
a dynamic zone to disk; "rndc sync -clean" also
removes the journal file after syncing.  Also,
"rndc freeze" no longer removes journal files.
[RT #22473]

12 files changed:
CHANGES
bin/named/control.c
bin/named/include/named/control.h
bin/named/include/named/server.h
bin/named/server.c
doc/arm/Bv9ARM-book.xml
lib/dns/include/dns/result.h
lib/dns/include/dns/zone.h
lib/dns/result.c
lib/dns/win32/libdns.def
lib/dns/zone.c
lib/dns/zt.c

diff --git a/CHANGES b/CHANGES
index 2175018277d54ed1162cb883d39a342307731650..68da4cf442cb57760e1c1da0f15285fe080d8cb1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+3084.  [func]          A new command "rndc sync" dumps pending changes in
+                       a dynamic zone to disk; "rndc sync -clean" also
+                       removes the journal file after syncing.  Also,
+                       "rndc freeze" no longer removes journal files.
+                       [RT #22473]
+
 3083.  [bug]           NOTIFY messages were not being sent when generating
                        a NSEC3 chain incrementally. [RT #23702]
 
index ff084fc7d5a99c35cdcd07c7abe9da260a1014e8..96f76ac9bc6b18958eddb76b952e4cc71414761d 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: control.c,v 1.41 2010/12/03 22:05:19 each Exp $ */
+/* $Id: control.c,v 1.42 2011/03/21 07:22:11 each Exp $ */
 
 /*! \file */
 
@@ -183,6 +183,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) {
                   command_compare(command, NS_COMMAND_THAW)) {
                result = ns_server_freeze(ns_g_server, ISC_FALSE, command,
                                          text);
+       } else if (command_compare(command, NS_COMMAND_SYNC)) {
+               result = ns_server_sync(ns_g_server, 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 24e59093b4d11ec4876af0a669e0947bb5c5ce7f..b3c0949c23234064535b81670fd932019f027fd6 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: control.h,v 1.31 2010/08/16 22:21:06 marka Exp $ */
+/* $Id: control.h,v 1.32 2011/03/21 07:22:11 each Exp $ */
 
 #ifndef NAMED_CONTROL_H
 #define NAMED_CONTROL_H 1
@@ -62,6 +62,7 @@
 #define NS_COMMAND_LOADKEYS    "loadkeys"
 #define NS_COMMAND_ADDZONE     "addzone"
 #define NS_COMMAND_DELZONE     "delzone"
+#define NS_COMMAND_SYNC                "sync"
 
 isc_result_t
 ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
index 25aa641ad37ea5c5061607ac858f5248128c0258..bdc18b5b873a0dc6a98af672ece83af319e228ba 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.h,v 1.110 2010/08/16 23:46:52 tbox Exp $ */
+/* $Id: server.h,v 1.111 2011/03/21 07:22:11 each Exp $ */
 
 #ifndef NAMED_SERVER_H
 #define NAMED_SERVER_H 1
@@ -294,6 +294,12 @@ isc_result_t
 ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
                 isc_buffer_t *text);
 
+/*%
+ * Dump zone updates to disk, optionally removing the journal file
+ */
+isc_result_t
+ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text);
+
 /*%
  * Update a zone's DNSKEY set from the key repository.  If
  * the command that triggered the call to this function was "sign",
index 6172adce7fe9411dd4c7dc6a604b0712f25a9ffd..d6042dfa353edb6f79a0148ad86de63eed27e470 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: server.c,v 1.608 2011/03/11 06:11:21 marka Exp $ */
+/* $Id: server.c,v 1.609 2011/03/21 07:22:11 each Exp $ */
 
 /*! \file */
 
@@ -6981,6 +6981,106 @@ ns_server_rekey(ns_server_t *server, char *args) {
        return (result);
 }
 
+/*
+ * Act on a "sync" command from the command channel.
+*/
+static isc_result_t
+synczone(dns_zone_t *zone, void *uap) {
+       isc_boolean_t cleanup = *(isc_boolean_t *)uap;
+       isc_result_t result;
+       char *journal;
+
+       result = dns_zone_flush(zone);
+       if (result != ISC_R_SUCCESS)
+               cleanup = ISC_FALSE;
+       if (cleanup) {
+               journal = dns_zone_getjournal(zone);
+               if (journal != NULL)
+                       (void)isc_file_remove(journal);
+       }
+       return (result);
+}
+
+isc_result_t
+ns_server_sync(ns_server_t *server, char *args, isc_buffer_t *text) {
+       isc_result_t result, tresult;
+       dns_view_t *view;
+       dns_zone_t *zone = NULL;
+       char classstr[DNS_RDATACLASS_FORMATSIZE];
+       char zonename[DNS_NAME_FORMATSIZE];
+       const char *vname, *sep, *msg = NULL;
+       isc_boolean_t cleanup = ISC_FALSE;
+       char arg[8];
+       int n;
+
+       /* Did the user specify -clean? */
+       n = sscanf(args, "%*s %7s", arg);
+       if (n > 0 && strcmp(arg, "-clean") == 0) {
+               cleanup = ISC_TRUE;
+
+               /* shift so that zone_from_args() won't be confused */
+               (void) next_token(&args, " \t");
+       }
+
+       result = zone_from_args(server, args, &zone, NULL);
+       if (result != ISC_R_SUCCESS)
+               return (result);
+
+       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_zt_apply(view->zonetable, ISC_FALSE,
+                                             synczone, &cleanup);
+                       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,
+                             "dumping all zones%s: %s",
+                             cleanup ? ", removing journal files" : "",
+                             isc_result_totext(result));
+               return (tresult);
+       }
+
+       result = isc_task_beginexclusive(server->task);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+       result = synczone(zone, &cleanup);
+       isc_task_endexclusive(server->task);
+
+       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 ||
+           strcmp(view->name, "_bind") == 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));
+       isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+                     NS_LOGMODULE_SERVER, ISC_LOG_INFO,
+                     "dumping zone '%s/%s'%s%s%s: %s",
+                     zonename, classstr, sep, vname,
+                     cleanup ? ", removing journal file" : "",
+                     isc_result_totext(result));
+       dns_zone_detach(&zone);
+       return (result);
+}
+
 /*
  * Act on a "freeze" or "thaw" command from the command channel.
  */
@@ -6994,7 +7094,6 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
        char classstr[DNS_RDATACLASS_FORMATSIZE];
        char zonename[DNS_NAME_FORMATSIZE];
        dns_view_t *view;
-       char *journal;
        const char *vname, *sep;
        isc_boolean_t frozen;
        const char *msg = NULL;
@@ -7028,6 +7127,11 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
                return (DNS_R_NOTMASTER);
        }
 
+       if (freeze && !dns_zone_isdynamic(zone)) {
+               dns_zone_detach(&zone);
+               return (DNS_R_NOTDYNAMIC);
+       }
+
        result = isc_task_beginexclusive(server->task);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        frozen = dns_zone_getupdatedisabled(zone);
@@ -7044,11 +7148,6 @@ ns_server_freeze(ns_server_t *server, isc_boolean_t freeze, char *args,
                                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 {
index 83449c8870a35997364021179845c978459ff40f..3c65f5398c55fbba81679e1bd137af1a478a648c 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- File: $Id: Bv9ARM-book.xml,v 1.482 2011/03/09 00:48:17 ebersman Exp $ -->
+<!-- File: $Id: Bv9ARM-book.xml,v 1.483 2011/03/21 07:22:12 each Exp $ -->
 <book xmlns:xi="http://www.w3.org/2001/XInclude">
   <title>BIND 9 Administrator Reference Manual</title>
 
@@ -1235,15 +1235,12 @@ zone "eng.example.com" {
                     <listitem>
                       <para>
                         Suspend updates to a dynamic zone.  If no zone is
-                        specified,
-                        then all zones are suspended.  This allows manual
-                        edits to be made to a zone normally updated by dynamic
-                        update.  It
-                        also causes changes in the journal file to be synced
-                        into the master
-                        and the journal file to be removed.  All dynamic
-                        update attempts will
-                        be refused while the zone is frozen.
+                        specified, then all zones are suspended.  This allows
+                        manual edits to be made to a zone normally updated by
+                        dynamic update.  It also causes changes in the
+                        journal file to be synced into the master file.
+                        All dynamic update attempts will be refused while
+                        the zone is frozen.
                       </para>
                     </listitem>
                   </varlistentry>
@@ -1255,15 +1252,28 @@ zone "eng.example.com" {
            <optional><replaceable>view</replaceable></optional></optional></optional></userinput></term>
                     <listitem>
                       <para>
-                        Enable updates to a frozen dynamic zone.  If no zone
-                        is
-                        specified, then all frozen zones are enabled.  This
-                        causes
-                        the server to reload the zone from disk, and
-                        re-enables dynamic updates
-                        after the load has completed.  After a zone is thawed,
-                        dynamic updates
-                        will no longer be refused.
+                        Enable updates to a frozen dynamic zone.  If no
+                        zone is specified, then all frozen zones are
+                        enabled.  This causes the server to reload the zone
+                        from disk, and re-enables dynamic updates after the
+                        load has completed.  After a zone is thawed,
+                        dynamic updates will no longer be refused.
+                      </para>
+                    </listitem>
+                  </varlistentry>
+
+                  <varlistentry>
+                    <term><userinput>sync
+                        <optional>-clean</optional>
+                        <optional><replaceable>zone</replaceable>
+       <optional><replaceable>class</replaceable>
+           <optional><replaceable>view</replaceable></optional></optional></optional></userinput></term>
+                    <listitem>
+                      <para>
+                        Sync changes in the journal file for a dynamic zone
+                        to the master file.  If the "-clean" option is
+                        specified, the journal file is also removed.  If
+                        no zone is specified, then all zones are synced.
                       </para>
                     </listitem>
                   </varlistentry>
index 9195f20e10cc56aa207e91e41100a1d49628748b..18c49ba8a04a4de762732852b10b8a8b2990ae92 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: result.h,v 1.122 2011/01/11 23:47:13 tbox Exp $ */
+/* $Id: result.h,v 1.123 2011/03/21 07:22:14 each Exp $ */
 
 #ifndef DNS_RESULT_H
 #define DNS_RESULT_H 1
 #define DNS_R_NOTMASTER                (ISC_RESULTCLASS_DNS + 105)
 #define DNS_R_BROKENCHAIN              (ISC_RESULTCLASS_DNS + 106)
 #define DNS_R_EXPIRED                  (ISC_RESULTCLASS_DNS + 107)
+#define DNS_R_NOTDYNAMIC               (ISC_RESULTCLASS_DNS + 108)
 
-#define DNS_R_NRESULTS                 108     /*%< Number of results */
+#define DNS_R_NRESULTS                 109     /*%< Number of results */
 
 /*
  * DNS wire format rcodes.
index d3709ac423b27518ca4f55de029555e400ab1802..35ca8efaa9aab7ce509ea803ea5c998b30fc5233 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.184 2011/03/01 23:48:07 tbox Exp $ */
+/* $Id: zone.h,v 1.185 2011/03/21 07:22:14 each Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -1853,6 +1853,21 @@ dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db);
  * Load the origin names for a writeable DLZ database.
  */
 
+isc_boolean_t
+dns_zone_isdynamic(dns_zone_t *zone);
+/*%
+ * Return true iff the zone is "dynamic", in the sense that the zone's
+ * master file (if any) is written by the server, rather than being
+ * updated manually and read by the server.
+ *
+ * This is true for slave zones, stub zones, key zones, and zones that
+ * allow dynamic updates either by having an update policy ("ssutable")
+ * or an "allow-update" ACL with a value other than exactly "{ none; }".
+ *
+ * Requires:
+ * \li 'zone' to be valid.
+ */
+
 ISC_LANG_ENDDECLS
 
 #endif /* DNS_ZONE_H */
index 547ac14c352c56399f5079886de3545d52e70e99..e0b9cee5b88325142932448e5a21a2f77e2d222f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: result.c,v 1.132 2011/01/11 23:47:13 tbox Exp $ */
+/* $Id: result.c,v 1.133 2011/03/21 07:22:13 each Exp $ */
 
 /*! \file */
 
@@ -161,6 +161,7 @@ static const char *text[DNS_R_NRESULTS] = {
        "not master",                          /*%< 105 DNS_R_NOTMASTER */
        "broken trust chain",                  /*%< 106 DNS_R_BROKENCHAIN */
        "expired",                             /*%< 106 DNS_R_EXPIRED */
+       "not dynamic",                         /*%< 107 DNS_R_NOTDYNAMIC */
 };
 
 static const char *rcode_text[DNS_R_NRCODERESULTS] = {
index 2f9d1dce5f7fa1de25595d41e3251913439be2b5..db40131a3ada1647107d27bf75a63252a3b901b6 100644 (file)
@@ -813,6 +813,7 @@ dns_zone_getxfrsource6
 dns_zone_getzeronosoattl
 dns_zone_iattach
 dns_zone_idetach
+dns_zone_isdynamic
 dns_zone_isforced
 dns_zone_load
 dns_zone_loadandthaw
index 6aeec1b7473a0592ba0e4da3305b739548de807d..eb5917977034bbf4f1ff4e97254f59cfc745fcd7 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.598 2011/03/21 01:02:39 marka Exp $ */
+/* $Id: zone.c,v 1.599 2011/03/21 07:22:13 each Exp $ */
 
 /*! \file */
 
@@ -1367,8 +1367,8 @@ dns_zone_getjournal(dns_zone_t *zone) {
  * allow dynamic updates either by having an update policy ("ssutable")
  * or an "allow-update" ACL with a value other than exactly "{ none; }".
  */
-static isc_boolean_t
-zone_isdynamic(dns_zone_t *zone) {
+isc_boolean_t
+dns_zone_isdynamic(dns_zone_t *zone) {
        REQUIRE(DNS_ZONE_VALID(zone));
 
        return (ISC_TF(zone->type == dns_zone_slave ||
@@ -1381,7 +1381,6 @@ zone_isdynamic(dns_zone_t *zone) {
                        !dns_acl_isnone(zone->update_acl))));
 }
 
-
 static isc_result_t
 zone_load(dns_zone_t *zone, unsigned int flags) {
        isc_result_t result;
@@ -1418,7 +1417,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
                goto cleanup;
        }
 
-       if (zone->db != NULL && zone_isdynamic(zone)) {
+       if (zone->db != NULL && dns_zone_isdynamic(zone)) {
                /*
                 * This is a slave, stub, or dynamically updated
                 * zone being reloaded.  Do nothing - the database
@@ -2602,7 +2601,7 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
        isc_result_t result;
        dns_rdata_t rdata = DNS_RDATA_INIT;
        isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
-                               zone_isdynamic(zone) : ISC_FALSE;
+                               dns_zone_isdynamic(zone) : ISC_FALSE;
 
        dns_rdataset_init(&rdataset);
        result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
index ed7f28a4a97007af36d51cc723a033b90c5897e5..8b4b1abf4e3f963f22165283962014d74e2a7e0c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zt.c,v 1.47 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: zt.c,v 1.48 2011/03/21 07:22:14 each Exp $ */
 
 /*! \file */
 
@@ -299,6 +299,8 @@ freezezones(dns_zone_t *zone, void *uap) {
 
        if (dns_zone_gettype(zone) != dns_zone_master)
                return (ISC_R_SUCCESS);
+       if (!dns_zone_isdynamic(zone))
+               return (ISC_R_SUCCESS);
 
        frozen = dns_zone_getupdatedisabled(zone);
        if (freeze) {