diff --git a/CHANGES b/CHANGES index 56ec886834..f459f0ae2b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3497. [func] When deleting a slave/stub zone using 'rndc delzone' + report the files that were being used so they can + be cleaned up if desired. [RT #27899] + 3496. [placeholder] 3495. [func] Support multiple response-policy zones (up to 32), diff --git a/bin/named/control.c b/bin/named/control.c index 1d9514b505..bd86b95b41 100644 --- a/bin/named/control.c +++ b/bin/named/control.c @@ -204,7 +204,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t *text) { } else if (command_compare(command, NS_COMMAND_ADDZONE)) { result = ns_server_add_zone(ns_g_server, command); } else if (command_compare(command, NS_COMMAND_DELZONE)) { - result = ns_server_del_zone(ns_g_server, command); + result = ns_server_del_zone(ns_g_server, command, text); } else if (command_compare(command, NS_COMMAND_SIGNING)) { result = ns_server_signing(ns_g_server, command, text); } else if (command_compare(command, NS_COMMAND_ZONESTATUS)) { diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 7e9aaada12..4ee84ea1b7 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -350,7 +350,7 @@ ns_server_add_zone(ns_server_t *server, char *args); * Deletes a zone from a running process */ isc_result_t -ns_server_del_zone(ns_server_t *server, char *args); +ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text); /*% * Lists the status of the signing records for a given zone. diff --git a/bin/named/server.c b/bin/named/server.c index a82d023404..2558617d4a 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8303,13 +8303,33 @@ ns_server_add_zone(ns_server_t *server, char *args) { return (result); } +static isc_boolean_t +inuse(const char* file, isc_boolean_t first, isc_buffer_t *text) { +#define INUSEMSG "The following files were in use and may now be removed:\n" + + if (file != NULL && isc_file_exists(file) && + isc_buffer_availablelength(text) > + strlen(file) + (first ? sizeof(INUSEMSG) : 0)) + { + if (first) + isc__buffer_putstr(text, INUSEMSG); + else + isc_buffer_putstr(text, "\n"); + isc__buffer_putstr(text, file); + return (ISC_FALSE); + } + return (first); +} + /* * Act on a "delzone" command from the command channel. */ isc_result_t -ns_server_del_zone(ns_server_t *server, char *args) { +ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) { isc_result_t result; dns_zone_t *zone = NULL; + dns_zone_t *raw = NULL; + dns_zone_t *mayberaw; dns_view_t *view = NULL; dns_db_t *dbp = NULL; const char *filename = NULL; @@ -8318,6 +8338,7 @@ ns_server_del_zone(ns_server_t *server, char *args) { const char *zonename = NULL; size_t znamelen = 0; FILE *ifp = NULL, *ofp = NULL; + isc_boolean_t exclusive = ISC_FALSE; /* Parse parameters */ CHECK(zone_from_args(server, args, NULL, &zone, &zonename, ISC_TRUE)); @@ -8327,6 +8348,10 @@ ns_server_del_zone(ns_server_t *server, char *args) { goto cleanup; } + result = isc_task_beginexclusive(server->task); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + exclusive = ISC_TRUE; + /* * Was this zone originally added at runtime? * If not, we can't delete it now. @@ -8439,6 +8464,29 @@ ns_server_del_zone(ns_server_t *server, char *args) { dns_zone_unload(zone); } + /* Clean up stub / slave zone files */ + dns_zone_getraw(zone, &raw); + mayberaw = (raw != NULL) ? raw : zone; + if (dns_zone_gettype(mayberaw) == dns_zone_slave || + dns_zone_gettype(mayberaw) == dns_zone_stub) { + const char *file; + isc_boolean_t first; + + file = dns_zone_getfile(mayberaw); + first = inuse(file, ISC_TRUE, text); + + file = dns_zone_getjournal(mayberaw); + first = inuse(file, first, text); + + if (zone != mayberaw) { + file = dns_zone_getfile(zone); + first = inuse(file, first, text); + + file = dns_zone_getjournal(zone); + first = inuse(file, first, text); + } + } + CHECK(dns_zt_unmount(view->zonetable, zone)); isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, @@ -8448,6 +8496,8 @@ ns_server_del_zone(ns_server_t *server, char *args) { result = ISC_R_SUCCESS; cleanup: + if (exclusive) + isc_task_endexclusive(server->task); if (ifp != NULL) isc_stdio_close(ifp); if (ofp != NULL) { @@ -8456,6 +8506,8 @@ ns_server_del_zone(ns_server_t *server, char *args) { } if (tmpname != NULL) isc_mem_free(server->mctx, tmpname); + if (raw != NULL) + dns_zone_detach(&raw); if (zone != NULL) dns_zone_detach(&zone); diff --git a/bin/tests/system/addzone/clean.sh b/bin/tests/system/addzone/clean.sh index a4ce250bd4..e58215bb1e 100644 --- a/bin/tests/system/addzone/clean.sh +++ b/bin/tests/system/addzone/clean.sh @@ -17,7 +17,7 @@ # $Id: clean.sh,v 1.3 2010/09/15 03:32:34 marka Exp $ rm -f dig.out.* -rm -f rndc.out.* +rm -f rndc.out* rm -f ns2/named.conf rm -f */named.memstats rm -f ns2/*.nzf diff --git a/bin/tests/system/addzone/tests.sh b/bin/tests/system/addzone/tests.sh index 59456b3439..6eaacc54cc 100644 --- a/bin/tests/system/addzone/tests.sh +++ b/bin/tests/system/addzone/tests.sh @@ -133,6 +133,18 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:attempting to delete slave zone with inline signing ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 delzone inlineslave.example 2>&1 > rndc.out2.test$n +grep '^inlineslave.bk$' rndc.out2.test$n > /dev/null || { + echo "I:failed to report inlineslave.bk"; ret=1; +} +grep '^inlineslave.bk.signed$' rndc.out2.test$n > /dev/null || { + echo "I:failed to report inlineslave.bk.signed"; ret=1; +} +n=`expr $n + 1` +status=`expr $status + $ret` + echo "I:reconfiguring server with multiple views" rm -f ns2/named.conf cp -f ns2/named2.conf ns2/named.conf