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]
This commit is contained in:
Evan Hunt 2011-03-21 07:22:14 +00:00
parent 99bab541ab
commit 7cb226ec34
12 changed files with 183 additions and 40 deletions

View file

@ -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]

View 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)) {

View 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);

View 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",

View 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 {

View 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>

View 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
@ -151,8 +151,9 @@
#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.

View 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 */

View 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] = {

View 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

View 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);

View 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) {