mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
catz: use two pairs of dns_db_t and dns_dbversion_t in a catalog zone
As it is done in the RPZ module, use 'db' and 'dbversion' for the database we are going to update to, and 'updb' and 'updbversion' for the database we are working on. Doing this should avoid a race between the 'dns__catz_update_cb()' and 'dns_catz_dbupdate_callback()' functions.
This commit is contained in:
@@ -88,11 +88,13 @@ struct dns_catz_zone {
|
||||
dns_catz_options_t zoneoptions;
|
||||
isc_time_t lastupdated;
|
||||
|
||||
bool updatepending; /* there is an update pending */
|
||||
bool updaterunning; /* there is an update running */
|
||||
isc_result_t updateresult; /* result from the offloaded work */
|
||||
dns_db_t *db; /* zones database */
|
||||
dns_dbversion_t *dbversion; /* zones database version */
|
||||
bool updatepending; /* there is an update pending */
|
||||
bool updaterunning; /* there is an update running */
|
||||
isc_result_t updateresult; /* result from the offloaded work */
|
||||
dns_db_t *db; /* zones database */
|
||||
dns_dbversion_t *dbversion; /* version we will be updating to */
|
||||
dns_db_t *updb; /* zones database we're working on */
|
||||
dns_dbversion_t *updbversion; /* version we're working on */
|
||||
|
||||
isc_timer_t *updatetimer;
|
||||
|
||||
@@ -2094,12 +2096,18 @@ dns__catz_timer_cb(void *arg) {
|
||||
LOCK(&catz->catzs->lock);
|
||||
|
||||
INSIST(DNS_DB_VALID(catz->db));
|
||||
INSIST(catz->dbversion != NULL);
|
||||
INSIST(catz->updb == NULL);
|
||||
INSIST(catz->updbversion == NULL);
|
||||
|
||||
catz->updatepending = false;
|
||||
catz->updaterunning = true;
|
||||
catz->updateresult = ISC_R_UNSET;
|
||||
|
||||
dns_db_attach(catz->db, &catz->updb);
|
||||
INSIST(catz->dbversion != NULL);
|
||||
catz->updbversion = catz->dbversion;
|
||||
catz->dbversion = NULL;
|
||||
|
||||
dns_name_format(&catz->name, domain, DNS_NAME_FORMATSIZE);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_INFO, "catz: %s: reload start", domain);
|
||||
@@ -2193,14 +2201,14 @@ catz_rdatatype_is_processable(const dns_rdatatype_t type) {
|
||||
static void
|
||||
dns__catz_update_cb(void *data) {
|
||||
dns_catz_zone_t *catz = (dns_catz_zone_t *)data;
|
||||
dns_db_t *db = NULL;
|
||||
dns_db_t *updb = NULL;
|
||||
dns_catz_zones_t *catzs = NULL;
|
||||
dns_catz_zone_t *oldcatz = NULL, *newcatz = NULL;
|
||||
isc_result_t result;
|
||||
isc_region_t r;
|
||||
dns_dbnode_t *node = NULL;
|
||||
const dns_dbnode_t *vers_node = NULL;
|
||||
dns_dbiterator_t *it = NULL;
|
||||
dns_dbiterator_t *updbit = NULL;
|
||||
dns_fixedname_t fixname;
|
||||
dns_name_t *name = NULL;
|
||||
dns_rdatasetiter_t *rdsiter = NULL;
|
||||
@@ -2215,7 +2223,7 @@ dns__catz_update_cb(void *data) {
|
||||
REQUIRE(DNS_DB_VALID(catz->db));
|
||||
REQUIRE(DNS_CATZ_ZONES_VALID(catz->catzs));
|
||||
|
||||
db = catz->db;
|
||||
updb = catz->updb;
|
||||
catzs = catz->catzs;
|
||||
|
||||
if (atomic_load(&catzs->shuttingdown)) {
|
||||
@@ -2223,12 +2231,12 @@ dns__catz_update_cb(void *data) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dns_name_format(&db->origin, bname, DNS_NAME_FORMATSIZE);
|
||||
dns_name_format(&updb->origin, bname, DNS_NAME_FORMATSIZE);
|
||||
|
||||
/*
|
||||
* Create a new catz in the same context as current catz.
|
||||
*/
|
||||
dns_name_toregion(&db->origin, &r);
|
||||
dns_name_toregion(&updb->origin, &r);
|
||||
LOCK(&catzs->lock);
|
||||
result = isc_ht_find(catzs->zones, r.base, r.length, (void **)&oldcatz);
|
||||
UNLOCK(&catzs->lock);
|
||||
@@ -2240,7 +2248,7 @@ dns__catz_update_cb(void *data) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = dns_db_getsoaserial(db, oldcatz->dbversion, &vers);
|
||||
result = dns_db_getsoaserial(updb, oldcatz->updbversion, &vers);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/* A zone without SOA record?!? */
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
@@ -2255,9 +2263,8 @@ dns__catz_update_cb(void *data) {
|
||||
"catz: updating catalog zone '%s' with serial %" PRIu32,
|
||||
bname, vers);
|
||||
|
||||
result = dns_catz_new_zone(catzs, &newcatz, &db->origin);
|
||||
result = dns_catz_new_zone(catzs, &newcatz, &updb->origin);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_db_closeversion(db, &oldcatz->dbversion, false);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: failed to create new zone - %s",
|
||||
@@ -2265,10 +2272,9 @@ dns__catz_update_cb(void *data) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = dns_db_createiterator(db, DNS_DB_NONSEC3, &it);
|
||||
result = dns_db_createiterator(updb, DNS_DB_NONSEC3, &updbit);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_catz_detach_catz(&newcatz);
|
||||
dns_db_closeversion(db, &oldcatz->dbversion, false);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: failed to create DB iterator - %s",
|
||||
@@ -2283,21 +2289,19 @@ dns__catz_update_cb(void *data) {
|
||||
* records might be processed differently depending on the version of
|
||||
* the catalog zone's schema.
|
||||
*/
|
||||
result = dns_name_fromstring2(name, "version", &db->origin, 0, NULL);
|
||||
result = dns_name_fromstring2(name, "version", &updb->origin, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_dbiterator_destroy(&it);
|
||||
dns_dbiterator_destroy(&updbit);
|
||||
dns_catz_detach_catz(&newcatz);
|
||||
dns_db_closeversion(db, &oldcatz->dbversion, false);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: failed to create name from string - %s",
|
||||
isc_result_totext(result));
|
||||
goto exit;
|
||||
}
|
||||
result = dns_dbiterator_seek(it, name);
|
||||
result = dns_dbiterator_seek(updbit, name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_dbiterator_destroy(&it);
|
||||
dns_db_closeversion(db, &oldcatz->dbversion, false);
|
||||
dns_dbiterator_destroy(&updbit);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: zone '%s' has no 'version' record (%s)",
|
||||
@@ -2317,7 +2321,7 @@ dns__catz_update_cb(void *data) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = dns_dbiterator_current(it, &node, name);
|
||||
result = dns_dbiterator_current(updbit, &node, name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
@@ -2326,7 +2330,7 @@ dns__catz_update_cb(void *data) {
|
||||
break;
|
||||
}
|
||||
|
||||
result = dns_dbiterator_pause(it);
|
||||
result = dns_dbiterator_pause(updbit);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
if (!is_vers_processed) {
|
||||
@@ -2334,19 +2338,19 @@ dns__catz_update_cb(void *data) {
|
||||
vers_node = node;
|
||||
} else if (node == vers_node) {
|
||||
/* Skip the already processed version node */
|
||||
dns_db_detachnode(db, &node);
|
||||
result = dns_dbiterator_next(it);
|
||||
dns_db_detachnode(updb, &node);
|
||||
result = dns_dbiterator_next(updbit);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = dns_db_allrdatasets(db, node, oldcatz->dbversion, 0, 0,
|
||||
&rdsiter);
|
||||
result = dns_db_allrdatasets(updb, node, oldcatz->updbversion,
|
||||
0, 0, &rdsiter);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
|
||||
"catz: failed to fetch rrdatasets - %s",
|
||||
isc_result_totext(result));
|
||||
dns_db_detachnode(db, &node);
|
||||
dns_db_detachnode(updb, &node);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2401,18 +2405,17 @@ dns__catz_update_cb(void *data) {
|
||||
|
||||
dns_rdatasetiter_destroy(&rdsiter);
|
||||
|
||||
dns_db_detachnode(db, &node);
|
||||
dns_db_detachnode(updb, &node);
|
||||
|
||||
if (!is_vers_processed) {
|
||||
is_vers_processed = true;
|
||||
result = dns_dbiterator_first(it);
|
||||
result = dns_dbiterator_first(updbit);
|
||||
} else {
|
||||
result = dns_dbiterator_next(it);
|
||||
result = dns_dbiterator_next(updbit);
|
||||
}
|
||||
}
|
||||
|
||||
dns_dbiterator_destroy(&it);
|
||||
dns_db_closeversion(db, &oldcatz->dbversion, false);
|
||||
dns_dbiterator_destroy(&updbit);
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
ISC_LOG_DEBUG(3),
|
||||
"catz: update_from_db: iteration finished: %s",
|
||||
@@ -2479,7 +2482,7 @@ final:
|
||||
*/
|
||||
if (!oldcatz->db_registered) {
|
||||
result = dns_db_updatenotify_register(
|
||||
db, dns_catz_dbupdate_callback, oldcatz->catzs);
|
||||
updb, dns_catz_dbupdate_callback, oldcatz->catzs);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
oldcatz->db_registered = true;
|
||||
}
|
||||
@@ -2506,6 +2509,9 @@ dns__catz_done_cb(void *data) {
|
||||
dns__catz_timer_start(catz);
|
||||
}
|
||||
|
||||
dns_db_closeversion(catz->updb, &catz->updbversion, false);
|
||||
dns_db_detach(&catz->updb);
|
||||
|
||||
UNLOCK(&catz->catzs->lock);
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
|
||||
|
Reference in New Issue
Block a user