if (dochecksrv)
dns_zone_setchecksrv(zone, checksrv);
- CHECK(dns_zone_load(zone));
+ CHECK(dns_zone_load(zone, false));
/*
* When loading map files we can't catch oversize TTLs during
* Load the zone from the master file. If this fails, we'll
* need to undo the configuration we've done already.
*/
- result = dns_zone_loadnew(zone);
+ result = dns_zone_load(zone, true);
if (result != ISC_R_SUCCESS) {
dns_db_t *dbp = NULL;
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
- "catz: dns_zone_loadnew() failed "
+ "catz: dns_zone_load() failed "
"with %s; reverting.",
isc_result_totext(result));
view = ISC_LIST_NEXT(view, link))
{
if (view->managed_keys != NULL) {
- result = dns_zone_load(view->managed_keys);
+ result = dns_zone_load(view->managed_keys, false);
if (result != ISC_R_SUCCESS &&
result != DNS_R_UPTODATE &&
result != DNS_R_CONTINUE)
goto cleanup;
}
if (view->redirect != NULL) {
- result = dns_zone_load(view->redirect);
+ result = dns_zone_load(view->redirect, false);
if (result != ISC_R_SUCCESS &&
result != DNS_R_UPTODATE &&
result != DNS_R_CONTINUE)
* zones.
*/
isc_refcount_increment(&zl->refs);
- CHECK(dns_view_asyncload(view, view_loaded, zl));
+ CHECK(dns_view_asyncload(view, reconfig, view_loaded, zl));
}
cleanup:
dns_zone_detach(&zone);
msg = "zone refresh queued";
} else {
- result = dns_zone_load(zone);
+ result = dns_zone_load(zone, false);
dns_zone_detach(&zone);
switch (result) {
case ISC_R_SUCCESS:
* Load the zone from the master file. If this fails, we'll
* need to undo the configuration we've done already.
*/
- result = dns_zone_loadnew(zone);
+ result = dns_zone_load(zone, true);
if (result != ISC_R_SUCCESS) {
dns_db_t *dbp = NULL;
}
/* Load the zone from the master file if it needs reloading. */
- result = dns_zone_loadnew(zone);
+ result = dns_zone_load(zone, true);
/*
* Dynamic zones need no reloading, so we can pass this result.
if (zonetype == dns_zone_slave)
dns_zone_setmasters(zone, &addr, 1);
- result = dns_zone_load(zone);
+ result = dns_zone_load(zone, false);
ERRRET(result, "dns_zone_load");
result = dns_zonemgr_managezone(zonemgr, zone);
bool zone_dynamic;
uint32_t serial;
- result = dns_zone_load(zone);
+ result = dns_zone_load(zone, false);
if (result != ISC_R_SUCCESS && result != DNS_R_UPTODATE
&& result != DNS_R_DYNAMIC && result != DNS_R_CONTINUE)
goto cleanup;
*/
isc_result_t
-dns_view_load(dns_view_t *view, bool stop);
+dns_view_load(dns_view_t *view, bool stop, bool newonly);
isc_result_t
-dns_view_loadnew(dns_view_t *view, bool stop);
-
-isc_result_t
-dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg);
+dns_view_asyncload(dns_view_t *view, bool newonly, dns_zt_allloaded_t callback,
+ void *arg);
/*%<
* Load zones attached to this view. dns_view_load() loads
* all zones whose master file has changed since the last
- * load; dns_view_loadnew() loads only zones that have never
- * been loaded.
+ * load
*
* dns_view_asyncload() loads zones asynchronously. When all zones
* in the view have finished loading, 'callback' is called with argument
* If 'stop' is true, stop on the first error and return it.
* If 'stop' is false (or we are loading asynchronously), ignore errors.
*
+ * If 'newonly' is true load only zones that were never loaded.
+ *
* Requires:
*
*\li 'view' is valid.
*/
isc_result_t
-dns_zone_load(dns_zone_t *zone);
-
-isc_result_t
-dns_zone_loadnew(dns_zone_t *zone);
+dns_zone_load(dns_zone_t *zone, bool newonly);
isc_result_t
dns_zone_loadandthaw(dns_zone_t *zone);
* Confirm that the minimum requirements for the zone type are
* met, otherwise DNS_R_BADZONE is returned.
*
- * dns_zone_loadnew() only loads zones that are not yet loaded.
- * dns_zone_load() also loads zones that are already loaded and
- * and whose master file has changed since the last load.
+ * If newonly is set dns_zone_load() only loads new zones.
* dns_zone_loadandthaw() is similar to dns_zone_load() but will
* also re-enable DNS UPDATEs when the load completes.
*
*/
isc_result_t
-dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg);
+dns_zone_asyncload(dns_zone_t *zone, bool newonly,
+ dns_zt_zoneloaded_t done, void *arg);
/*%<
* Cause the database to be loaded from its backing store asynchronously.
* Other zone maintenance functions are suspended until this is complete.
*/
isc_result_t
-dns_zt_load(dns_zt_t *zt, bool stop);
+dns_zt_load(dns_zt_t *zt, bool stop, bool newonly);
isc_result_t
-dns_zt_loadnew(dns_zt_t *zt, bool stop);
-
-isc_result_t
-dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg);
+dns_zt_asyncload(dns_zt_t *zt, bool newonly, dns_zt_allloaded_t alldone,
+ void *arg);
/*%<
* Load all zones in the table. If 'stop' is true,
* stop on the first error and return it. If 'stop'
* is false, ignore errors.
*
- * dns_zt_loadnew() only loads zones that are not yet loaded.
- * dns_zt_load() also loads zones that are already loaded and
- * and whose master file has changed since the last load.
+ * if newonly is set only zones that were never loaded are loaded.
* dns_zt_asyncload() loads zones asynchronously; when all
* zones in the zone table have finished loaded (or failed due
* to errors), the caller is informed by calling 'alldone'
static void
debit_log(const dns_rrl_entry_t *e, int age, const char *action) {
- char buf[sizeof("age=12345678")];
+ char buf[sizeof("age=2147483647")];
const char *age_str;
if (age == DNS_RRL_FOREVER) {
struct args {
void *arg1;
void *arg2;
+ bool arg3;
};
/*
UNUSED(task);
- dns_zt_asyncload(args->arg1, all_done, args->arg2);
+ dns_zt_asyncload(args->arg1, false, all_done, args->arg2);
isc_event_free(&event);
}
UNUSED(task);
- dns_zone_asyncload(args->arg1, load_done, args->arg2);
+ dns_zone_asyncload(args->arg1, args->arg3, load_done, args->arg2);
isc_event_free(&event);
}
ATF_REQUIRE(view->zonetable != NULL);
ATF_CHECK_EQ(0, nzones);
- result = dns_zt_apply(view->zonetable, false, NULL, count_zone,
- &nzones);
+ result = dns_zt_apply(view->zonetable, false, NULL,
+ count_zone, &nzones);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
ATF_CHECK_EQ(1, nzones);
}
ATF_TC_BODY(asyncload_zone, tc) {
isc_result_t result;
+ int n;
dns_zone_t *zone = NULL;
dns_view_t *view = NULL;
dns_db_t *db = NULL;
+ FILE* zonefile, *origfile;
+ char buf[4096];
bool done = false;
int i = 0;
struct args args;
ATF_CHECK(!dns__zone_loadpending(zone));
ATF_CHECK(!done);
- dns_zone_setfile(zone, "testdata/zt/zone1.db", dns_masterformat_text,
- &dns_master_style_default);
+ zonefile = fopen("./zone.data", "wb");
+ ATF_CHECK(zonefile != NULL);
+ origfile = fopen("./testdata/zt/zone1.db", "r+b");
+ ATF_CHECK(origfile != NULL);
+ n = fread(buf, 1, 4096, origfile);
+ fwrite(buf, 1, n, zonefile);
+ fflush(zonefile);
+
+ dns_zone_setfile(zone, "./zone.data",
+ dns_masterformat_text, &dns_master_style_default);
args.arg1 = zone;
args.arg2 = &done;
+ args.arg3 = false;
isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
isc_app_run();
while (dns__zone_loadpending(zone) && i++ < 5000)
dns_test_nap(1000);
ATF_CHECK(done);
+ /* The zone should now be loaded; test it */
+ result = dns_zone_getdb(zone, &db);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ dns_db_detach(&db);
+ /*
+ * Add something to zone file, reload zone with newonly - it should
+ * not be reloaded.
+ */
+ fprintf(zonefile, "\nb in b 1.2.3.4\n");
+ fflush(zonefile);
+
+ args.arg1 = zone;
+ args.arg2 = &done;
+ args.arg3 = true;
+ isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
+
+ isc_app_run();
+ while (dns__zone_loadpending(zone) && i++ < 5000)
+ dns_test_nap(1000);
+ ATF_CHECK(done);
/* The zone should now be loaded; test it */
result = dns_zone_getdb(zone, &db);
ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+ dns_db_detach(&db);
+
+ /* Now reload it without newonly - it should be reloaded */
+ args.arg1 = zone;
+ args.arg2 = &done;
+ args.arg3 = false;
+ isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
+
+ isc_app_run();
+
+ while (dns__zone_loadpending(zone) && i++ < 5000)
+ dns_test_nap(1000);
+ ATF_CHECK(done);
+ /* The zone should now be loaded; test it */
+ result = dns_zone_getdb(zone, &db);
+ ATF_CHECK_EQ(result, ISC_R_SUCCESS);
+
ATF_CHECK(db != NULL);
if (db != NULL)
dns_db_detach(&db);
isc_result_t result;
dns_zone_t *zone1 = NULL, *zone2 = NULL, *zone3 = NULL;
dns_view_t *view;
- dns_zt_t *zt;
+ dns_zt_t *zt = NULL;
dns_db_t *db = NULL;
bool done = false;
int i = 0;
}
isc_result_t
-dns_view_load(dns_view_t *view, bool stop) {
+dns_view_load(dns_view_t *view, bool stop, bool newonly) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
- return (dns_zt_load(view->zonetable, stop));
+ return (dns_zt_load(view->zonetable, stop, newonly));
}
isc_result_t
-dns_view_loadnew(dns_view_t *view, bool stop) {
-
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->zonetable != NULL);
-
- return (dns_zt_loadnew(view->zonetable, stop));
-}
-
-isc_result_t
-dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) {
+dns_view_asyncload(dns_view_t *view, bool newonly,
+ dns_zt_allloaded_t callback, void *arg) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
- return (dns_zt_asyncload(view->zonetable, callback, arg));
+ return (dns_zt_asyncload(view->zonetable, newonly, callback, arg));
}
isc_result_t
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
/* Flags for zone_load() */
-#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
-#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
- load. */
+#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
+#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
+ load. */
#define UNREACH_CHACHE_SIZE 10U
#define UNREACH_HOLD_TIME 600 /* 10 minutes */
*/
struct dns_asyncload {
dns_zone_t *zone;
+ unsigned int flags;
dns_zt_zoneloaded_t loaded;
void *loaded_arg;
};
}
isc_result_t
-dns_zone_load(dns_zone_t *zone) {
- return (zone_load(zone, 0, false));
-}
-
-isc_result_t
-dns_zone_loadnew(dns_zone_t *zone) {
- return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT, false));
+dns_zone_load(dns_zone_t *zone, bool newonly) {
+ return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
}
static void
isc_event_free(&event);
LOCK_ZONE(zone);
- result = zone_load(zone, 0, true);
+ result = zone_load(zone, asl->flags, true);
if (result != DNS_R_CONTINUE) {
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
}
}
isc_result_t
-dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) {
+dns_zone_asyncload(dns_zone_t *zone, bool newonly,
+ dns_zt_zoneloaded_t done, void *arg)
+{
isc_event_t *e;
dns_asyncload_t *asl = NULL;
isc_result_t result = ISC_R_SUCCESS;
CHECK(ISC_R_NOMEMORY);
asl->zone = NULL;
+ asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
asl->loaded = done;
asl->loaded_arg = arg;
#include <dns/zone.h>
#include <dns/zt.h>
+struct zt_load_params {
+ dns_zt_zoneloaded_t dl;
+ bool newonly;
+};
+
struct dns_zt {
/* Unlocked. */
unsigned int magic;
isc_rwlock_t rwlock;
dns_zt_allloaded_t loaddone;
void * loaddone_arg;
+ struct zt_load_params *loadparams;
/* Locked by lock. */
bool flush;
uint32_t references;
#define ZTMAGIC ISC_MAGIC('Z', 'T', 'b', 'l')
#define VALID_ZT(zt) ISC_MAGIC_VALID(zt, ZTMAGIC)
+
static void
auto_detach(void *, void *);
static isc_result_t
asyncload(dns_zone_t *zone, void *callback);
-static isc_result_t
-loadnew(dns_zone_t *zone, void *uap);
-
static isc_result_t
freezezones(dns_zone_t *zone, void *uap);
zt->magic = ZTMAGIC;
zt->loaddone = NULL;
zt->loaddone_arg = NULL;
+ zt->loadparams = NULL;
zt->loads_pending = 0;
*ztp = zt;
}
isc_result_t
-dns_zt_load(dns_zt_t *zt, bool stop) {
+dns_zt_load(dns_zt_t *zt, bool stop, bool newonly) {
isc_result_t result;
-
+ struct zt_load_params params;
REQUIRE(VALID_ZT(zt));
-
+ params.newonly = newonly;
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, stop, NULL, load, NULL);
+ result = dns_zt_apply(zt, stop, NULL, load, ¶ms);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
return (result);
}
static isc_result_t
-load(dns_zone_t *zone, void *uap) {
+load(dns_zone_t *zone, void *paramsv) {
isc_result_t result;
- UNUSED(uap);
-
- result = dns_zone_load(zone);
- if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE)
+ struct zt_load_params *params = (struct zt_load_params*) paramsv;
+ result = dns_zone_load(zone, params->newonly);
+ if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE ||
+ result == DNS_R_DYNAMIC) {
result = ISC_R_SUCCESS;
-
+ }
return (result);
}
isc_result_t
-dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
+dns_zt_asyncload(dns_zt_t *zt, bool newonly,
+ dns_zt_allloaded_t alldone, void *arg) {
isc_result_t result;
- static dns_zt_zoneloaded_t dl = doneloading;
int pending;
REQUIRE(VALID_ZT(zt));
-
+ zt->loadparams = isc_mem_get(zt->mctx, sizeof(struct zt_load_params));
+ if (zt->loadparams == NULL) {
+ return (ISC_R_NOMEMORY);
+ }
+ zt->loadparams->dl = doneloading;
+ zt->loadparams->newonly = newonly;
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
-
INSIST(zt->loads_pending == 0);
- result = dns_zt_apply(zt, false, NULL, asyncload, &dl);
+ result = dns_zt_apply(zt, false, NULL, asyncload, zt);
pending = zt->loads_pending;
if (pending != 0) {
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
- if (pending == 0)
+ if (pending == 0) {
+ isc_mem_put(zt->mctx, zt->loadparams, sizeof(struct zt_load_params));
+ zt->loadparams = NULL;
alldone(arg);
+ }
return (result);
}
* the zone loading is complete.
*/
static isc_result_t
-asyncload(dns_zone_t *zone, void *callback) {
+asyncload(dns_zone_t *zone, void *zt_) {
isc_result_t result;
- dns_zt_zoneloaded_t *loaded = callback;
- dns_zt_t *zt;
-
+ struct dns_zt *zt = (dns_zt_t*) zt_;
REQUIRE(zone != NULL);
- zt = dns_zone_getview(zone)->zonetable;
- INSIST(VALID_ZT(zt));
-
INSIST(zt->references > 0);
zt->references++;
zt->loads_pending++;
- result = dns_zone_asyncload(zone, *loaded, zt);
+ result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt);
if (result != ISC_R_SUCCESS) {
zt->references--;
zt->loads_pending--;
return (ISC_R_SUCCESS);
}
-isc_result_t
-dns_zt_loadnew(dns_zt_t *zt, bool stop) {
- isc_result_t result;
-
- REQUIRE(VALID_ZT(zt));
-
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, stop, NULL, loadnew, NULL);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
- return (result);
-}
-
-static isc_result_t
-loadnew(dns_zone_t *zone, void *uap) {
- isc_result_t result;
- UNUSED(uap);
-
- result = dns_zone_loadnew(zone);
- if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE ||
- result == DNS_R_DYNAMIC)
- result = ISC_R_SUCCESS;
- return (result);
-}
-
isc_result_t
dns_zt_freezezones(dns_zt_t *zt, bool freeze) {
isc_result_t result, tresult;
arg = zt->loaddone_arg;
zt->loaddone = NULL;
zt->loaddone_arg = NULL;
+ isc_mem_put(zt->mctx, zt->loadparams, sizeof(struct zt_load_params));
+ zt->loadparams = NULL;
}
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
*/
dns_zone_setfile(served_zone, filename, dns_masterformat_text,
&dns_master_style_default);
- result = dns_zone_load(served_zone);
+ result = dns_zone_load(served_zone, false);
if (result != ISC_R_SUCCESS) {
goto release_zone;
}