mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 08:05:21 +00:00
Handle a missing zone when reloading a catalog zone
Previously a missing/deleted zone which was referenced by a catalog zone was causing a crash when doing a reload. This commit will make `named` to ignore the fact that the zone is missing, and make sure to restore it later on.
This commit is contained in:
@@ -3061,7 +3061,9 @@ configure_catz_zone(dns_view_t *view, const cfg_obj_t *config,
|
||||
name = dns_catz_entry_getname(entry);
|
||||
|
||||
tresult = dns_view_findzone(pview, name, &dnszone);
|
||||
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dns_zone_setview(dnszone, view);
|
||||
dns_view_addzone(view, dnszone);
|
||||
|
@@ -1555,5 +1555,129 @@ wait_for_soa @10.53.0.2 dom15.example. dig.out.test$n || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
##########################################################################
|
||||
echo_i "Testing recreation of a manually deleted zone after a reload"
|
||||
n=$((n+1))
|
||||
echo_i "checking that dom16.example. is not served by primary ($n)"
|
||||
ret=0
|
||||
wait_for_no_soa @10.53.0.1 dom16.example. dig.out.test$n || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "Adding a domain dom16.example. to primary ns1 via RNDC ($n)"
|
||||
ret=0
|
||||
echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom16.example.db
|
||||
echo "@ IN NS invalid." >> ns1/dom16.example.db
|
||||
echo "@ IN A 192.0.2.1" >> ns1/dom16.example.db
|
||||
rndccmd 10.53.0.1 addzone dom16.example. '{type primary; file "dom16.example.db";};' || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking that dom16.example. is now served by primary ns1 ($n)"
|
||||
ret=0
|
||||
wait_for_soa @10.53.0.1 dom16.example. dig.out.test$n || 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 dom16.example. to catalog1 zone with ns1 as primary ($n)"
|
||||
ret=0
|
||||
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||
server 10.53.0.1 ${PORT}
|
||||
update add efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example.
|
||||
update add masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1
|
||||
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 ($n)"
|
||||
ret=0
|
||||
wait_for_message ns2/named.run "catz: adding zone 'dom16.example' from catalog 'catalog1.example'" &&
|
||||
wait_for_message ns2/named.run "transfer of 'dom16.example/IN' from 10.53.0.1#${PORT}: Transfer status: 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 "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)"
|
||||
ret=0
|
||||
wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1
|
||||
grep "192.0.2.1" dig.out.test$n > /dev/null || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
nextpart ns2/named.run >/dev/null
|
||||
|
||||
echo_i "Deleting dom16.example. from secondary ns2 via RNDC ($n)"
|
||||
ret=0
|
||||
rndccmd 10.53.0.2 delzone dom16.example. >/dev/null 2>&1 || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking that dom16.example. is no longer served by secondary ($n)"
|
||||
ret=0
|
||||
wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
nextpart ns2/named.run >/dev/null
|
||||
|
||||
echo_i "Reloading secondary ns2 via RNDC ($n)"
|
||||
ret=0
|
||||
rndccmd 10.53.0.2 reload >/dev/null 2>&1 || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "waiting for secondary to sync up ($n)"
|
||||
ret=0
|
||||
wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking that dom16.example. is served by secondary and that it's the one from ns1 ($n)"
|
||||
ret=0
|
||||
wait_for_a @10.53.0.2 dom16.example. dig.out.test$n || ret=1
|
||||
grep "192.0.2.1" dig.out.test$n > /dev/null || 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 "Deleting domain dom16.example. from catalog1 ($n)"
|
||||
ret=0
|
||||
$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
|
||||
server 10.53.0.1 ${PORT}
|
||||
update delete efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN PTR dom16.example.
|
||||
update delete masters.efe725d0cf430ffb113b9bcf59266f066a21216b.zones.catalog1.example. 3600 IN A 10.53.0.1
|
||||
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 ($n)"
|
||||
ret=0
|
||||
wait_for_message ns2/named.run "catz: update_from_db: new zone merged" || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
n=$((n+1))
|
||||
echo_i "checking that dom16.example. is no longer served by secondary ($n)"
|
||||
ret=0
|
||||
wait_for_no_soa @10.53.0.2 dom16.example. dig.out.test$n || ret=1
|
||||
if [ $ret -ne 0 ]; then echo_i "failed"; fi
|
||||
status=$((status+ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
@@ -86,6 +86,11 @@ catz_process_zones_entry(dns_catz_zone_t *zone, dns_rdataset_t *value,
|
||||
static isc_result_t
|
||||
catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value,
|
||||
dns_label_t *mhash, dns_name_t *name);
|
||||
static void
|
||||
catz_entry_add_or_mod(dns_catz_zone_t *target, isc_ht_t *ht, unsigned char *key,
|
||||
size_t keysize, dns_catz_entry_t *nentry,
|
||||
dns_catz_entry_t *oentry, const char *msg,
|
||||
const char *zname, const char *czname);
|
||||
|
||||
/*%
|
||||
* Collection of catalog zones for a view
|
||||
@@ -443,6 +448,7 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) {
|
||||
{
|
||||
dns_catz_entry_t *nentry = NULL;
|
||||
dns_catz_entry_t *oentry = NULL;
|
||||
dns_zone_t *zone = NULL;
|
||||
unsigned char *key = NULL;
|
||||
size_t keysize;
|
||||
delcur = false;
|
||||
@@ -474,36 +480,34 @@ 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) {
|
||||
result = isc_ht_add(toadd, key, (uint32_t)keysize,
|
||||
nentry);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_ERROR,
|
||||
"catz: error adding zone '%s' "
|
||||
"from catalog '%s' - %s",
|
||||
zname, czname,
|
||||
isc_result_totext(result));
|
||||
}
|
||||
catz_entry_add_or_mod(target, toadd, key, keysize,
|
||||
nentry, NULL, "adding", zname,
|
||||
czname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dns_catz_entry_cmp(oentry, nentry) != true) {
|
||||
result = isc_ht_add(tomod, key, (uint32_t)keysize,
|
||||
nentry);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_ERROR,
|
||||
"catz: error modifying zone '%s' "
|
||||
"from catalog '%s' - %s",
|
||||
zname, czname,
|
||||
isc_result_totext(result));
|
||||
}
|
||||
result = dns_zt_find(target->catzs->view->zonetable,
|
||||
dns_catz_entry_getname(nentry), 0, NULL,
|
||||
&zone);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3),
|
||||
"catz: zone '%s' was expected to exist "
|
||||
"but can not be found, will be restored",
|
||||
zname);
|
||||
catz_entry_add_or_mod(target, toadd, key, keysize,
|
||||
nentry, oentry, "adding", zname,
|
||||
czname);
|
||||
continue;
|
||||
}
|
||||
dns_zone_detach(&zone);
|
||||
|
||||
if (dns_catz_entry_cmp(oentry, nentry) != true) {
|
||||
catz_entry_add_or_mod(target, tomod, key, keysize,
|
||||
nentry, oentry, "modifying",
|
||||
zname, czname);
|
||||
continue;
|
||||
}
|
||||
dns_catz_entry_detach(target, &oentry);
|
||||
result = isc_ht_delete(target->entries, key, (uint32_t)keysize);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
RUNTIME_CHECK(result == ISC_R_NOMORE);
|
||||
isc_ht_iter_destroy(&iter1);
|
||||
@@ -1388,6 +1392,26 @@ catz_process_zones_suboption(dns_catz_zone_t *zone, dns_rdataset_t *value,
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
catz_entry_add_or_mod(dns_catz_zone_t *target, isc_ht_t *ht, unsigned char *key,
|
||||
size_t keysize, dns_catz_entry_t *nentry,
|
||||
dns_catz_entry_t *oentry, const char *msg,
|
||||
const char *zname, const char *czname) {
|
||||
isc_result_t result = isc_ht_add(ht, key, (uint32_t)keysize, nentry);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: error %s zone '%s' from catalog '%s' - %s",
|
||||
msg, zname, czname, isc_result_totext(result));
|
||||
}
|
||||
if (oentry != NULL) {
|
||||
dns_catz_entry_detach(target, &oentry);
|
||||
result = isc_ht_delete(target->entries, key, (uint32_t)keysize);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
catz_process_value(dns_catz_zone_t *zone, dns_name_t *name,
|
||||
dns_rdataset_t *rdataset) {
|
||||
|
Reference in New Issue
Block a user