diff --git a/bin/tests/system/catz/tests.sh b/bin/tests/system/catz/tests.sh index c973dc020c..f305acff01 100644 --- a/bin/tests/system/catz/tests.sh +++ b/bin/tests/system/catz/tests.sh @@ -473,6 +473,30 @@ status=$((status+ret)) nextpart ns2/named.run >/dev/null +# Test zone associated state reset. +n=$((n+1)) +echo_i "renaming the label of domain dom4.example. in catalog2 zone ($n)" +ret=0 +$NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 + server 10.53.0.3 ${PORT} + update delete de26b88d855397a03f77ff1162fd055d8b419584.zones.catalog2.example. 3600 IN PTR dom4.example. + update add dom4-renamed-label.zones.catalog2.example. 3600 IN PTR dom4.example. + send +END +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +n=$((n+1)) +echo_i "waiting for secondary to sync up, and checking that the zone has been reset ($n)" +ret=0 +wait_for_message ns2/named.run "catz: zone 'dom4.example' unique label has changed, reset state" && +wait_for_message ns2/named.run "catz: deleting zone 'dom4.example' from catalog 'catalog2.example' - success" && +wait_for_message ns2/named.run "catz: adding zone 'dom4.example' from catalog 'catalog2.example' - success" || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status+ret)) + +nextpart ns2/named.run >/dev/null + n=$((n+1)) echo_i "adding domain dom2.example. to catalog2 zone to test change of ownership ($n)" ret=0 @@ -732,7 +756,7 @@ $NSUPDATE -d <> nsupdate.out.test$n 2>&1 || ret=1 update delete dom2-with-coo.zones.catalog2.example. 3600 IN PTR dom2.example. update delete primaries.dom2-with-coo.zones.catalog2.example. 3600 IN A 10.53.0.3 update delete coo.dom2-with-coo.zones.catalog2.example. 3600 IN PTR catalog1.example. - update delete de26b88d855397a03f77ff1162fd055d8b419584.zones.catalog2.example. 3600 IN PTR dom4.example. + update delete dom4-renamed-label.zones.catalog2.example. 3600 IN PTR dom4.example. send END if [ $ret -ne 0 ]; then echo_i "failed"; fi diff --git a/doc/arm/catz.rst b/doc/arm/catz.rst index 0a13fc8655..ce6ce0158d 100644 --- a/doc/arm/catz.rst +++ b/doc/arm/catz.rst @@ -177,7 +177,8 @@ The target of the PTR record is the member zone name. For example, to add member uniquelabel.zones.catalog.example. IN PTR domain2.example. The label is necessary to identify custom properties (see below) for a specific member zone. -Also, the zone state can be reset by changing its label. +Also, the zone state can be reset by changing its label, in which case BIND will remove +the member zone and add it back. Catalog Zone Custom Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -288,7 +289,10 @@ zone. Catalog consumers which support the ``coo`` property will then take note, and when the zone is finally added into ``catalog2.example`` catalog zone, catalog consumers will change the ownership of the zone from ``catalog.example`` to ``catalog2.example``. BIND's implementation simply deletes the zone from the -old catalog zone and adds it back into the new catalog zone. The record with -``coo`` custom property can be later deleted by the catalog zone operator, if it -is confirmed that all the consumers have received it and have successfully -changed the ownership of the zone. +old catalog zone and adds it back into the new catalog zone, which also means +that all associated state for the just migrated zone will be reset, including +when the unique label is the same. + +The record with ``coo`` custom property can be later deleted by the +catalog zone operator after confirming that all the consumers have received +it and have successfully changed the ownership of the zone. diff --git a/lib/dns/catz.c b/lib/dns/catz.c index 9d231906d8..cd76eaa179 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -470,6 +470,7 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { : isc_ht_iter_next(iter1)) { isc_result_t zt_find_result; + dns_catz_zone_t *parentcatz = NULL; dns_catz_entry_t *nentry = NULL; dns_catz_entry_t *oentry = NULL; dns_zone_t *zone = NULL; @@ -506,7 +507,6 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { dns_catz_entry_getname(nentry), 0, NULL, &zone); if (zt_find_result == ISC_R_SUCCESS) { - dns_catz_zone_t *parentcatz = NULL; dns_catz_coo_t *coo = NULL; char pczname[DNS_NAME_FORMATSIZE]; @@ -551,6 +551,28 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) { result = isc_ht_find(target->entries, key, (uint32_t)keysize, (void **)&oentry); if (result != ISC_R_SUCCESS) { + if (zt_find_result == ISC_R_SUCCESS && + parentcatz == target) { + /* + * This means that the zone's unique label + * has been changed, in that case we must + * reset the zone's internal state by removing + * and re-adding it. + * + * Scheduling the addition now, the removal will + * be scheduled below, when walking the old + * zone for remaining entries, and then we will + * perform deletions earlier than additions and + * modifications. + */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTER, + ISC_LOG_INFO, + "catz: zone '%s' unique label " + "has changed, reset state", + zname); + } + catz_entry_add_or_mod(target, toadd, key, keysize, nentry, NULL, "adding", zname, czname);